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_MULTI_MIN_H
00024 #define O2SCL_MULTI_MIN_H
00025
00026 #include <o2scl/text_file.h>
00027 #include <o2scl/ovector_tlate.h>
00028 #include <o2scl/multi_funct.h>
00029
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033
00034
00035 template<class param_t, class vec_t=ovector_view>
00036 class grad_funct {
00037
00038 public:
00039
00040 virtual ~grad_funct() {}
00041
00042
00043 virtual int operator()(size_t nv, vec_t &x, vec_t &g, param_t &pa) {
00044 return 0;
00045 }
00046
00047 };
00048
00049
00050
00051 template <class param_t, class vec_t=ovector_view>
00052 class grad_funct_fptr : public grad_funct<param_t,vec_t> {
00053
00054 public:
00055
00056
00057
00058 grad_funct_fptr(int (*fp)(size_t nv, vec_t &x, vec_t &g, param_t &pa)) {
00059 fptr=fp;
00060 }
00061
00062 virtual ~grad_funct_fptr() {};
00063
00064
00065
00066 virtual int operator()(size_t nv, vec_t &x, vec_t &g, param_t &pa) {
00067 return (*fptr)(nv,x,g,pa);
00068 }
00069
00070 #ifndef DOXYGEN_INTERNAL
00071
00072 protected:
00073
00074
00075 int (*fptr)(size_t nv, vec_t &x, vec_t &g, param_t &pa);
00076
00077 #endif
00078
00079 #ifndef DOXYGENP
00080
00081 private:
00082
00083 grad_funct_fptr(const grad_funct_fptr &);
00084 grad_funct_fptr& operator=(const grad_funct_fptr&);
00085
00086 #endif
00087
00088 };
00089
00090
00091
00092 template <class tclass, class param_t, class vec_t=ovector_view>
00093 class grad_funct_mfptr : public grad_funct<param_t,vec_t> {
00094
00095 public:
00096
00097
00098
00099 grad_funct_mfptr(tclass *tp, int (tclass::*fp)
00100 (size_t nv, vec_t &x, vec_t &g, param_t &pa)) {
00101 tptr=tp;
00102 fptr=fp;
00103 }
00104
00105 virtual ~grad_funct_mfptr() {};
00106
00107
00108
00109 virtual int operator()(size_t nv, vec_t &x, vec_t &g, param_t &pa) {
00110 return (*tptr.*fptr)(nv,x,g,pa);
00111 }
00112
00113 #ifndef DOXYGEN_INTERNAL
00114
00115 protected:
00116
00117
00118 int (tclass::*fptr)(size_t nv, vec_t &x, vec_t &g, param_t &pa);
00119
00120
00121 tclass *tptr;
00122
00123 #endif
00124
00125 #ifndef DOXYGENP
00126
00127 private:
00128
00129 grad_funct_mfptr(const grad_funct_mfptr &);
00130 grad_funct_mfptr& operator=(const grad_funct_mfptr&);
00131
00132 #endif
00133
00134 };
00135
00136
00137 template<class param_t, class func_t, class vec_t=ovector_view>
00138 class gradient : public grad_funct<param_t,vec_t> {
00139
00140 public:
00141
00142 virtual ~gradient() {}
00143
00144
00145 virtual int set_function(func_t &f) {
00146 func=&f;
00147 return 0;
00148 }
00149
00150
00151
00152 virtual int operator()(size_t nv, vec_t &x, vec_t &g, param_t &pa) {
00153 return 0;
00154 }
00155
00156 #ifndef DOXYGEN_INTERNAL
00157
00158 protected:
00159
00160
00161 func_t *func;
00162
00163 #endif
00164
00165 };
00166
00167
00168 template<class param_t, class func_t, class vec_t> class simple_grad :
00169 public gradient<param_t,func_t,vec_t> {
00170
00171 public:
00172
00173 simple_grad() {
00174 epsrel=1.0e-4;
00175 epsmin=1.0e-15;
00176 }
00177
00178 virtual ~simple_grad() {}
00179
00180
00181
00182
00183 double epsrel;
00184
00185
00186 double epsmin;
00187
00188
00189
00190 virtual int operator()(size_t nv, vec_t &x, vec_t &g, param_t &pa) {
00191 double fv1, fv2, h;
00192
00193 (*this->func)(nv,x,fv1,pa);
00194
00195 for(size_t i=0;i<nv;i++) {
00196
00197 h=epsrel*fabs(x[i]);
00198 if (fabs(h)<=epsmin) h=epsrel;
00199
00200 x[i]+=h;
00201 (*this->func)(nv,x,fv2,pa);
00202 x[i]-=h;
00203 g[i]=(fv2-fv1)/h;
00204 }
00205
00206 return 0;
00207 }
00208
00209 };
00210
00211
00212 template<class param_t, size_t nv> class grad_vfunct {
00213
00214 public:
00215
00216 virtual ~grad_vfunct() {}
00217
00218
00219
00220 virtual int operator()(size_t nvar, double x[nv], double g[nv],
00221 param_t &pa) {
00222 return 0;
00223 }
00224
00225 };
00226
00227
00228
00229 template <class param_t, size_t nv>
00230 class grad_vfunct_fptr : public grad_vfunct<param_t,nv> {
00231
00232 public:
00233
00234
00235
00236 grad_vfunct_fptr(int (*fp)(size_t nv, double x[nv], double g[nv],
00237 param_t &pa)) {
00238 fptr=fp;
00239 }
00240
00241 virtual ~grad_vfunct_fptr() {};
00242
00243
00244
00245 virtual int operator()(size_t nvar, double x[nv], double g[nv],
00246 param_t &pa) {
00247 return (*fptr)(nvar,x,g,pa);
00248 }
00249
00250 #ifndef DOXYGEN_INTERNAL
00251
00252 protected:
00253
00254
00255 int (*fptr)(size_t nvar, double x[nv], double g[nv], param_t &pa);
00256
00257 #endif
00258
00259 #ifndef DOXYGENP
00260
00261 private:
00262
00263 grad_vfunct_fptr(const grad_vfunct_fptr &);
00264 grad_vfunct_fptr& operator=(const grad_vfunct_fptr&);
00265
00266 #endif
00267
00268 };
00269
00270
00271
00272 template <class tclass, class param_t, size_t nv>
00273 class grad_vfunct_mfptr : public grad_vfunct<param_t,nv> {
00274
00275 public:
00276
00277
00278
00279 grad_vfunct_mfptr(tclass *tp, int (tclass::*fp)
00280 (size_t nvar, double x[nv], double g[nv], param_t &pa)) {
00281 tptr=tp;
00282 fptr=fp;
00283 }
00284
00285 virtual ~grad_vfunct_mfptr() {};
00286
00287
00288
00289 virtual int operator()(size_t nvar, double x[nv], double g[nv],
00290 param_t &pa) {
00291 return (*tptr.*fptr)(nvar,x,g,pa);
00292 }
00293
00294 #ifndef DOXYGEN_INTERNAL
00295
00296 protected:
00297
00298
00299 int (tclass::*fptr)(size_t nvar, double x[nv], double g[nv], param_t &pa);
00300
00301
00302 tclass *tptr;
00303
00304 #endif
00305
00306 #ifndef DOXYGENP
00307
00308 private:
00309
00310 grad_vfunct_mfptr(const grad_vfunct_mfptr &);
00311 grad_vfunct_mfptr& operator=(const grad_vfunct_mfptr&);
00312
00313 #endif
00314
00315 };
00316
00317
00318 template<class param_t, class func_t, size_t nv>
00319 class gradient_array : public grad_vfunct<param_t,nv> {
00320
00321 public:
00322
00323 virtual ~gradient_array() {}
00324
00325
00326 virtual int set_function(func_t &f) {
00327 func=&f;
00328 return 0;
00329 }
00330
00331
00332
00333 virtual int operator()(size_t nvar, double x[nv], double g[nv],
00334 param_t &pa) {
00335 return 0;
00336 }
00337
00338 #ifndef DOXYGEN_INTERNAL
00339
00340 protected:
00341
00342
00343 func_t *func;
00344
00345 #endif
00346
00347 };
00348
00349
00350
00351
00352 template<class param_t, class func_t, size_t nv> class simple_grad_array :
00353 public gradient_array<param_t,func_t,nv> {
00354
00355 public:
00356
00357 simple_grad_array() {
00358 epsrel=1.0e-4;
00359 epsmin=1.0e-15;
00360 }
00361
00362 virtual ~simple_grad_array() {}
00363
00364
00365
00366
00367 double epsrel;
00368
00369
00370 double epsmin;
00371
00372
00373
00374 virtual int operator()(size_t nvar, double x[nv], double g[nv],
00375 param_t &pa) {
00376 double fv1, fv2, h;
00377
00378 (*this->func)(nv,x,fv1,pa);
00379
00380 for(size_t i=0;i<nvar;i++) {
00381
00382 h=epsrel*fabs(x[i]);
00383 if (fabs(h)<=epsmin) h=epsrel;
00384
00385 x[i]+=h;
00386 (*this->func)(nvar,x,fv2,pa);
00387 x[i]-=h;
00388 g[i]=(fv2-fv1)/h;
00389 }
00390
00391 return 0;
00392 }
00393
00394 };
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413 template<class param_t, class func_t, class dfunc_t=func_t,
00414 class vec_t=ovector_view> class multi_min {
00415
00416 public:
00417
00418
00419 int verbose;
00420
00421
00422 int ntrial;
00423
00424
00425 double tolf;
00426
00427
00428 double tolx;
00429
00430
00431 int last_ntrial;
00432
00433 multi_min() {
00434 verbose=0;
00435 ntrial=100;
00436 tolf=1.0e-4;
00437 tolx=1.0e-4;
00438 last_ntrial=0;
00439 }
00440
00441 virtual ~multi_min() {}
00442
00443
00444
00445
00446 virtual int mmin(size_t nvar, vec_t &x, double &fmin, param_t &pa,
00447 func_t &func)
00448 {
00449 return 0;
00450 }
00451
00452
00453
00454
00455
00456 virtual int mmin_de(size_t nvar, vec_t &x, double &fmin, param_t &pa,
00457 func_t &func, dfunc_t &dfunc)
00458 {
00459 return mmin(nvar,x,fmin,pa,func);
00460 }
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472 template<class vec2_t>
00473 int print_iter(size_t nv, vec2_t &x, double y, int iter,
00474 double value, double limit,
00475 std::string comment)
00476 {
00477 if (verbose<=0) return 0;
00478
00479 int i;
00480 char ch;
00481
00482 std::cout << comment << " Iteration: " << iter << std::endl;
00483 text_out_file outs(&std::cout,79);
00484 outs.word_out("x:");
00485 for(i=0;i<((int)nv);i++) outs.double_out(x[i]);
00486 outs.end_line();
00487 std::cout << "y: " << y << " Val: " << value << " Lim: "
00488 << limit << std::endl;
00489 if (verbose>1) {
00490 std::cout << "Press a key and type enter to continue. ";
00491 std::cin >> ch;
00492 }
00493
00494 return 0;
00495 }
00496
00497
00498 const char *type() { return "multi_min"; }
00499
00500 };
00501
00502 #ifndef DOXYGENP
00503 }
00504 #endif
00505
00506 #endif
00507