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_GSL_ANNEAL_H
00024 #define O2SCL_GSL_ANNEAL_H
00025
00026 #include <o2scl/sim_anneal.h>
00027 #include <gsl/gsl_rng.h>
00028 #include <gsl/gsl_siman.h>
00029
00030 #ifndef DOXYGENP
00031 namespace o2scl {
00032 #endif
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054 template<class param_t, class func_t, class vec_t=ovector_view,
00055 class rng_t=gsl_rnga> class gsl_anneal :
00056 public sim_anneal<param_t,func_t,vec_t,rng_t> {
00057 public:
00058
00059 virtual ~gsl_anneal() {}
00060
00061
00062
00063
00064 virtual int mmin(size_t nvar, vec_t &x0, double &fmin, param_t &pa,
00065 func_t &func)
00066 {
00067
00068 fmin=0.0;
00069
00070 allocate(nvar);
00071
00072 double E, new_E, best_E, T;
00073 int i, iter=0;
00074 bool done;
00075 size_t j;
00076
00077 for(j=0;j<nvar;j++) {
00078 x[j]=x0[j];
00079 best_x[j]=x0[j];
00080 }
00081
00082 E=func(nvar,x,pa);
00083 best_E=E;
00084
00085 T=this->tp->start(0.0,0,x0,NULL);
00086 done=false;
00087
00088 while (!done) {
00089 for (i=0;i<this->ntrial;++i) {
00090 for (j=0;j<nvar;j++) new_x[j]=x[j];
00091
00092 step(new_x,nvar);
00093 new_E=func(nvar,new_x,pa);
00094
00095 if(new_E<=best_E){
00096 for(j=0;j<nvar;j++) best_x[j]=new_x[j];
00097 best_E=new_E;
00098 }
00099
00100
00101
00102 if (new_E<E) {
00103 for(j=0;j<nvar;j++) x[j]=new_x[j];
00104 E=new_E;
00105 } else if (this->def_rng.random() < exp(-(new_E-E)/(boltz*T)) ) {
00106 for(j=0;j<nvar;j++) x[j]=new_x[j];
00107 E=new_E;
00108 }
00109 }
00110
00111 if (this->verbose>0) {
00112 this->print_iter(nvar,best_x,best_E,iter,T,"gsl_anneal");
00113 iter++;
00114 }
00115
00116
00117 T=this->tp->next(0.0,0,x0,NULL);
00118 if (this->tp->done(0.0,0,x0,NULL)) {
00119 done=true;
00120 }
00121 }
00122
00123 for(j=0;j<nvar;j++) x0[j]=best_x[j];
00124 fmin=best_E;
00125
00126 free();
00127
00128 return 0;
00129 }
00130
00131
00132 virtual const char *type() { return "gsl_anneal"; }
00133
00134
00135 double step_size;
00136
00137
00138 double boltz;
00139
00140 #ifndef DOXYGEN_INTERNAL
00141
00142 protected:
00143
00144
00145
00146 ovector x, new_x, best_x;
00147
00148
00149
00150
00151
00152 int allocate(size_t n, double ustep=10.0, double boltz_factor=1.0) {
00153 x.allocate(n);
00154 new_x.allocate(n);
00155 best_x.allocate(n);
00156 step_size=ustep;
00157 boltz=boltz_factor;
00158 return 0;
00159 }
00160
00161
00162 int free() {
00163 x.free();
00164 new_x.free();
00165 best_x.free();
00166 return 0;
00167 }
00168
00169
00170 int step(vec_t &sx, int nvar) {
00171 for(int i=0;i<nvar;i++) {
00172 double u=this->def_rng.random();
00173 sx[i]=2.0*u*step_size-step_size+sx[i];
00174 }
00175 return 0;
00176 }
00177
00178 #endif
00179
00180 };
00181
00182 #ifndef DOXYGENP
00183 }
00184 #endif
00185
00186 #endif