lines 9-257 of file: include/cppad/example/cppad_eigen.hpp {xrst_begin cppad_eigen.hpp} {xrst_spell plugin scalars specializations } Enable Use of Eigen Linear Algebra Package with CppAD ##################################################### Syntax ****** # ``include `` {xrst_toc_hidden include/cppad/example/eigen_plugin.hpp example/general/eigen_array.cpp example/general/eigen_det.cpp } Purpose ******* Enables the use of the :ref:`eigen-name` linear algebra package with the type *AD* < ``Base`` > ; see `custom scalar types `_. Example ******* The files :ref:`eigen_array.cpp-name` and :ref:`eigen_det.cpp-name` contain an example and test of this include file. They return true if they succeed and false otherwise. CppAD Declarations ****************** First declare some items that are defined by cppad.hpp: {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { // AD template class AD; // numeric_limits template class numeric_limits; } /* {xrst_code} {xrst_spell_on} std Declarations **************** Next declare some template specializations in std namespace: {xrst_spell_off} {xrst_code cpp} */ namespace std { template bool isinf(const CppAD::AD &x); template bool isfinite(const CppAD::AD &x); template bool isnan(const CppAD::AD &x); } /* {xrst_code} {xrst_spell_on} Include Eigen/Core ****************** Next define the eigen plugin and then include Eigen/Core: {xrst_spell_off} {xrst_code cpp} */ # define EIGEN_MATRIXBASE_PLUGIN # include /* {xrst_code} {xrst_spell_on} Eigen NumTraits *************** Eigen needs the following definitions, in the Eigen namespace, to work properly with ``AD`` < *Base* > scalars: {xrst_spell_off} {xrst_code cpp} */ namespace Eigen { template struct NumTraits< CppAD::AD > { // type that corresponds to the real part of an AD value typedef CppAD::AD Real; // type for AD operations that result in non-integer values typedef CppAD::AD NonInteger; // type to use for numeric literals such as "2" or "0.5". typedef CppAD::AD Literal; // type for nested value inside an AD expression tree typedef CppAD::AD Nested; enum { // does not support complex Base types IsComplex = 0 , // does not support integer Base types IsInteger = 0 , // only support signed Base types IsSigned = 1 , // must initialize an AD object RequireInitialization = 1 , // computational cost of the corresponding operations ReadCost = 1 , AddCost = 2 , MulCost = 2 }; // machine epsilon with type of real part of x // (use assumption that Base is not complex) static CppAD::AD epsilon(void) { return CppAD::numeric_limits< CppAD::AD >::epsilon(); } // relaxed version of machine epsilon for comparison of different // operations that should result in the same value static CppAD::AD dummy_precision(void) { return 100. * CppAD::numeric_limits< CppAD::AD >::epsilon(); } // minimum normalized positive value static CppAD::AD lowest(void) { return CppAD::numeric_limits< CppAD::AD >::min(); } // maximum finite value static CppAD::AD highest(void) { return CppAD::numeric_limits< CppAD::AD >::max(); } // number of decimal digits that can be represented without change. static int digits10(void) { return CppAD::numeric_limits< CppAD::AD >::digits10; } // number of decimal digits necessary to uniquely represent values. static int max_digits10(void) { return CppAD::numeric_limits< CppAD::AD >::max_digits10; } // not a number static CppAD::AD quiet_NaN(void) { return CppAD::numeric_limits< CppAD::AD >::quiet_NaN(); } // positive infinite value static CppAD::AD infinity(void) { return CppAD::numeric_limits< CppAD::AD >::infinity(); } }; } /* {xrst_code} {xrst_spell_on} Eigen ScalarBinaryOpTraits ************************** {xrst_spell_off} {xrst_code cpp} */ namespace Eigen { // Inform Eigen that a binary operations between Base and AD // are allowed and thate the return type is AD template struct ScalarBinaryOpTraits, Base, BinOp>{ typedef CppAD::AD ReturnType; }; template struct ScalarBinaryOpTraits, BinOp> { typedef CppAD::AD ReturnType; }; } /* {xrst_code} {xrst_spell_on} CppAD Namespace *************** Eigen needs the following definitions, in the CppAD namespace, to work properly with ``AD`` < *Base* > scalars: {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { // functions that return references template const AD& conj(const AD& x) { return x; } template const AD& real(const AD& x) { return x; } // functions that return values (note abs is defined by cppad.hpp) template AD imag(const AD& x) { return CppAD::AD(0.); } template AD abs2(const AD& x) { return x * x; } } /* {xrst_code} {xrst_spell_on} eigen_vector ************ The class ``CppAD::eigen_vector`` is a wrapper for Eigen column vectors so that they are :ref:`simple vectors` . To be specific, it converts ``Eigen::Index`` arguments and return values to ``size_t`` . {xrst_spell_off} {xrst_code cpp} */ namespace CppAD { template class eigen_vector : public Eigen::Matrix { private: // base_class typedef Eigen::Matrix base_class; public: // constructor eigen_vector(size_t n) : base_class( Eigen::Index(n) ) { } eigen_vector(void) : base_class() { } // operator[] Scalar& operator[](size_t i) { return base_class::operator[]( Eigen::Index(i) ); } const Scalar& operator[](size_t i) const { return base_class::operator[]( Eigen::Index(i) ); } // size size_t size(void) const { return size_t( base_class::size() ); } // resize void resize(size_t n) { base_class::resize( Eigen::Index(n) ); } }; } /* {xrst_code} {xrst_spell_on} Include cppad.hpp ***************** {xrst_spell_off} {xrst_code cpp} */ # include /* {xrst_code} {xrst_spell_on} std Definitions *************** The definitions below use cppad.hpp. Note that :ref:`Value-name` function can only be used with a :ref:`constant parameter` argument. {xrst_spell_off} {xrst_code cpp} */ namespace std { template bool isinf(const CppAD::AD &x) { return isinf(CppAD::Value( CppAD::Var2Par(x) ) ); } template bool isfinite(const CppAD::AD &x) { return isfinite(CppAD::Value( CppAD::Var2Par(x) ) ); } template bool isnan(const CppAD::AD &x) { return isnan(CppAD::Value( CppAD::Var2Par(x) ) ); } } /* {xrst_code} {xrst_spell_on} {xrst_end cppad_eigen.hpp}