00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 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 \brief Multidimensional minimization by simulated annealing (GSL) 00036 00037 Minimize by simulated annealing for an arbitrary temperature 00038 schedule and random number generator. A move is defined by 00039 \f[ 00040 x_{i,\mathrm{new}} = \mathrm{stepsize} (2 u_i - 1) + x_{i,\mathrm{old}} 00041 \f] 00042 where the \f$u_i\f$ are random numbers between 0 and 1. The 00043 random number generator and temperature schedule are set in the 00044 parent, sim_anneal. The variables minimize::tolx and 00045 minimize::tolf are not used 00046 00047 \todo Implement different stepsizes for the different dimensions 00048 00049 \future Implement a more general routine which would allow 00050 the solution of discrete problems like the Traveling Salesman 00051 problem. 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 /** \brief Calculate the minimum \c fmin of \c func w.r.t the 00062 array \c x0 of size \c nvar. 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 // Take the crucial step: see if the new point is accepted 00101 // or not, as determined by the boltzman probability 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 // apply the cooling schedule to the temperature 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 /// Return string denoting type ("gsl_anneal") 00132 virtual const char *type() { return "gsl_anneal"; } 00133 00134 /// Size of step (default 10.0). 00135 double step_size; 00136 00137 /// Boltzmann factor (default 1.0). 00138 double boltz; 00139 00140 #ifndef DOXYGEN_INTERNAL 00141 00142 protected: 00143 00144 /// \name Storage for present, next, and best vectors 00145 //@{ 00146 ovector x, new_x, best_x; 00147 //@} 00148 00149 /** \brief Allocate memory for a minimizer over \c n dimensions 00150 with stepsize \c step and Boltzmann factor \c boltz_factor 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 /// Free allocated memory 00162 int free() { 00163 x.free(); 00164 new_x.free(); 00165 best_x.free(); 00166 return 0; 00167 } 00168 00169 /// Make a step to a new attempted minimum 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
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page