|
|
// This file is part of Eigen, a lightweight C++ template library // for linear algebra. // // Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // // This Source Code Form is subject to the terms of the Mozilla // Public License v. 2.0. If a copy of the MPL was not distributed // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#ifndef EIGEN_ADLOC_FORWARD #define EIGEN_ADLOC_FORWARD
//-------------------------------------------------------------------------------- // // This file provides support for adolc's adouble type in forward mode. // ADOL-C is a C++ automatic differentiation library, // see https://projects.coin-or.org/ADOL-C for more information. // // Note that the maximal number of directions is controlled by // the preprocessor token NUMBER_DIRECTIONS. The default is 2. // //--------------------------------------------------------------------------------
#define ADOLC_TAPELESS #ifndef NUMBER_DIRECTIONS # define NUMBER_DIRECTIONS 2 #endif #include <adolc/adtl.h>
// adolc defines some very stupid macros: #if defined(malloc) # undef malloc #endif
#if defined(calloc) # undef calloc #endif
#if defined(realloc) # undef realloc #endif
#include <Eigen/Core>
namespace StormEigen {
/** * \defgroup AdolcForward_Module Adolc forward module * This module provides support for adolc's adouble type in forward mode. * ADOL-C is a C++ automatic differentiation library, * see https://projects.coin-or.org/ADOL-C for more information. * It mainly consists in: * - a struct StormEigen::NumTraits<adtl::adouble> specialization * - overloads of internal::* math function for adtl::adouble type. * * Note that the maximal number of directions is controlled by * the preprocessor token NUMBER_DIRECTIONS. The default is 2. * * \code * #include <unsupported/Eigen/AdolcSupport> * \endcode */ //@{
} // namespace StormEigen
// Eigen's require a few additional functions which must be defined in the same namespace // than the custom scalar type own namespace namespace adtl {
inline const adouble& conj(const adouble& x) { return x; } inline const adouble& real(const adouble& x) { return x; } inline adouble imag(const adouble&) { return 0.; } inline adouble abs(const adouble& x) { return fabs(x); } inline adouble abs2(const adouble& x) { return x*x; }
}
namespace StormEigen {
template<> struct NumTraits<adtl::adouble> : NumTraits<double> { typedef adtl::adouble Real; typedef adtl::adouble NonInteger; typedef adtl::adouble Nested; enum { IsComplex = 0, IsInteger = 0, IsSigned = 1, RequireInitialization = 1, ReadCost = 1, AddCost = 1, MulCost = 1 }; };
template<typename Functor> class AdolcForwardJacobian : public Functor { typedef adtl::adouble ActiveScalar; public:
AdolcForwardJacobian() : Functor() {} AdolcForwardJacobian(const Functor& f) : Functor(f) {}
// forward constructors template<typename T0> AdolcForwardJacobian(const T0& a0) : Functor(a0) {} template<typename T0, typename T1> AdolcForwardJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {} template<typename T0, typename T1, typename T2> AdolcForwardJacobian(const T0& a0, const T1& a1, const T1& a2) : Functor(a0, a1, a2) {}
typedef typename Functor::InputType InputType; typedef typename Functor::ValueType ValueType; typedef typename Functor::JacobianType JacobianType;
typedef Matrix<ActiveScalar, InputType::SizeAtCompileTime, 1> ActiveInput; typedef Matrix<ActiveScalar, ValueType::SizeAtCompileTime, 1> ActiveValue;
void operator() (const InputType& x, ValueType* v, JacobianType* _jac) const { eigen_assert(v!=0); if (!_jac) { Functor::operator()(x, v); return; }
JacobianType& jac = *_jac;
ActiveInput ax = x.template cast<ActiveScalar>(); ActiveValue av(jac.rows());
for (int j=0; j<jac.cols(); j++) for (int i=0; i<jac.cols(); i++) ax[i].setADValue(j, i==j ? 1 : 0);
Functor::operator()(ax, &av);
for (int i=0; i<jac.rows(); i++) { (*v)[i] = av[i].getValue(); for (int j=0; j<jac.cols(); j++) jac.coeffRef(i,j) = av[i].getADValue(j); } } protected:
};
//@}
}
#endif // EIGEN_ADLOC_FORWARD
|