Files Classes Functions Hierarchy
00001 #ifndef EXPLOREH_H 00002 #define EXPLOREH_H 00003 00004 00005 #include <cassert> 00006 #include <iostream> 00007 using namespace std; 00008 00009 typedef unsigned int uint; 00010 typedef unsigned int const uintc; 00011 00012 #define SHOW(x) #x << '=' << (x) 00013 00030 template < typename FN, typename XI, typename T > 00031 class exploreh 00032 { 00033 protected: 00035 void clean(); 00037 void init(); 00038 public: 00039 00041 typedef FN FNtype; 00043 typedef XI XItype; 00045 typedef T Ttype; 00046 00048 FN fn; 00049 00051 uint index; 00053 bool valid; 00055 bool hasStateChanged; 00057 T fmin; 00059 T * hi; 00061 void h0Set( T const hnew); 00062 00063 00065 bool const evaluate() 00066 { 00067 T f1; 00068 fn(f1); 00069 if (f1<fmin) 00070 { 00071 fmin=f1; 00072 //cout << SHOW(fmin) << endl; 00073 hasStateChanged=true; 00074 return true; 00075 } 00076 return false; 00077 } 00078 00081 void movelocal(); 00082 00084 void move(); 00085 00087 uintc N; 00088 00090 T * h0; 00091 00093 XI xi; 00094 00096 void xiSet(XI xi_) 00097 { xi = fn.xi = xi_; } 00098 00101 uint indexmax; 00102 00103 00104 // Set with initial high h values to 00105 // avoid problem of never converging with small h values. 00106 00108 exploreh 00109 ( 00110 uintc N_, 00111 T const h0step=20.0, 00112 uintc indexmax_=500 00113 ); 00114 00116 exploreh 00117 ( 00118 FN fn_, 00119 uintc N_, 00120 T const h0step=20.0, 00121 uintc indexmax_=500 00122 ); 00123 00125 ~exploreh(); 00126 00128 bool const operator !() const 00129 { return valid; } 00130 00132 void reset(); 00133 00134 00140 void reset( T const * x0 ); 00141 00143 void operator ++ (); 00144 00146 ostream & print(ostream & os) const; 00147 00148 }; 00149 00150 00151 /* 00152 *--------------------------------------------------------------- 00153 * Implementation 00154 */ 00155 00156 00157 /* silly 00158 template < typename FN, typename XI, typename T > 00159 void exploreh<FN,XI,T>::resetposition() 00160 { 00161 T f1; 00162 fn(f1); 00163 fmin=f1; 00164 } 00165 */ 00166 00167 00168 00169 template < typename FN, typename XI, typename T > 00170 void exploreh<FN,XI,T>::movelocal() 00171 { 00172 00173 #ifndef NDEBUG 00174 if (valid==false) 00175 cout << "error" << endl; 00176 assert(valid==true); 00177 #endif 00178 00179 // preserve fmin; 00180 T fmin0 = fmin; 00181 fn(fmin); 00182 //resetposition(); 00183 /* 00184 T f1; 00185 fn(f1); 00186 fmin=f1; 00187 */ 00188 00189 hasStateChanged=false; 00190 00191 for ( ; (hasStateChanged==false)&&valid; ) 00192 { 00193 operator ++ (); 00194 } 00195 00196 // Restore fmin. 00197 fmin = fmin0; 00198 } 00199 00200 00201 template < typename FN, typename XI, typename T > 00202 void exploreh<FN,XI,T>::move() 00203 { 00204 #ifndef NDEBUG 00205 if (valid==false) 00206 cout << "error: exploreh.valid is false" << endl; 00207 // assert(valid==true); 00208 #endif 00209 hasStateChanged=false; 00210 00211 for ( ; (hasStateChanged==false)&&valid; ) 00212 { 00213 operator ++ (); 00214 } 00215 00216 } 00217 00218 00219 template < typename FN, typename XI, typename T > 00220 ostream & exploreh<FN,XI,T>::print(ostream & os) const 00221 { 00222 os << "fmin=" << fmin; 00223 00224 os << " h: " << hi[0]; 00225 for (uint i=1; i<N; ++i) 00226 os << " " << hi[i]; 00227 os << " x: " << xi[0]; 00228 for (uint i=1; i<N; ++i) 00229 os << " " << xi[i]; 00230 00231 os << endl; 00232 00233 return os; 00234 } 00235 00236 00237 template < typename FN, typename XI, typename T > 00238 exploreh<FN,XI,T>::exploreh(uintc N_, T const h0step, uintc indexmax_) 00239 : valid(false), N(N_), indexmax(indexmax_) 00240 { 00241 init(); 00242 h0Set(h0step); 00243 } 00244 00245 template < typename FN, typename XI, typename T > 00246 exploreh<FN,XI,T>::exploreh 00247 ( 00248 FN fn_, 00249 uintc N_, 00250 T const h0step, 00251 uintc indexmax_ 00252 ) 00253 : fn(fn_), valid(false), N(N_), indexmax(indexmax_) 00254 { 00255 init(); 00256 h0Set(h0step); 00257 } 00258 00259 template < typename FN, typename XI, typename T > 00260 void exploreh<FN,XI,T>::clean() 00261 { 00262 delete[] hi; 00263 delete[] h0; 00264 hi=0; 00265 h0=0; 00266 } 00267 00268 template < typename FN, typename XI, typename T > 00269 exploreh<FN,XI,T>::~exploreh() 00270 { 00271 clean(); 00272 } 00273 00274 template < typename FN, typename XI, typename T > 00275 void exploreh<FN,XI,T>::init() 00276 { 00277 assert(N!=0); 00278 00279 index=0; 00280 hi = new T[N]; 00281 h0 = new T[N]; 00282 00283 xi = fn.xi; 00284 } 00285 00286 00287 template < typename FN, typename XI, typename T > 00288 void exploreh<FN,XI,T>::h0Set( T const hnew) 00289 { 00290 assert(N!=0); 00291 00292 for (uint i=0; i<N; ++i) 00293 hi[i] = h0[i] = hnew; 00294 } 00295 00296 template < typename FN, typename XI, typename T > 00297 void exploreh<FN,XI,T>::reset() 00298 { 00299 index=0; 00300 for (uint i=0; i<N; ++i) 00301 { 00302 assert(h0[i]!=0.0); 00303 hi[i] = h0[i]; 00304 } 00305 valid=true; 00306 00307 fn(fmin); 00308 } 00309 00310 template < typename FN, typename XI, typename T > 00311 void exploreh<FN,XI,T>::reset( T const * x0) 00312 { 00313 index=0; 00314 for (uint i=0; i<N; ++i) 00315 { 00316 assert(h0[i]!=0.0); 00317 hi[i] = h0[i]; 00318 xi[i] = x0[i]; 00319 } 00320 valid=true; 00321 00322 fn(fmin); 00323 } 00324 00325 00326 00327 template < typename FN, typename XI, typename T > 00328 void exploreh<FN,XI,T>::operator ++ () 00329 { 00330 //cout << "exploreh<FN,XI,T>::operator ++" << endl; 00331 00332 hasStateChanged=false; 00333 00334 if (!valid) 00335 return; 00336 00337 if (index>indexmax) 00338 { 00339 valid=false; 00340 #ifndef NDEBUG 00341 cout << "error: indexmax reached " << SHOW(index) << endl; 00342 #endif 00343 return; 00344 } 00345 00346 ++index; 00347 00348 for (uint i=0; i<N; ++i) 00349 { 00350 //cout << "***" << i << endl; 00351 xi[i] += hi[i]; 00352 if (evaluate()) 00353 continue; 00354 00355 hi[i] *= -1; 00356 xi[i] += hi[i]; 00357 xi[i] += hi[i]; 00358 if (evaluate()) 00359 continue; 00360 00361 xi[i] -= hi[i]; 00362 00363 // Golden Section Search. 00364 hi[i] *= 0.61803398875; 00365 } 00366 //cout << printvecfunc(xi,N) << endl; 00367 } 00368 00369 00370 00371 00372 #endif 00373 00374
1.5.8