GCOP
1.0
|
00001 // This file is part of libgcop, a library for Geometric Control, Optimization, and Planning (GCOP) 00002 // 00003 // Copyright (C) 2004-2014 Marin Kobilarov <marin(at)jhu.edu> 00004 // 00005 // This Source Code Form is subject to the terms of the Mozilla 00006 // Public License v. 2.0. If a copy of the MPL was not distributed 00007 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00008 00009 #ifndef GCOP_CE_H 00010 #define GCOP_CE_H 00011 00012 #include <vector> 00013 #include "gmm.h" 00014 #include <limits> 00015 00016 namespace gcop { 00017 00018 using namespace Eigen; 00019 using namespace std; 00020 00039 template <int _n = Dynamic> 00040 class Ce { 00041 public: 00042 typedef Matrix<double, _n, 1> Vectornd; 00043 typedef Matrix<double, _n, _n> Matrixnd; 00044 00051 Ce(int n = _n, int k = 1, const Matrixnd *S = 0); 00052 00053 virtual ~Ce(); 00054 00058 void Reset(); 00059 00065 virtual void AddSample(const Vectornd &z, double c); 00066 00070 void Select(); 00071 00075 bool Fit(); 00076 00082 virtual double Sample(Vectornd &z); 00083 00089 const Vectornd& Best(); 00090 00091 int n; 00092 00093 Gmm<_n> gmm; 00094 00095 Matrixnd S; 00096 00097 vector<pair<Vectornd, double> > zps; 00098 00099 vector<double> cs; 00100 00101 double rho; 00102 00103 double alpha; 00104 00105 bool mras; 00106 00107 double b; 00108 00109 bool bAuto; 00110 00111 bool inc; 00112 00113 Vectornd zmin; 00114 00115 double Jmin; 00116 00117 double Jmax; 00118 00119 double Jave; 00120 00121 }; 00122 00123 template <int _n> 00124 Ce<_n>::Ce(int n, 00125 int k, 00126 const Matrixnd *S) : 00127 n(n), 00128 gmm(n, k), 00129 rho(.1), 00130 alpha(.9), 00131 mras(false), 00132 b(1), 00133 bAuto(true), 00134 inc(false), 00135 Jmin(std::numeric_limits<double>::max()), 00136 Jmax(0), 00137 Jave(std::numeric_limits<double>::max()) 00138 { 00139 if (_n == Dynamic) { 00140 this->S.resize(n, n); 00141 this->zmin.resize(n); 00142 } else { 00143 assert(_n == n); 00144 } 00145 00146 if (S) 00147 this->S = *S; 00148 else 00149 this->S.setZero(); 00150 } 00151 00152 template <int _n> 00153 Ce<_n>::~Ce() 00154 { 00155 } 00156 00157 00158 template <int _n> 00159 void Ce<_n>::Reset() 00160 { 00161 zps.clear(); 00162 cs.clear(); 00163 Jmin = std::numeric_limits<double>::max(); 00164 Jmax = 0; 00165 } 00166 00167 template <int _n> 00168 void Ce<_n>::AddSample(const Vectornd &z, double c) 00169 { 00170 int Ns = zps.size(); 00171 if (!Ns) { 00172 Jave = c; 00173 Jmax = c; 00174 } else { 00175 Jave = (Jave*Ns + c)/(Ns + 1); 00176 } 00177 zps.push_back(make_pair(z, c)); 00178 cs.push_back(c); 00179 00180 if (Jmin > c) { 00181 zmin = z; 00182 Jmin = c; 00183 } 00184 00185 if (Jmax < c) { 00186 Jmax = c; 00187 } 00188 } 00189 00190 template <int _n> 00191 bool zpSort(const pair<Matrix<double, _n, 1>, double> &zpa, const pair<Matrix<double, _n, 1>, double> &zpb) 00192 { 00193 return zpa.second < zpb.second; 00194 } 00195 00196 template <int _n> 00197 void Ce<_n>::Select() 00198 { 00199 if (mras) { 00200 // set b to minimum cost 00201 if (bAuto) { 00202 b = Jmin; 00203 /* 00204 b = std::numeric_limits<double>::max(); 00205 for (int j = 0; j < cs.size(); ++j) { 00206 if (b > cs[j]) 00207 b = cs[j]; 00208 } 00209 */ 00210 } 00211 return; 00212 } 00213 00214 int N = zps.size(); 00215 int Ne = MIN((int)ceil(N*rho), N); 00216 00217 if (Ne < N) { 00218 std::sort(zps.begin(), zps.end(), zpSort<_n>); 00219 std::sort(cs.begin(), cs.end()); // this is redundant but is kept for consistency 00220 zps.resize(Ne); 00221 cs.resize(Ne); 00222 } 00223 } 00224 00225 00226 template <int _n> 00227 bool Ce<_n>::Fit() 00228 { 00229 int N = zps.size(); 00230 00231 if (mras) { 00232 double cn = 0; 00233 for (int j = 0; j < N; ++j) { 00234 pair<Vectornd, double> &zp = zps[j]; 00235 zp.second = exp(-b*cs[j]); // pdf 00236 cn += zp.second; // normalizer 00237 } 00238 assert(cn > 0); 00239 for (int j = 0; j < N; ++j) 00240 zps[j].second /= cn; // normalize 00241 00242 gmm.Fit(zps, alpha, 50, &S); 00243 } else { 00244 for (int j = 0; j < N; ++j) 00245 zps[j].second = 1.0/N; // probability 00246 00247 gmm.Fit(zps, alpha, 50, &S); 00248 } 00249 00250 return gmm.Update(); 00251 } 00252 00253 template <int _n> 00254 double Ce<_n>::Sample(Vectornd &z) 00255 { 00256 return gmm.Sample(z); 00257 } 00258 00259 template <int _n> 00260 const Matrix<double, _n, 1>& Ce<_n>::Best() 00261 { 00262 return zmin; 00263 } 00264 } 00265 00266 00267 #endif