Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #ifndef EIGEN_NUMERICAL_DIFF_H
00014 #define EIGEN_NUMERICAL_DIFF_H
00015
00016 namespace Eigen {
00017
00018 enum NumericalDiffMode {
00019 Forward,
00020 Central
00021 };
00022
00023
00035 template<typename _Functor, NumericalDiffMode mode=Forward>
00036 class NumericalDiff : public _Functor
00037 {
00038 public:
00039 typedef _Functor Functor;
00040 typedef typename Functor::Scalar Scalar;
00041 typedef typename Functor::InputType InputType;
00042 typedef typename Functor::ValueType ValueType;
00043 typedef typename Functor::JacobianType JacobianType;
00044
00045 NumericalDiff(Scalar _epsfcn=0.) : Functor(), epsfcn(_epsfcn) {}
00046 NumericalDiff(const Functor& f, Scalar _epsfcn=0.) : Functor(f), epsfcn(_epsfcn) {}
00047
00048
00049 template<typename T0>
00050 NumericalDiff(const T0& a0) : Functor(a0), epsfcn(0) {}
00051 template<typename T0, typename T1>
00052 NumericalDiff(const T0& a0, const T1& a1) : Functor(a0, a1), epsfcn(0) {}
00053 template<typename T0, typename T1, typename T2>
00054 NumericalDiff(const T0& a0, const T1& a1, const T2& a2) : Functor(a0, a1, a2), epsfcn(0) {}
00055
00056 enum {
00057 InputsAtCompileTime = Functor::InputsAtCompileTime,
00058 ValuesAtCompileTime = Functor::ValuesAtCompileTime
00059 };
00060
00064 int df(const InputType& _x, JacobianType &jac) const
00065 {
00066
00067 Scalar h;
00068 int nfev=0;
00069 const typename InputType::Index n = _x.size();
00070 const Scalar eps = internal::sqrt(((std::max)(epsfcn,NumTraits<Scalar>::epsilon() )));
00071 ValueType val1, val2;
00072 InputType x = _x;
00073
00074 val1.resize(Functor::values());
00075 val2.resize(Functor::values());
00076
00077
00078 switch(mode) {
00079 case Forward:
00080
00081 Functor::operator()(x, val1); nfev++;
00082 break;
00083 case Central:
00084
00085 break;
00086 default:
00087 assert(false);
00088 };
00089
00090
00091 for (int j = 0; j < n; ++j) {
00092 h = eps * internal::abs(x[j]);
00093 if (h == 0.) {
00094 h = eps;
00095 }
00096 switch(mode) {
00097 case Forward:
00098 x[j] += h;
00099 Functor::operator()(x, val2);
00100 nfev++;
00101 x[j] = _x[j];
00102 jac.col(j) = (val2-val1)/h;
00103 break;
00104 case Central:
00105 x[j] += h;
00106 Functor::operator()(x, val2); nfev++;
00107 x[j] -= 2*h;
00108 Functor::operator()(x, val1); nfev++;
00109 x[j] = _x[j];
00110 jac.col(j) = (val2-val1)/(2*h);
00111 break;
00112 default:
00113 assert(false);
00114 };
00115 }
00116 return nfev;
00117 }
00118 private:
00119 Scalar epsfcn;
00120
00121 NumericalDiff& operator=(const NumericalDiff&);
00122 };
00123
00124 }
00125
00126
00127 #endif // EIGEN_NUMERICAL_DIFF_H
00128