GCOP
1.0
|
00001 #ifndef GCOP_FUNCTION_H 00002 #define GCOP_FUNCTION_H 00003 00004 #include <Eigen/Dense> 00005 #include "manifold.h" 00006 #include "rn.h" 00007 #include <assert.h> 00008 00009 namespace gcop { 00010 00011 using namespace Eigen; 00017 template <typename T, int _n = Dynamic, int _m = Dynamic> class Function { 00018 public: 00019 typedef Matrix<double, _n, 1> Vectornd; 00020 typedef Matrix<double, _m, 1> Vectormd; 00021 typedef Matrix<double, _m, _n> Matrixmnd; 00022 00023 Function(Manifold<T, _n> &X, double eps = 1e-12); 00024 00025 virtual void F(Vectormd &f, const T &x) = 0; 00026 00027 void DF(Matrixmnd &Df, const T &x); 00028 00029 Manifold<T, _n> &X; 00030 double eps; 00031 }; 00032 00033 00034 template <typename T, int _n, int _m> 00035 Function<T, _n, _m>::Function(Manifold<T, _n> &X, double eps) : 00036 X(X), 00037 eps(eps) { 00038 } 00039 00040 00041 template <typename T, int _n, int _m> 00042 void Function<T, _n, _m>::DF(Matrix<double, _m, _n> &Df, 00043 const T &x) { 00044 00045 typedef Matrix<double, _n, 1> Vectornd; 00046 typedef Matrix<double, _m, 1> Vectormd; 00047 typedef Matrix<double, _m, _n> Matrixmnd; 00048 00049 int m = Df.rows(); 00050 int n = Df.cols(); 00051 00052 assert(n > 0); 00053 assert(m > 0); 00054 00055 T xl(x); 00056 T xr(x); 00057 Vectormd fl; 00058 Vectormd fr; 00059 Vectornd e; 00060 00061 if (_m == Dynamic) { 00062 fl.resize(m); 00063 fr.resize(m); 00064 } else { 00065 assert(_m == m); 00066 } 00067 00068 if (_n == Dynamic) { 00069 e.resize(n); 00070 } else { 00071 assert(_n == n); 00072 } 00073 00074 for (int i = 0; i < n; ++i) { 00075 e.setZero(); 00076 00077 // left 00078 e[i] = -eps; 00079 X.Retract(xl, x, e); 00080 F(fl, xl); 00081 00082 // right 00083 e[i] = eps; 00084 X.Retract(xr, x, e); 00085 F(fr, xr); 00086 00087 // central difference 00088 Df.block(0, i, m, 1) = (fr - fl)/(2*eps); 00089 } 00090 } 00091 00092 } 00093 00094 #endif 00095