GCOP  1.0
rn.h
Go to the documentation of this file.
00001 #ifndef GCOP_RN_H
00002 #define GCOP_RN_H
00003 
00004 #include "manifold.h"
00005 #include <cfloat>
00006 
00007 namespace gcop {
00008   
00009   using namespace Eigen;
00010   
00014   template <int _n = Dynamic> class Rn :
00015     public Manifold< Matrix<double, _n, 1>, _n> {
00016     
00017     typedef Matrix<double, _n, 1> Vectornd;
00018     typedef Matrix<double, _n, _n> Matrixnd;
00019     
00020   public:
00021 
00022     Rn(int n = _n);
00023     
00028     static Rn<_n>& Instance();
00029     
00030     void Lift(Vectornd &v,
00031               const Vectornd &xa,
00032               const Vectornd &xb);
00033     
00034     void Retract(Vectornd &xb,
00035                  const Vectornd &xa,
00036                  const Vectornd &v);
00037 
00038     void dtau(Matrixnd &M, const Vectornd &v);
00039     
00040     void Adtau(Matrixnd &M, const Vectornd &v);
00041 
00042     static const char BND_BOX = 0;
00043     static const char BND_ELLIPSOID = 1;    
00044 
00045     char bndType; 
00046     Vectornd w;   
00047 
00059     virtual bool Bound(Vectornd &v, Vectornd &d, const Vectornd &v0);
00060 
00066     virtual bool Clip(Vectornd &v) const;
00067 
00068   };
00069 
00070   template <int _n> 
00071     Rn<_n>::Rn(int n) : Manifold<Matrix<double, _n, 1>, _n>(n), bndType(BND_BOX) {
00072     if (_n == Dynamic) {
00073       this->lb.resize(n);
00074       this->ub.resize(n);
00075       w.resize(n);
00076     }
00077     this->lb.setConstant(-1e16);
00078     this->ub.setConstant(1e16);      
00079     w.setConstant(1);
00080   }
00081   
00082   template <int _n> 
00083     Rn<_n>& Rn<_n>::Instance() {
00084     static Rn<_n> instance;
00085     return instance;
00086   }
00087 
00088   template <int _n>
00089     void Rn<_n>::Lift(Matrix<double, _n, 1> &v, 
00090                      const Matrix<double, _n, 1> &xa,
00091                      const Matrix<double, _n, 1> &xb) {
00092     v = xb - xa;
00093   }
00094 
00095   template <int _n> 
00096     void Rn<_n>::Retract(Matrix<double, _n, 1> &xb, 
00097                          const Matrix<double, _n, 1> &xa,
00098                          const Matrix<double, _n, 1> &v) {
00099     xb = xa + v;
00100   }
00101 
00102   template <int _n> 
00103     void Rn<_n>::dtau(Matrix<double, _n, _n> &M, 
00104                       const Matrix<double, _n, 1> &v) {
00105     M.setIdentity();
00106   }
00107 
00108   template <int _n> 
00109     void Rn<_n>::Adtau(Matrix<double, _n, _n> &M, 
00110                        const Matrix<double, _n, 1> &v) {
00111     M.setIdentity();
00112   }
00113 
00114   template <int _n> 
00115     bool Rn<_n>::Clip(Vectornd &v) const {
00116     if (!this->bnd)
00117       return false;
00118     
00119     bool clipped = false;
00120     if (bndType == BND_BOX) {
00121       for (int j = 0; j < v.size(); ++j) {
00122         if (v[j] < this->lb[j]) {
00123           v[j] = this->lb[j];          
00124           clipped = true;
00125         } else
00126           if (v[j] > this->ub[j]) {
00127             v[j] = this->ub[j];
00128             clipped = true;          
00129           }        
00130       }
00131     }
00132     return clipped;
00133   }
00134 
00135   template <int _n> 
00136     bool Rn<_n>::Bound(Vectornd &v, Vectornd &d, const Vectornd &v0) {
00137 
00138     if (bndType == BND_BOX) {
00139       for (int j = 0; j < v.size(); ++j) {
00140         if (v[j] < this->lb[j]) {
00141           v[j] = this->lb[j];
00142           d[j] = this->lb[j] - v0[j];        } else
00143           if (v[j] > this->ub[j]) {
00144             v[j] = this->ub[j];
00145             d[j] = this->ub[j] - v0[j];
00146         }
00147       } 
00148       return true;
00149     }
00150 
00151     if (bndType == BND_ELLIPSOID) {
00152       
00153       // if constraint satisfied
00154       if ((v.cwiseProduct(w)).dot(v) <= 1)
00155         return false;
00156 
00157       // if constraint cannot be satisfied
00158       if ((v0.cwiseProduct(w)).dot(v0) >= 1) {
00159         v = v0;
00160         d.setZero();
00161         return false;        
00162       }
00163 
00164       double a = (d.cwiseProduct(w)).dot(d);
00165       double b = 2*(d.cwiseProduct(w)).dot(v0);
00166       double c = (v0.cwiseProduct(w)).dot(v0) - 1; // should be negative
00167       assert(c <= 1e-16);
00168 
00169       double s = (- b + sqrt(b*b - 4*a*c))/(2*a);
00170       
00171       for (int i = 0; i < d.size(); ++i) {
00172         if (w[i] > 1e-16) {
00173           d[i] = s*d[i];   
00174           v[i] = v0[i] + d[i];
00175         }        
00176       }
00177       return true;
00178     }
00179     
00180   }
00181 
00182 }
00183 
00184 #endif