00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #ifndef O2SCL_MINIMIZE_H
00024 #define O2SCL_MINIMIZE_H
00025
00026
00027
00028
00029
00030
00031 #ifndef DOXYGENP
00032 namespace o2scl {
00033 #endif
00034
00035
00036
00037
00038 template<class param_t, class func_t, class dfunc_t=func_t>
00039 class minimize {
00040
00041 public:
00042
00043
00044 int verbose;
00045
00046
00047 int ntrial;
00048
00049
00050 double tolf;
00051
00052
00053 double tolx;
00054
00055
00056 int last_ntrial;
00057
00058 minimize() {
00059 verbose=0;
00060 ntrial=100;
00061 tolf=1.0e-4;
00062 tolx=1.0e-4;
00063 last_ntrial=0;
00064 }
00065
00066 virtual ~minimize() {}
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078 virtual int print_iter(double x, double y, int iter, double value=0.0,
00079 double limit=0.0, std::string comment="") {
00080
00081 if (verbose<=0) return gsl_success;
00082
00083 char ch;
00084
00085 std::cout << comment << " Iteration: " << iter << std::endl;
00086 if (x<0) std::cout << x << " ";
00087 else std::cout << " " << x << " ";
00088 if (y<0) std::cout << y << " ";
00089 else std::cout << " " << y << " ";
00090 if (value<0) std::cout << value << " ";
00091 else std::cout << " " << value << " ";
00092 if (limit<0) std::cout << limit << std::endl;
00093 else std::cout << " " << limit << std::endl;
00094 if (verbose>1) {
00095 std::cout << "Press a key and type enter to continue. ";
00096 std::cin >> ch;
00097 }
00098
00099 return gsl_success;
00100 }
00101
00102
00103
00104
00105
00106
00107
00108
00109 virtual int min(double &x, double &fmin, param_t &pa, func_t &func) {
00110 double xl, xr, f, fl, fr;
00111 xl=x*0.9;
00112 xr=x*1.1;
00113 bracket(xl,x,xr,fl,f,fr,pa,func);
00114 return min_bkt(x,xl,xr,fmin,pa,func);
00115 }
00116
00117
00118
00119
00120
00121
00122 virtual int min_bkt(double &x2, double x1, double x3, double &fmin,
00123 param_t &pa, func_t &func)
00124 {
00125 return min(x2,fmin,pa,func);
00126 }
00127
00128
00129
00130
00131
00132
00133
00134
00135 virtual int min_de(double &x, double &fmin, param_t &pa, func_t &func,
00136 dfunc_t &df)
00137 {
00138 double xl, xr, f, fl, fr;
00139 xl=x*0.9;
00140 xr=x*1.1;
00141 bracket(xl,x,xr,fl,f,fr,pa,func);
00142 return min_bkt_de(x,xl,xr,fmin,pa,func,df);
00143 }
00144
00145
00146
00147
00148
00149
00150 virtual int min_bkt_de(double &x2, double x1, double x3, double &fmin,
00151 param_t &pa, func_t &func, dfunc_t &df)
00152 {
00153 return min_de(x2,fmin,pa,func,df);
00154 }
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167 virtual int bracket(double &ax, double &bx, double &cx, double &fa,
00168 double &fb, double &fc, param_t &pa,
00169 func_t &func)
00170 {
00171
00172 double x=ax, x2=bx, x3=(ax+bx)/2.0;
00173 double fx, fx3, fx2;
00174 int i=0;
00175
00176 bool done=false;
00177 while(done==false && i<20) {
00178 func(x,fx,pa);
00179 func(x2,fx2,pa);
00180 func(x3,fx3,pa);
00181
00182 if (fx3>=fx2 && fx3>=fx) {
00183 if (fx2>fx) {
00184 x2=x3;
00185 x3=(x+x2)/2.0;
00186 } else {
00187 x=x3;
00188 x3=(x+x2)/2.0;
00189 }
00190 } else if (fx<=fx3 && fx3<=fx2) {
00191 x3=x;
00192 x=x2-2.0*(x2-x);
00193 } else if (fx3<fx2 && fx3<fx) {
00194 done=true;
00195 ax=x;
00196 bx=x3;
00197 cx=x2;
00198 fa=fx;
00199 fb=fx3;
00200 fc=fx2;
00201 } else {
00202 x3=x2;
00203 x2=x+2.0*(x2-x);
00204 }
00205 i++;
00206 }
00207
00208 if (done==false) {
00209 set_err_ret("Too many iterations in minimize::bracket().",
00210 gsl_emaxiter);
00211 }
00212
00213 return 0;
00214 }
00215
00216
00217 virtual const char *type() { return "minimize"; }
00218
00219 };
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237 inline double constraint(double x, double center, double width,
00238 double height) {
00239 double ret=0.0;
00240 if (x>center+width) {
00241 ret=height*(1.0+fabs(x-center-width)/width);
00242 } else if (x<center-width) {
00243 ret=height*(1.0+fabs(x-center+width)/width);
00244 }
00245 return ret;
00246 }
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272 inline double cont_constraint(double x, double center, double width,
00273 double height, double tightness=40.0,
00274 double exp_arg_limit=50.0) {
00275 double ret, wid2=width*width;
00276 double arg=tightness/wid2*(x-center-width)*(center+width-x);
00277 if (arg<-exp_arg_limit) {
00278 ret=(x-center)*(x-center)/wid2;
00279 } else {
00280 ret=(x-center)*(x-center)/wid2/(1.0+exp(arg));
00281 }
00282 return ret;
00283 }
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 inline double lower_bound(double x, double center, double width,
00301 double height) {
00302 double ret=0.0;
00303 if (x<center) ret=height*(1.0+fabs(x-center)/width);
00304 return ret;
00305 }
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324 inline double cont_lower_bound(double x, double center, double width,
00325 double height, double tightness=40.0,
00326 double exp_arg_limit=50.0) {
00327 double ret, arg=tightness*(x-center)/width;
00328 if (arg>exp_arg_limit) {
00329 ret=0.0;
00330 } else if (arg<-exp_arg_limit) {
00331 ret=height*(center-x+width);
00332 } else {
00333 ret=height*(center-x+width)/(1.0+exp(arg));
00334 }
00335 return ret;
00336 }
00337
00338 #ifndef DOXYGENP
00339 }
00340 #endif
00341
00342 #endif