GCOP
1.0
|
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