Files Classes Functions Hierarchy
00001 #ifndef MINEXPDIM_H 00002 #define MINEXPDIM_H 00003 00004 #include <cassert> 00005 #include <cmath> 00006 #include <iostream> 00007 using namespace std; 00008 00009 #include <funcstate.h> 00010 00017 template< typename X > 00018 class minexpdim 00019 { 00020 public: 00021 00023 funcstate<X>* fn; 00024 00026 X* hi; 00028 X* h0; 00030 X* xi; 00032 X fmin; 00033 00034 // TODO dim from fn to avoid fn->dim references. 00035 00036 // TODO fn to reference rather than pointer. 00037 00038 00040 bool mem; 00042 uint index; 00044 bool valid; 00046 bool hasminimized; 00047 00050 uint indexmax; 00051 00053 boolc operator !() const 00054 { return valid; } 00056 virtual void reset(); 00058 virtual void operator ++ (); 00059 00061 minexpdim 00062 ( 00063 funcstate<X>& fn_, 00064 X const h0step=20.0, 00065 uintc indexmax_=500, 00066 boolc mem_=true 00067 ); 00068 00070 virtual ~minexpdim(); 00071 00073 boolc minmove(); 00075 boolc exploredimension(uintc i); 00076 00078 boolc moveOrder1(); 00079 00081 boolc moveOrder1(uintc maxloop); 00082 00085 bool magnitude_increase; 00086 00088 X himax(); 00090 X himaxtol(); 00091 00092 void h0set(X h); 00093 void hiset(X h); 00094 }; 00095 00096 template< typename X > 00097 class minexpdimN : public minexpdim<X> 00098 { 00099 public: 00100 00102 minexpdimN 00103 ( 00104 funcstate<X>& fn_, 00105 X const h0step=20.0, 00106 uintc indexmax_=1000, 00107 boolc mem_=true 00108 ); 00109 00111 virtual void operator ++ (); 00112 00113 }; 00114 00115 00116 //---------------------------------------------------- 00117 // Implementation 00118 00119 00120 template < typename X > 00121 boolc minexpdim<X>::moveOrder1() 00122 { 00123 bool res=false; 00124 for (uint i=0; i<fn->dim; ++i) 00125 { 00126 minexpdim<X>::operator ++ (); 00127 if (hasminimized) 00128 res=true; 00129 } 00130 00131 hasminimized=res; 00132 return res; 00133 } 00134 00135 00136 template < typename X > 00137 boolc minexpdim<X>::moveOrder1(uintc maxloop) 00138 { 00139 for (uint k=0; k<maxloop; ++k) 00140 { 00141 if(moveOrder1()) 00142 return true; 00143 } 00144 00145 return false; 00146 } 00147 00148 template < typename X > 00149 void minexpdim<X>::operator ++ () 00150 { 00151 //cout << "minexpdim<X>::operator ++" << endl; 00152 if (!valid) 00153 return; 00154 00155 if (index>indexmax) 00156 { 00157 valid=false; 00158 #ifndef NDEBUG 00159 cout << "error: indexmax reached " << SHOW(index) << endl; 00160 #endif 00161 return; 00162 } 00163 00164 exploredimension(index % fn->dim); 00165 00166 ++index; 00167 } 00168 00169 template < typename X > 00170 boolc minexpdim<X>::minmove() 00171 { 00172 (*fn)(); 00173 if (xi[fn->dim]<fmin) 00174 { 00175 fmin=xi[fn->dim]; 00176 //cout << SHOW(fmin) << endl; 00177 hasminimized=true; 00178 return true; 00179 } 00180 assert(hasminimized==false); 00181 return false; 00182 } 00183 00184 template < typename X > 00185 boolc minexpdim<X>::exploredimension(uintc i) 00186 { 00187 hasminimized=false; 00188 00189 // Remembering last hi's direction 00190 xi[i] += hi[i]; 00191 if (minmove()) 00192 { 00193 if (magnitude_increase) 00194 hi[i] *= 1.61803398875; 00195 return true; 00196 } 00197 00198 hi[i] *= -1; 00199 xi[i] += hi[i]; 00200 xi[i] += hi[i]; 00201 if (minmove()) 00202 { 00203 if (magnitude_increase) 00204 hi[i] *= 1.61803398875; 00205 return true; 00206 } 00207 00208 xi[i] -= hi[i]; 00209 xi[fn->dim] = fmin; 00210 00211 // Restore last good direction. 00212 hi[i] *= -1; 00213 00214 // Unsuccessful search - decrease h 00215 // Golden Section Search. 00216 hi[i] *= 0.61803398875; 00217 00218 return false; 00219 } 00220 00221 template < typename X > 00222 minexpdim<X>::minexpdim 00223 ( 00224 funcstate<X>& fn_, 00225 X const h0step, 00226 uintc indexmax_, 00227 boolc mem_ 00228 ) 00229 : fn(&fn_), xi(fn->xi), mem(mem_), 00230 index(0), valid(false), indexmax(indexmax_), magnitude_increase(false) 00231 { 00232 assert(fn!=0); 00233 assert(fn->dim>0); 00234 hi = new X[fn->dim]; 00235 h0 = new X[fn->dim]; 00236 00237 h0set(h0step); 00238 } 00239 00240 template < typename X > 00241 minexpdim<X>::~minexpdim() 00242 { 00243 if (mem) 00244 { 00245 delete[] hi; 00246 delete[] h0; 00247 delete fn; 00248 } 00249 hi=0; 00250 h0=0; 00251 xi=0; 00252 } 00253 00254 template < typename X > 00255 void minexpdim<X>::h0set(X h) 00256 { 00257 for (uint i=0; i<fn->dim; ++i) 00258 { 00259 assert(h!=0); 00260 h0[i] = h; 00261 } 00262 } 00263 00264 template < typename X > 00265 void minexpdim<X>::hiset(X h) 00266 { 00267 for (uint i=0; i<fn->dim; ++i) 00268 { 00269 assert(h!=0); 00270 hi[i] = h; 00271 } 00272 } 00273 00274 template < typename X > 00275 void minexpdim<X>::reset() 00276 { 00277 index=0; 00278 for (uint i=0; i<fn->dim; ++i) 00279 { 00280 assert(h0[i]!=0.0); 00281 hi[i] = h0[i]; 00282 } 00283 valid=true; 00284 00285 fmin = (*fn)(); 00286 00287 hasminimized=false; 00288 } 00289 00290 template < typename X > 00291 X minexpdim<X>::himax() 00292 { 00293 assert(fn->dim!=0); 00294 X h=hi[0]*hi[0]; 00295 for (uint i=1; i<fn->dim; ++i) 00296 { 00297 X h2(hi[i]*hi[i]); 00298 if (h2>h) 00299 h=h2; 00300 } 00301 00302 return h; 00303 } 00304 00305 template < typename X > 00306 X minexpdim<X>::himaxtol() 00307 { 00308 assert(fn->dim!=0); 00309 X h=abs(hi[0]); 00310 for (uint i=1; i<fn->dim; ++i) 00311 { 00312 X h2(abs(hi[i])); 00313 if (h2>h) 00314 h=h2; 00315 } 00316 00317 return h; 00318 } 00319 00320 template < typename X > 00321 void minexpdimN<X>::operator ++ () 00322 { 00323 bool res = minexpdim<X>::moveOrder1(); 00324 minexpdim<X>::hasminimized=res; 00325 } 00326 00327 template < typename X > 00328 minexpdimN<X>::minexpdimN 00329 ( 00330 funcstate<X>& fn_, 00331 X const h0step, 00332 uintc indexmax_, 00333 boolc mem_ 00334 ) 00335 : minexpdim<X>::minexpdim(fn_,h0step,indexmax_,mem_) 00336 { 00337 } 00338 00339 00340 #endif 00341 00342
1.5.8