00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "QMCMikesBracketingStepLengthSelector.h"
00014
00015 double QMCMikesBracketingStepLengthSelector::stepLength(
00016 QMCObjectiveFunction *function, Array1D<double> & position,
00017 Array1D<double> & searchDirection, Array1D<double> & gradient,
00018 Array2D<double> & unused,
00019 double functionValue)
00020
00021 {
00022 double initial_step_length=0.001;
00023 double initial_alpha=0.0;
00024
00025
00026 bracket(function, position,searchDirection,initial_alpha,
00027 initial_step_length,0);
00028
00029 print_interval();
00030
00031
00032
00033
00034 if(alpha_middle<0.0)
00035 {
00036 return 0.0;
00037 }
00038
00039
00040 bool done=false;
00041 int counter=0;
00042 while(!done)
00043 {
00044
00045 quadratic_rebracketer(function,position,searchDirection);
00046
00047 print_interval();
00048
00049
00050 if(counter>=3)
00051 {
00052 done=true;
00053 }
00054 counter++;
00055 }
00056 return alpha_middle;
00057 }
00058
00059 void QMCMikesBracketingStepLengthSelector::print_interval()
00060 {
00061 cout<<endl;
00062 cout<<"alphas:\t"<<alpha_left<<"\t"<<alpha_middle<<"\t"<<alpha_right<<endl;
00063 cout<<"scores:\t"<<score_left<<"\t"<<score_middle<<"\t"<<score_right<<endl;
00064 cout<<endl;
00065 }
00066
00067
00068 void QMCMikesBracketingStepLengthSelector::bracket(QMCObjectiveFunction *OF,
00069 Array1D<double> & position,Array1D<double> & searchDirection,
00070 double alpha_zero,double scale,int recursion_depth)
00071 {
00072 cout<<"\nbracket()"<<endl;
00073 cout<<"x: "<<position;
00074 cout<<"p: "<<searchDirection;
00075 cout<<alpha_zero<<"\t"<<scale<<"\t"<<recursion_depth<<endl;
00076
00077 if(recursion_depth<4)
00078 {
00079
00080 int steps=8;
00081
00082
00083 Array1D < Array1D <double> > population;
00084 population.allocate(steps);
00085 for(int i=0;i<steps;i++)
00086 {
00087 population(i).allocate(position.dim1());
00088 }
00089
00090
00091 Array1D<double> alphas;
00092 alphas.allocate(steps);
00093
00094
00095 Array1D<double> scores;
00096 scores.allocate(steps);
00097
00098
00099 Array1D< QMCObjectiveFunctionResult > results;
00100 results.allocate(steps);
00101
00102
00103 alphas(0)=alpha_zero;
00104 double temp=1.0;
00105 for(int i=1;i<population.dim1();i++)
00106 {
00107
00108 temp=temp*2.0;
00109 alphas(i)=alpha_zero+scale*temp;
00110 }
00111
00112
00113 for(int i=0;i<population.dim1();i++)
00114 {
00115 for(int j=0;j<population(i).dim1();j++)
00116 {
00117 population(i)(j)=position(j)+alphas(i)*
00118 searchDirection(j);
00119 }
00120 cout<<population(i);
00121 }
00122
00123 cout<<"evaluating in bracketer"<<endl;
00124 results = OF->evaluate(population);
00125 cout<<"just after evaluating in bracketer"<<endl;
00126
00127
00128 for(int i=0;i<population.dim1();i++)
00129 {
00130 scores(i)=results(i).getScore();
00131
00132 if(IeeeMath::isNaN(scores(i)) != 0)
00133 {
00134 scores(i) = 1e30;
00135 }
00136 }
00137
00138 cout << "\nALPHAS = " << alphas;
00139 cout << "SCORES = " << scores<<endl;;
00140
00141
00142 int min_index=0;
00143 double min_score=scores(0)+1e6;
00144 for(int i=0;i<population.dim1();i++)
00145 {
00146 if(min_score>scores(i))
00147 {
00148 min_score=scores(i);
00149 min_index=i;
00150 }
00151 cout << "min_index = " << min_index << endl;
00152 }
00153
00154
00155 if(min_index==steps-1)
00156 {
00157 cout << "Bracket Stepping Further --------------" << endl;
00158
00159 scale=scale*pow(2.0,(double)(steps-3));
00160
00161
00162
00163
00164 bracket(OF, position,searchDirection,alphas(steps-2),scale,
00165 recursion_depth+1);
00166 }
00167
00168
00169
00170 else if(min_index==0)
00171 {
00172 cout << "Bracket Stepping Closer --------------" << endl;
00173
00174
00175
00176 scale=scale*pow(2.0,(double)(-1.0*(steps-2)));
00177
00178
00179 bracket(OF,position,searchDirection,alphas(0),scale,
00180 recursion_depth+1);
00181 }
00182
00183
00184
00185 else
00186 {
00187
00188
00189 alpha_left = alphas(min_index-1);
00190 score_left = scores(min_index-1);
00191 alpha_middle = alphas(min_index);
00192 score_middle = scores(min_index);
00193 alpha_right = alphas(min_index+1);
00194 score_right = scores(min_index+1);
00195 }
00196 }
00197 else
00198 {
00199 alpha_left = -1.0;
00200 alpha_middle = -1.0;
00201 alpha_right = -1.0;
00202 }
00203 }
00204
00205
00206 void QMCMikesBracketingStepLengthSelector::quadratic_rebracketer(
00207 QMCObjectiveFunction * OF, Array1D<double> & position, Array1D<double> & searchDirection)
00208 {
00209
00210 int trials=4;
00211
00212
00213 Array1D < Array1D <double> > population;
00214 population.allocate(trials);
00215 for(int i=0;i<trials;i++)
00216 {
00217 population(i).allocate(position.dim1());
00218 }
00219
00220
00221 Array1D<double> alphas;
00222 alphas.allocate(trials);
00223
00224
00225 Array1D<double> scores;
00226 scores.allocate(trials);
00227
00228
00229 Array1D< QMCObjectiveFunctionResult > results;
00230 results.allocate(trials);
00231
00232
00233 double alpha_star;
00234
00235
00236 double a=alpha_left;
00237 double b=alpha_middle;
00238 double c=alpha_right;
00239 double fa=score_left;
00240 double fb=score_middle;
00241 double fc=score_right;
00242 double bafbfc=(b-a)*(fb-fc);
00243 double bcfbfa=(b-c)*(fb-fa);
00244
00245
00246 alpha_star=b-0.5*((b-a)*bafbfc-(b-c)*bcfbfa)/(bafbfc-bcfbfa);
00247
00248
00249 double d_LM=alpha_middle-alpha_left;
00250 double d_MR=alpha_right-alpha_middle;
00251
00252
00253 double buffer_fraction=0.1;
00254
00255
00256 if(alpha_star<(alpha_left+buffer_fraction*d_LM))
00257 {
00258 alpha_star=alpha_left+buffer_fraction*d_LM;
00259 }
00260
00261
00262 if(alpha_star>(alpha_middle-buffer_fraction*d_LM))
00263 {
00264 alpha_star=alpha_middle-buffer_fraction*d_LM;
00265 }
00266 if(alpha_star<(alpha_middle+buffer_fraction*d_MR))
00267 {
00268 alpha_star=alpha_middle+buffer_fraction*d_MR;
00269 }
00270
00271
00272 if(alpha_star>(alpha_right-buffer_fraction*d_MR))
00273 {
00274 alpha_star=alpha_right-buffer_fraction*d_MR;
00275 }
00276
00277
00278
00279 if(alpha_star<alpha_middle)
00280 {
00281 alphas(0) = (alpha_left+alpha_star)/2.0;
00282 alphas(1) = alpha_star;
00283 alphas(2) = (alpha_star+alpha_middle)/2.0;
00284 alphas(3) = (alpha_middle+alpha_right)/2.0;
00285 }
00286 else
00287 {
00288 alphas(0) = (alpha_left+alpha_middle)/2.0;
00289 alphas(1) = (alpha_middle+alpha_star)/2.0;
00290 alphas(2) = alpha_star;
00291 alphas(3) = (alpha_star+alpha_right)/2.0;
00292 }
00293
00294
00295 for(int i=0;i<population.dim1();i++)
00296 {
00297 for(int j=0;j<population(i).dim1();j++)
00298 {
00299 population(i)(j)=position(j)+alphas(i)*
00300 searchDirection(j);
00301 }
00302 }
00303
00304
00305 results = OF->evaluate(population);
00306
00307
00308 for(int i=0;i<population.dim1();i++)
00309 {
00310 scores(i)=results(i).getScore();
00311 }
00312
00313
00314
00315 int min_index=-1;
00316
00317 double min_score=score_middle;
00318 for(int i=0;i<population.dim1();i++)
00319 {
00320 if(min_score>scores(i))
00321 {
00322 min_score=scores(i);
00323 min_index=i;
00324 }
00325 }
00326
00327
00328 if(min_index==-1)
00329 {
00330
00331 if(alpha_star<alpha_middle)
00332 {
00333
00334 alpha_left = alphas(2);
00335 score_left = scores(2);
00336 alpha_right = alphas(3);
00337 score_right = scores(3);
00338 }
00339 else
00340 {
00341
00342 alpha_left = alphas(0);
00343 score_left = scores(0);
00344 alpha_right = alphas(1);
00345 score_right = scores(1);
00346 }
00347 }
00348 else
00349 {
00350 if(alpha_star<alpha_middle)
00351 {
00352
00353 if(min_index==0)
00354 {
00355 alpha_middle = alphas(0);
00356 score_middle = scores(0);
00357 alpha_right = alphas(1);
00358 score_right = scores(1);
00359 }
00360 else if(min_index==1)
00361 {
00362 alpha_left = alphas(0);
00363 score_left = scores(0);
00364 alpha_middle = alphas(1);
00365 score_middle = scores(1);
00366 alpha_right = alphas(2);
00367 score_right = scores(2);
00368 }
00369 else if(min_index==2)
00370 {
00371 alpha_right = alpha_middle;
00372 score_right = score_middle;
00373 alpha_left = alphas(1);
00374 score_left = scores(1);
00375 alpha_middle = alphas(2);
00376 score_middle = scores(2);
00377 }
00378 else
00379 {
00380 alpha_left = alpha_middle;
00381 score_left = score_middle;
00382 alpha_middle = alphas(3);
00383 score_middle = scores(3);
00384 }
00385 }
00386 else
00387 {
00388
00389 if(min_index==0)
00390 {
00391 alpha_right = alpha_middle;
00392 score_right = score_middle;
00393 alpha_middle = alphas(0);
00394 score_middle = scores(0);
00395 }
00396 else if(min_index==1)
00397 {
00398 alpha_left = alpha_middle;
00399 score_left = score_middle;
00400 alpha_middle = alphas(1);
00401 score_middle = scores(1);
00402 alpha_right = alphas(2);
00403 score_right = scores(2);
00404 }
00405 else if(min_index==2)
00406 {
00407 alpha_left = alphas(1);
00408 score_left = scores(1);
00409 alpha_middle = alphas(2);
00410 score_middle = scores(2);
00411 alpha_right = alphas(3);
00412 score_right = scores(3);
00413 }
00414 else
00415 {
00416 alpha_left = alphas(2);
00417 score_left = scores(2);
00418 alpha_middle = alphas(3);
00419 score_middle = scores(3);
00420 }
00421 }
00422 }
00423 }
00424
00425
00426
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438