$darkmode
Eigen-unsupported  5.0.1-dev
NumericalDiff.h
1 // -*- coding: utf-8
2 // vim: set fileencoding=utf-8
3 
4 // This file is part of Eigen, a lightweight C++ template library
5 // for linear algebra.
6 //
7 // Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
8 //
9 // This Source Code Form is subject to the terms of the Mozilla
10 // Public License v. 2.0. If a copy of the MPL was not distributed
11 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
12 
13 #ifndef EIGEN_NUMERICAL_DIFF_H
14 #define EIGEN_NUMERICAL_DIFF_H
15 
16 // IWYU pragma: private
17 #include "./InternalHeaderCheck.h"
18 
19 namespace Eigen {
20 
21 enum NumericalDiffMode { Forward, Central };
22 
34 template <typename Functor_, NumericalDiffMode mode = Forward>
35 class NumericalDiff : public Functor_ {
36  public:
37  typedef Functor_ Functor;
38  typedef typename Functor::Scalar Scalar;
39  typedef typename Functor::InputType InputType;
40  typedef typename Functor::ValueType ValueType;
41  typedef typename Functor::JacobianType JacobianType;
42 
43  NumericalDiff(Scalar _epsfcn = 0.) : Functor(), epsfcn(_epsfcn) {}
44  NumericalDiff(const Functor& f, Scalar _epsfcn = 0.) : Functor(f), epsfcn(_epsfcn) {}
45 
46  // forward constructors
47  template <typename T0>
48  NumericalDiff(const T0& a0) : Functor(a0), epsfcn(0) {}
49  template <typename T0, typename T1>
50  NumericalDiff(const T0& a0, const T1& a1) : Functor(a0, a1), epsfcn(0) {}
51  template <typename T0, typename T1, typename T2>
52  NumericalDiff(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2), epsfcn(0) {}
53 
54  enum { InputsAtCompileTime = Functor::InputsAtCompileTime, ValuesAtCompileTime = Functor::ValuesAtCompileTime };
55 
59  int df(const InputType& _x, JacobianType& jac) const {
60  using std::abs;
61  using std::sqrt;
62  /* Local variables */
63  Scalar h;
64  int nfev = 0;
65  const typename InputType::Index n = _x.size();
66  const Scalar eps = sqrt(((std::max)(epsfcn, NumTraits<Scalar>::epsilon())));
67  ValueType val1, val2;
68  InputType x = _x;
69  // TODO : we should do this only if the size is not already known
70  val1.resize(Functor::values());
71  val2.resize(Functor::values());
72 
73  // initialization
74  switch (mode) {
75  case Forward:
76  // compute f(x)
77  Functor::operator()(x, val1);
78  nfev++;
79  break;
80  case Central:
81  // do nothing
82  break;
83  default:
84  eigen_assert(false);
85  };
86 
87  // Function Body
88  for (int j = 0; j < n; ++j) {
89  h = eps * abs(x[j]);
90  if (h == 0.) {
91  h = eps;
92  }
93  switch (mode) {
94  case Forward:
95  x[j] += h;
96  Functor::operator()(x, val2);
97  nfev++;
98  x[j] = _x[j];
99  jac.col(j) = (val2 - val1) / h;
100  break;
101  case Central:
102  x[j] += h;
103  Functor::operator()(x, val2);
104  nfev++;
105  x[j] -= 2 * h;
106  Functor::operator()(x, val1);
107  nfev++;
108  x[j] = _x[j];
109  jac.col(j) = (val2 - val1) / (2 * h);
110  break;
111  default:
112  eigen_assert(false);
113  };
114  }
115  return nfev;
116  }
117 
118  private:
119  Scalar epsfcn;
120 
121  NumericalDiff& operator=(const NumericalDiff&);
122 };
123 
124 } // end namespace Eigen
125 
126 // vim: ai ts=4 sts=4 et sw=4
127 #endif // EIGEN_NUMERICAL_DIFF_H
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
Namespace containing all symbols from the Eigen library.
int df(const InputType &_x, JacobianType &jac) const
Definition: NumericalDiff.h:59
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
Definition: NumericalDiff.h:35