You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

156 lines
4.2 KiB

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