Eigen-unsupported  3.4.90 (git rev 67eeba6e720c5745abc77ae6c92ce0a44aa7b7ae)
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 #include "./InternalHeaderCheck.h"
17 
18 namespace Eigen {
19 
20 enum NumericalDiffMode {
21  Forward,
22  Central
23 };
24 
25 
37 template<typename Functor_, NumericalDiffMode mode=Forward>
38 class NumericalDiff : public Functor_
39 {
40 public:
41  typedef Functor_ Functor;
42  typedef typename Functor::Scalar Scalar;
43  typedef typename Functor::InputType InputType;
44  typedef typename Functor::ValueType ValueType;
45  typedef typename Functor::JacobianType JacobianType;
46 
47  NumericalDiff(Scalar _epsfcn=0.) : Functor(), epsfcn(_epsfcn) {}
48  NumericalDiff(const Functor& f, Scalar _epsfcn=0.) : Functor(f), epsfcn(_epsfcn) {}
49 
50  // forward constructors
51  template<typename T0>
52  NumericalDiff(const T0& a0) : Functor(a0), epsfcn(0) {}
53  template<typename T0, typename T1>
54  NumericalDiff(const T0& a0, const T1& a1) : Functor(a0, a1), epsfcn(0) {}
55  template<typename T0, typename T1, typename T2>
56  NumericalDiff(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2), epsfcn(0) {}
57 
58  enum {
59  InputsAtCompileTime = Functor::InputsAtCompileTime,
60  ValuesAtCompileTime = Functor::ValuesAtCompileTime
61  };
62 
66  int df(const InputType& _x, JacobianType &jac) const
67  {
68  using std::sqrt;
69  using std::abs;
70  /* Local variables */
71  Scalar h;
72  int nfev=0;
73  const typename InputType::Index n = _x.size();
74  const Scalar eps = sqrt(((std::max)(epsfcn,NumTraits<Scalar>::epsilon() )));
75  ValueType val1, val2;
76  InputType x = _x;
77  // TODO : we should do this only if the size is not already known
78  val1.resize(Functor::values());
79  val2.resize(Functor::values());
80 
81  // initialization
82  switch(mode) {
83  case Forward:
84  // compute f(x)
85  Functor::operator()(x, val1); nfev++;
86  break;
87  case Central:
88  // do nothing
89  break;
90  default:
91  eigen_assert(false);
92  };
93 
94  // Function Body
95  for (int j = 0; j < n; ++j) {
96  h = eps * abs(x[j]);
97  if (h == 0.) {
98  h = eps;
99  }
100  switch(mode) {
101  case Forward:
102  x[j] += h;
103  Functor::operator()(x, val2);
104  nfev++;
105  x[j] = _x[j];
106  jac.col(j) = (val2-val1)/h;
107  break;
108  case Central:
109  x[j] += h;
110  Functor::operator()(x, val2); nfev++;
111  x[j] -= 2*h;
112  Functor::operator()(x, val1); nfev++;
113  x[j] = _x[j];
114  jac.col(j) = (val2-val1)/(2*h);
115  break;
116  default:
117  eigen_assert(false);
118  };
119  }
120  return nfev;
121  }
122 private:
123  Scalar epsfcn;
124 
125  NumericalDiff& operator=(const NumericalDiff&);
126 };
127 
128 } // end namespace Eigen
129 
130 //vim: ai ts=4 sts=4 et sw=4
131 #endif // EIGEN_NUMERICAL_DIFF_H
132 
Definition: NumericalDiff.h:39
int df(const InputType &_x, JacobianType &jac) const
Definition: NumericalDiff.h:66
Namespace containing all symbols from the Eigen library.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)