1*bf2c3715SXin Li// This file is part of Eigen, a lightweight C++ template library 2*bf2c3715SXin Li// for linear algebra. 3*bf2c3715SXin Li// 4*bf2c3715SXin Li// Copyright (C) 2008-2009 Gael Guennebaud <[email protected]> 5*bf2c3715SXin Li// 6*bf2c3715SXin Li// This Source Code Form is subject to the terms of the Mozilla 7*bf2c3715SXin Li// Public License v. 2.0. If a copy of the MPL was not distributed 8*bf2c3715SXin Li// with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 9*bf2c3715SXin Li 10*bf2c3715SXin Li#ifndef EIGEN_ADLOC_FORWARD 11*bf2c3715SXin Li#define EIGEN_ADLOC_FORWARD 12*bf2c3715SXin Li 13*bf2c3715SXin Li//-------------------------------------------------------------------------------- 14*bf2c3715SXin Li// 15*bf2c3715SXin Li// This file provides support for adolc's adouble type in forward mode. 16*bf2c3715SXin Li// ADOL-C is a C++ automatic differentiation library, 17*bf2c3715SXin Li// see https://projects.coin-or.org/ADOL-C for more information. 18*bf2c3715SXin Li// 19*bf2c3715SXin Li// Note that the maximal number of directions is controlled by 20*bf2c3715SXin Li// the preprocessor token NUMBER_DIRECTIONS. The default is 2. 21*bf2c3715SXin Li// 22*bf2c3715SXin Li//-------------------------------------------------------------------------------- 23*bf2c3715SXin Li 24*bf2c3715SXin Li#define ADOLC_TAPELESS 25*bf2c3715SXin Li#ifndef NUMBER_DIRECTIONS 26*bf2c3715SXin Li# define NUMBER_DIRECTIONS 2 27*bf2c3715SXin Li#endif 28*bf2c3715SXin Li#include <adolc/adtl.h> 29*bf2c3715SXin Li 30*bf2c3715SXin Li// adolc defines some very stupid macros: 31*bf2c3715SXin Li#if defined(malloc) 32*bf2c3715SXin Li# undef malloc 33*bf2c3715SXin Li#endif 34*bf2c3715SXin Li 35*bf2c3715SXin Li#if defined(calloc) 36*bf2c3715SXin Li# undef calloc 37*bf2c3715SXin Li#endif 38*bf2c3715SXin Li 39*bf2c3715SXin Li#if defined(realloc) 40*bf2c3715SXin Li# undef realloc 41*bf2c3715SXin Li#endif 42*bf2c3715SXin Li 43*bf2c3715SXin Li#include "../../Eigen/Core" 44*bf2c3715SXin Li 45*bf2c3715SXin Linamespace Eigen { 46*bf2c3715SXin Li 47*bf2c3715SXin Li/** 48*bf2c3715SXin Li * \defgroup AdolcForward_Module Adolc forward module 49*bf2c3715SXin Li * This module provides support for adolc's adouble type in forward mode. 50*bf2c3715SXin Li * ADOL-C is a C++ automatic differentiation library, 51*bf2c3715SXin Li * see https://projects.coin-or.org/ADOL-C for more information. 52*bf2c3715SXin Li * It mainly consists in: 53*bf2c3715SXin Li * - a struct Eigen::NumTraits<adtl::adouble> specialization 54*bf2c3715SXin Li * - overloads of internal::* math function for adtl::adouble type. 55*bf2c3715SXin Li * 56*bf2c3715SXin Li * Note that the maximal number of directions is controlled by 57*bf2c3715SXin Li * the preprocessor token NUMBER_DIRECTIONS. The default is 2. 58*bf2c3715SXin Li * 59*bf2c3715SXin Li * \code 60*bf2c3715SXin Li * #include <unsupported/Eigen/AdolcSupport> 61*bf2c3715SXin Li * \endcode 62*bf2c3715SXin Li */ 63*bf2c3715SXin Li //@{ 64*bf2c3715SXin Li 65*bf2c3715SXin Li} // namespace Eigen 66*bf2c3715SXin Li 67*bf2c3715SXin Li// Eigen's require a few additional functions which must be defined in the same namespace 68*bf2c3715SXin Li// than the custom scalar type own namespace 69*bf2c3715SXin Linamespace adtl { 70*bf2c3715SXin Li 71*bf2c3715SXin Liinline const adouble& conj(const adouble& x) { return x; } 72*bf2c3715SXin Liinline const adouble& real(const adouble& x) { return x; } 73*bf2c3715SXin Liinline adouble imag(const adouble&) { return 0.; } 74*bf2c3715SXin Liinline adouble abs(const adouble& x) { return fabs(x); } 75*bf2c3715SXin Liinline adouble abs2(const adouble& x) { return x*x; } 76*bf2c3715SXin Li 77*bf2c3715SXin Liinline bool (isinf)(const adouble& x) { return (Eigen::numext::isinf)(x.getValue()); } 78*bf2c3715SXin Liinline bool (isnan)(const adouble& x) { return (Eigen::numext::isnan)(x.getValue()); } 79*bf2c3715SXin Li 80*bf2c3715SXin Li} 81*bf2c3715SXin Li 82*bf2c3715SXin Linamespace Eigen { 83*bf2c3715SXin Li 84*bf2c3715SXin Litemplate<> struct NumTraits<adtl::adouble> 85*bf2c3715SXin Li : NumTraits<double> 86*bf2c3715SXin Li{ 87*bf2c3715SXin Li typedef adtl::adouble Real; 88*bf2c3715SXin Li typedef adtl::adouble NonInteger; 89*bf2c3715SXin Li typedef adtl::adouble Nested; 90*bf2c3715SXin Li enum { 91*bf2c3715SXin Li IsComplex = 0, 92*bf2c3715SXin Li IsInteger = 0, 93*bf2c3715SXin Li IsSigned = 1, 94*bf2c3715SXin Li RequireInitialization = 1, 95*bf2c3715SXin Li ReadCost = 1, 96*bf2c3715SXin Li AddCost = 1, 97*bf2c3715SXin Li MulCost = 1 98*bf2c3715SXin Li }; 99*bf2c3715SXin Li}; 100*bf2c3715SXin Li 101*bf2c3715SXin Litemplate<typename Functor> class AdolcForwardJacobian : public Functor 102*bf2c3715SXin Li{ 103*bf2c3715SXin Li typedef adtl::adouble ActiveScalar; 104*bf2c3715SXin Lipublic: 105*bf2c3715SXin Li 106*bf2c3715SXin Li AdolcForwardJacobian() : Functor() {} 107*bf2c3715SXin Li AdolcForwardJacobian(const Functor& f) : Functor(f) {} 108*bf2c3715SXin Li 109*bf2c3715SXin Li // forward constructors 110*bf2c3715SXin Li template<typename T0> 111*bf2c3715SXin Li AdolcForwardJacobian(const T0& a0) : Functor(a0) {} 112*bf2c3715SXin Li template<typename T0, typename T1> 113*bf2c3715SXin Li AdolcForwardJacobian(const T0& a0, const T1& a1) : Functor(a0, a1) {} 114*bf2c3715SXin Li template<typename T0, typename T1, typename T2> 115*bf2c3715SXin Li AdolcForwardJacobian(const T0& a0, const T1& a1, const T1& a2) : Functor(a0, a1, a2) {} 116*bf2c3715SXin Li 117*bf2c3715SXin Li typedef typename Functor::InputType InputType; 118*bf2c3715SXin Li typedef typename Functor::ValueType ValueType; 119*bf2c3715SXin Li typedef typename Functor::JacobianType JacobianType; 120*bf2c3715SXin Li 121*bf2c3715SXin Li typedef Matrix<ActiveScalar, InputType::SizeAtCompileTime, 1> ActiveInput; 122*bf2c3715SXin Li typedef Matrix<ActiveScalar, ValueType::SizeAtCompileTime, 1> ActiveValue; 123*bf2c3715SXin Li 124*bf2c3715SXin Li void operator() (const InputType& x, ValueType* v, JacobianType* _jac) const 125*bf2c3715SXin Li { 126*bf2c3715SXin Li eigen_assert(v!=0); 127*bf2c3715SXin Li if (!_jac) 128*bf2c3715SXin Li { 129*bf2c3715SXin Li Functor::operator()(x, v); 130*bf2c3715SXin Li return; 131*bf2c3715SXin Li } 132*bf2c3715SXin Li 133*bf2c3715SXin Li JacobianType& jac = *_jac; 134*bf2c3715SXin Li 135*bf2c3715SXin Li ActiveInput ax = x.template cast<ActiveScalar>(); 136*bf2c3715SXin Li ActiveValue av(jac.rows()); 137*bf2c3715SXin Li 138*bf2c3715SXin Li for (int j=0; j<jac.cols(); j++) 139*bf2c3715SXin Li for (int i=0; i<jac.cols(); i++) 140*bf2c3715SXin Li ax[i].setADValue(j, i==j ? 1 : 0); 141*bf2c3715SXin Li 142*bf2c3715SXin Li Functor::operator()(ax, &av); 143*bf2c3715SXin Li 144*bf2c3715SXin Li for (int i=0; i<jac.rows(); i++) 145*bf2c3715SXin Li { 146*bf2c3715SXin Li (*v)[i] = av[i].getValue(); 147*bf2c3715SXin Li for (int j=0; j<jac.cols(); j++) 148*bf2c3715SXin Li jac.coeffRef(i,j) = av[i].getADValue(j); 149*bf2c3715SXin Li } 150*bf2c3715SXin Li } 151*bf2c3715SXin Liprotected: 152*bf2c3715SXin Li 153*bf2c3715SXin Li}; 154*bf2c3715SXin Li 155*bf2c3715SXin Li//@} 156*bf2c3715SXin Li 157*bf2c3715SXin Li} 158*bf2c3715SXin Li 159*bf2c3715SXin Li#endif // EIGEN_ADLOC_FORWARD 160