NumericalDiff.h
Go to the documentation of this file.
00001 // -*- coding: utf-8
00002 // vim: set fileencoding=utf-8
00003 
00004 // This file is part of Eigen, a lightweight C++ template library
00005 // for linear algebra.
00006 //
00007 // Copyright (C) 2009 Thomas Capricelli <orzel@freehackers.org>
00008 //
00009 // This Source Code Form is subject to the terms of the Mozilla
00010 // Public License v. 2.0. If a copy of the MPL was not distributed
00011 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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     // forward constructors
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         /* Local variables */
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         // TODO : we should do this only if the size is not already known
00074         val1.resize(Functor::values());
00075         val2.resize(Functor::values());
00076 
00077         // initialization
00078         switch(mode) {
00079             case Forward:
00080                 // compute f(x)
00081                 Functor::operator()(x, val1); nfev++;
00082                 break;
00083             case Central:
00084                 // do nothing
00085                 break;
00086             default:
00087                 assert(false);
00088         };
00089 
00090         // Function Body
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 } // end namespace Eigen
00125 
00126 //vim: ai ts=4 sts=4 et sw=4
00127 #endif // EIGEN_NUMERICAL_DIFF_H
00128 


win_eigen
Author(s): Daniel Stonier
autogenerated on Mon Oct 6 2014 12:25:22