Eigen-unsupported  5.0.1-dev+284dcc12
 
Loading...
Searching...
No Matches
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
19namespace Eigen {
20
21enum NumericalDiffMode { Forward, Central };
22
34template <typename Functor_, NumericalDiffMode mode = Forward>
35class 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
Definition NumericalDiff.h:35
int df(const InputType &_x, JacobianType &jac) const
Definition NumericalDiff.h:59
Namespace containing all symbols from the Eigen library.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_sqrt_op< typename Derived::Scalar >, const Derived > sqrt(const Eigen::ArrayBase< Derived > &x)
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_abs_op< typename Derived::Scalar >, const Derived > abs(const Eigen::ArrayBase< Derived > &x)