Example
The files eigen_array.cpp
and eigen_det.cpp
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:
namespace CppAD {
// AD<Base>template <class Base> class AD;
// numeric_limits<Float>template <class Float> class numeric_limits;
}
std Declarations
Next declare some template specializations in std namespace:
Include Eigen/Core
Next define the eigen plugin and then include Eigen/Core:
# define EIGEN_MATRIXBASE_PLUGIN <cppad/example/eigen_plugin.hpp>
# include <Eigen/Core>
Eigen NumTraits
Eigen needs the following definitions, in the Eigen namespace,
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> valuetypedef CppAD::AD<Base> Real;
// type for AD<Base> operations that result in non-integer valuestypedef CppAD::AD<Base> NonInteger;
// type to use for numeric literals such as "2" or "0.5".typedef CppAD::AD<Base> Literal;
// type for nested value inside an AD<Base> expression treetypedef 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 valuestatic CppAD::AD<Base> dummy_precision(void)
{ return 100. *
CppAD::numeric_limits< CppAD::AD<Base> >::epsilon();
}
// minimum normalized positive valuestatic CppAD::AD<Base> lowest(void)
{ return CppAD::numeric_limits< CppAD::AD<Base> >::min(); }
// maximum finite valuestatic CppAD::AD<Base> highest(void)
{ return CppAD::numeric_limits< CppAD::AD<Base> >::max(); }
// number of decimal digits that can be represented without change.static int digits10(void)
{ return CppAD::numeric_limits< CppAD::AD<Base> >::digits10; }
// not a numberstatic CppAD::AD<Base> quiet_NaN(void)
{ return CppAD::numeric_limits< CppAD::AD<Base> >::quiet_NaN(); }
// positive infinite valuestatic CppAD::AD<Base> infinity(void)
{ return CppAD::numeric_limits< CppAD::AD<Base> >::infinity(); }
};
}
namespace Eigen {
// Inform Eigen that a binary operations between Base and AD<Base>// are allowed and thate the return type is AD<Base>template<typename Base, typename BinOp>
struct ScalarBinaryOpTraits<CppAD::AD<Base>, Base, BinOp>{
typedef CppAD::AD<Base> ReturnType;
};
template<typename Base, typename BinOp>
struct ScalarBinaryOpTraits<Base, CppAD::AD<Base>, BinOp>
{
typedef CppAD::AD<Base> ReturnType;
};
}
CppAD Namespace
Eigen needs the following definitions, in the CppAD namespace,
to work properly with
AD<Base>
scalars:
eigen_vector
The class CppAD::eigen_vector is a wrapper for Eigen column vectors
so that they are simple vectors
.
To be specific, it converts Eigen::Index arguments and
return values to size_t.