Enable Use of Eigen Linear Algebra Package with CppAD
Keywords: enable use eigen linear algebra package with cppad syntax purpose example include files numtraits namespace

| Prev | Next |  |  |  |  |  |  |

Enable Use of Eigen Linear Algebra Package with CppAD
Syntax
`# include <cppad/example/cppad_eigen.hpp>`
Purpose
Enables the use of the eigen linear algebra package with the type `AD<Base>` .
Example
The files eigen_array.cpp and eigen_det.cpp contain an example and test of this include file. It returns true if it succeeds and false otherwise.
Include Files
The file `cppad_eigen.hpp` includes both `<cppad/cppad.hpp>` and `<Eigen/Core>`. In addition, The file eigen_plugin.hpp is used to define `value_type` in the Eigen matrix class definition so its vectors are simple vectors . `

    # define EIGEN_MATRIXBASE_PLUGIN <cppad/example/eigen_plugin.hpp>
    # include <Eigen/Core>
    # include <cppad/cppad.hpp>

`
Eigen NumTraits
Eigen needs the following definitions to work properly with `AD<Base>` scalars: `

    namespace Eigen {
         template <class Base> struct NumTraits< CppAD::AD<Base> >
         {    // type that corresponds to the real part of an AD<Base> value
              typedef CppAD::AD<Base>   Real;
              // type for AD<Base> operations that result in non-integer values
              typedef CppAD::AD<Base>   NonInteger;
              // type for nested value inside an AD<Base> expression tree
              typedef CppAD::AD<Base>   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<Base> 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<Base> epsilon(void)
              {    return CppAD::numeric_limits< CppAD::AD<Base> >::epsilon(); }

              // relaxed version of machine epsilon for comparison of different
              // operations that should result in the same value
              static CppAD::AD<Base> dummy_precision(void)
              {    return 100. *
                        CppAD::numeric_limits< CppAD::AD<Base> >::epsilon();
              }

              // minimum normalized positive value
              static CppAD::AD<Base> lowest(void)
              {    return CppAD::numeric_limits< CppAD::AD<Base> >::min(); }

              // maximum finite value
              static CppAD::AD<Base> highest(void)
              {    return CppAD::numeric_limits< CppAD::AD<Base> >::max(); }

         };
    }

`
CppAD Namespace
Eigen also needs the following definitions to work properly with `AD<Base>` scalars: `

    namespace CppAD {
              // functions that return references
              template <class Base> const AD<Base>& conj(const AD<Base>& x)
              {    return x; }
              template <class Base> const AD<Base>& real(const AD<Base>& x)
              {    return x; }

              // functions that return values (note abs is defined by cppad.hpp)
              template <class Base> AD<Base> imag(const AD<Base>& x)
              {    return CppAD::AD<Base>(0.); }
              template <class Base> AD<Base> abs2(const AD<Base>& x)
              {    return x * x; }
    }

    namespace Eigen {
         namespace internal {

              template<class Base>
              struct significant_decimals_default_impl< CppAD::AD<Base>, false>
              {    typedef CppAD::AD<Base> Scalar;

                   typedef typename NumTraits<Scalar>::Real RealScalar;
                   static inline int run()
                   {    Scalar neg_log_eps = - log(
                             NumTraits<RealScalar>::epsilon()
                        );
                        int ceil_neg_log_eps = Integer( neg_log_eps );
                        if( Scalar(ceil_neg_log_eps) < neg_log_eps )
                             ceil_neg_log_eps++;
                        return ceil_neg_log_eps;
                   }
              };
         }
    }

`

Input File: cppad/example/cppad_eigen.hpp