00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "Math/GSLSimAnnealing.h"
00014
00015 #include "gsl/gsl_siman.h"
00016
00017 #include "Math/IFunction.h"
00018 #include "Math/GSLRndmEngines.h"
00019 #include "GSLRngWrapper.h"
00020
00021
00022 #include <cassert>
00023 #include <iostream>
00024 #include <cmath>
00025 #include <vector>
00026
00027 namespace ROOT {
00028
00029 namespace Math {
00030
00031
00032
00033
00034 GSLSimAnFunc::GSLSimAnFunc(const ROOT::Math::IMultiGenFunction & func, const double * x) :
00035 fX( std::vector<double>(x, x + func.NDim() ) ),
00036 fScale( std::vector<double>(func.NDim() )),
00037 fFunc(&func)
00038 {
00039
00040 fScale.assign(fScale.size(), 1.);
00041 }
00042
00043 GSLSimAnFunc::GSLSimAnFunc(const ROOT::Math::IMultiGenFunction & func, const double * x, const double * scale) :
00044 fX( std::vector<double>(x, x + func.NDim() ) ),
00045 fScale( std::vector<double>(scale, scale + func.NDim() ) ),
00046 fFunc(&func)
00047 {}
00048
00049
00050 double GSLSimAnFunc::Energy() const {
00051
00052 return (*fFunc)(&fX.front() );
00053 }
00054
00055 void GSLSimAnFunc::Step(const GSLRandomEngine & random, double maxstep) {
00056
00057 unsigned int ndim = NDim();
00058 for (unsigned int i = 0; i < ndim; ++i) {
00059 double urndm = random();
00060 double sstep = maxstep * fScale[i];
00061 fX[i] += 2 * sstep * urndm - sstep;
00062 }
00063 }
00064
00065
00066 double GSLSimAnFunc::Distance(const GSLSimAnFunc & f) const {
00067
00068 const std::vector<double> & x = fX;
00069 const std::vector<double> & y = f.X();
00070 unsigned int n = x.size();
00071 assert (n == y.size());
00072 if (n > 1) {
00073 double d2 = 0;
00074 for (unsigned int i = 0; i < n; ++i)
00075 d2 += ( x[i] - y[i] ) * ( x[i] - y[i] );
00076 return std::sqrt(d2);
00077 }
00078 else
00079
00080 return std::abs( x[0] - y[0] );
00081 }
00082
00083 void GSLSimAnFunc::Print() {
00084
00085
00086 std::cout << "\tx = ( ";
00087 unsigned n = NDim();
00088 for (unsigned int i = 0; i < n-1; ++i) {
00089 std::cout << fX[i] << " , ";
00090 }
00091 std::cout << fX.back() << " )\t";
00092
00093 std::cout << "E / E_best = ";
00094 }
00095
00096 GSLSimAnFunc & GSLSimAnFunc::FastCopy(const GSLSimAnFunc & rhs) {
00097
00098
00099 std::copy(rhs.fX.begin(), rhs.fX.end(), fX.begin() );
00100 return *this;
00101 }
00102
00103
00104
00105
00106
00107 namespace GSLSimAn {
00108
00109
00110 double E( void * xp) {
00111
00112 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (xp);
00113 assert (fx != 0);
00114 return fx->Energy();
00115 }
00116
00117 void Step( const gsl_rng * r, void * xp, double step_size) {
00118
00119 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (xp);
00120 assert (fx != 0);
00121
00122
00123 GSLRngWrapper rng(const_cast<gsl_rng *>(r));
00124 GSLRandomEngine random(&rng);
00125
00126 fx->Step(random, step_size);
00127 }
00128
00129 double Dist( void * xp, void * yp) {
00130
00131 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (xp);
00132 GSLSimAnFunc * fy = reinterpret_cast<GSLSimAnFunc *> (yp);
00133
00134 assert (fx != 0);
00135 assert (fy != 0);
00136 return fx->Distance(*fy);
00137 }
00138
00139 void Print(void * xp) {
00140
00141
00142 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (xp);
00143 assert (fx != 0);
00144 fx->Print();
00145 }
00146
00147
00148
00149 void Copy( void * source, void * dest) {
00150 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (source);
00151 assert (fx != 0);
00152 GSLSimAnFunc * gx = reinterpret_cast<GSLSimAnFunc *> (dest);
00153 assert (gx != 0);
00154 gx->FastCopy(*fx);
00155 }
00156
00157 void * CopyCtor( void * xp) {
00158 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (xp);
00159 assert (fx != 0);
00160 return static_cast<void *> ( fx->Clone() );
00161 }
00162
00163 void Destroy( void * xp) {
00164 GSLSimAnFunc * fx = reinterpret_cast<GSLSimAnFunc *> (xp);
00165 assert (fx != 0);
00166 delete fx;
00167 }
00168
00169 }
00170
00171
00172
00173
00174 GSLSimAnnealing::GSLSimAnnealing()
00175 {
00176
00177 }
00178
00179
00180
00181
00182
00183 int GSLSimAnnealing::Solve(const ROOT::Math::IMultiGenFunction & func, const double * x0, const double * scale, double * xmin, bool debug) {
00184
00185
00186
00187
00188 GSLSimAnFunc fx(func, x0, scale);
00189
00190 int iret = Solve(fx, debug);
00191
00192 if (iret == 0) {
00193
00194 std::copy(fx.X().begin(), fx.X().end(), xmin);
00195 }
00196 return iret;
00197
00198 }
00199
00200 int GSLSimAnnealing::Solve(GSLSimAnFunc & fx, bool debug) {
00201
00202
00203 gsl_rng * r = gsl_rng_alloc(gsl_rng_mt19937);
00204
00205
00206
00207 gsl_siman_params_t simanParams;
00208
00209
00210
00211
00212 simanParams.n_tries = fParams.n_tries;
00213 simanParams.iters_fixed_T = fParams.iters_fixed_T;
00214 simanParams.step_size = fParams.step_size;
00215
00216 simanParams.k = fParams.k;
00217 simanParams.t_initial = fParams.t_initial;
00218 simanParams.mu_t = fParams.mu;
00219 simanParams.t_min = fParams.t_min;
00220
00221
00222 if (debug)
00223 gsl_siman_solve(r, &fx, &GSLSimAn::E, &GSLSimAn::Step, &GSLSimAn::Dist,
00224 &GSLSimAn::Print, &GSLSimAn::Copy, &GSLSimAn::CopyCtor , &GSLSimAn::Destroy, 0, simanParams );
00225
00226 else
00227 gsl_siman_solve(r, &fx, &GSLSimAn::E, &GSLSimAn::Step, &GSLSimAn::Dist,
00228 0, &GSLSimAn::Copy, &GSLSimAn::CopyCtor , &GSLSimAn::Destroy, 0, simanParams );
00229
00230 return 0;
00231
00232 }
00233
00234
00235
00236
00237 }
00238
00239 }
00240