xref: /aosp_15_r20/external/eigen/unsupported/Eigen/AdolcForward (revision bf2c37156dfe67e5dfebd6d394bad8b2ab5804d4)
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