GCOP  1.0
function.h
Go to the documentation of this file.
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