GCOP  1.0
autodiff.h
Go to the documentation of this file.
00001 #ifndef GCOP_AUTODIFF_H
00002 #define GCOP_AUTODIFF_H
00003 
00004 #include <Eigen/Dense>
00005 #include <vector>
00006 #include <assert.h>
00007 #include "system.h"
00008 #include <iostream>
00009 
00010 #define NUMBER_DIRECTIONS 16
00011 #include <unsupported/Eigen/AdolcForward>
00012 
00013 int adtl::ADOLC_numDir;
00014 
00015 namespace gcop {
00016   
00017   using namespace Eigen;
00018   
00019   template <typename T, int _n = Dynamic, int _c = Dynamic> 
00020     class Autodiff {
00021     
00022   public:
00023   
00024   typedef Matrix<double, _n, 1> Vectornd;
00025   typedef Matrix<double, _c, 1> Vectorcd;
00026   typedef Matrix<double, _n, _n> Matrixnd;
00027   typedef Matrix<double, _n, _c> Matrixncd;
00028   typedef Matrix<double, _c, _n> Matrixcnd;
00029   typedef Matrix<double, _c, _c> Matrixcd;
00030   
00031   typedef Matrix<double, Dynamic, 1> Vectormd;
00032   typedef Matrix<double, Dynamic, Dynamic> Matrixmd;
00033   typedef Matrix<double, _n, Dynamic> Matrixnmd;
00034   typedef Matrix<double, Dynamic, _n> Matrixmnd;
00035   
00036 
00037   Autodiff(System<T, Vectorcd, _n, _c> &sys);
00038   
00039   double DF(Vectornd &v, double t, const T& xa, 
00040             const Vectorcd &u, double h,
00041             Matrixnd *A, Matrixncd *B);
00042   
00043   double DF(Vectornd &v, double t, const T& xa,
00044             const Vectorcd &u, double h,
00045             const Vectormd &p,
00046             Matrixnd *A, Matrixncd *B, Matrixnmd *C);
00047 
00048 
00049   struct Fdx {
00050   Fdx(System<T, Vectorcd, _n, _c> &sys) : sys(sys) {};
00051     
00052     typedef Vectornd InputType;
00053     typedef Vectornd ValueType;
00054     typedef Matrixnd JacobianType;
00055     
00056     //    Fdx(double t, const T &x, const Vectorcd& u
00057     //    int inputs() const { return n; }
00058     //    int values() const { return n; }
00059     
00060     void operator() (const Vectornd& e, Vectornd* v) const {
00061       sys.X.Retract((T&)xe, *x, e);
00062       sys.F(*v, t, xe, *u, h);
00063     }
00064     
00065     System<T, Vectorcd, _n, _c> &sys;
00066     double t;
00067     T xe;
00068     const T *x;
00069     const Vectorcd* u;
00070     double h;
00071   };
00072   
00073   struct Fu {      
00074   Fu(System<T, Vectorcd, _n, _c> &sys) : sys(sys) {};
00075 
00076     typedef Vectorcd InputType;
00077     typedef Vectornd ValueType;
00078     typedef Matrixncd JacobianType;
00079 
00080     //    int inputs() const { return c; }
00081     //    int values() const { return n; }
00082     
00083     void operator() (const Vectorcd& u, Vectornd* v) const {
00084       sys.F(*v, t, *x, u, h);
00085     }
00086 
00087     System<T, Vectorcd, _n, _c> &sys;
00088     double t;
00089     const T* x;
00090     double h;
00091   };
00092   
00093   
00094   Fdx fdx; 
00095   Fu fu;
00096   
00097   };
00098   
00099   
00100   
00101   template <typename T, int _n, int _c> 
00102     Autodiff<T, _n, _c>::Autodiff(System<T, Matrix<double, _c, 1>, _n, _c> &sys) : 
00103     fdx(sys), fu(sys) {
00104     adtl::ADOLC_numDir = NUMBER_DIRECTIONS;
00105   }
00106 
00107   
00108   template <typename T, int _n, int _c> 
00109     double Autodiff<T, _n, _c>::DF(Vectornd &v, double t, const T &x, 
00110                                    const Matrix<double, _c ,1> &u, double h,
00111                                    Matrix<double, _n, _n> *A, Matrix<double, _n, _c> *B) {
00112     
00113 
00114     assert(A);
00115     assert(B);
00116 
00117     Matrixnd Dfdx;
00118     Matrixnd Ad;
00119     Matrixnd D;
00120     Vectornd e;
00121 
00122     
00123     fdx.t = t; 
00124     fdx.x = &x;
00125     fdx.xe = x;
00126     fdx.u = &u;
00127     fdx.h = h;
00128     AdolcForwardJacobian<System::Fdx> autoj(fdx);
00129     if (_n == Dynamic) {
00130       Dfdx.resize(n,n);
00131       Ad.resize(n,n);
00132       D.resize(n,n);
00133       e.resize(n);
00134     }
00135     
00136     e.setZero();
00137     
00138     autoj(e, &v, &Dfdx);
00139     
00140     X.Adtau(Ad, -v);
00141     X.dtau(D, -v);
00142     
00143     *A = Ad + D*Dfdx;
00144     
00145     // B matrix
00146     Matrixncd Dfu;
00147     if (_n == Dynamic || _c == Dynamic)
00148       Dfu.resize(n, c);
00149     
00150     fu.t = t; 
00151     fu.x = &xa;
00152     fu.h = h;
00153     AdolcForwardJacobian<Fdx> autoju(fu);
00154      
00155     autoju(u, &v, &Dfu);
00156     
00157     *B = D*Dfu;
00158     
00159     return 0;    
00160   }
00161   
00162   template <typename T, int _n, int _c> 
00163     double Autodiff<T, _n, _c>::F(Vectornd &v, double t, const T& xa,
00164                                   const Matrix<double, _c, 1> &u, double h,
00165                                   const VectorXd &p,
00166                                   Matrix<double, _n, _n> *A, Matrix<double, _n, _c> *B, 
00167                                   Matrix<double, _n, Dynamic> *C) {
00168     
00169   }
00170 }
00171 
00172 #endif