![]() |
MechSys
1.0
Computing library for simulations in continuum and discrete mechanics
|
00001 /************************************************************************ 00002 * MechSys - Open Library for Mechanical Systems * 00003 * Copyright (C) 2005 Dorival M. Pedroso, Raul Durand * 00004 * Copyright (C) 2009 Sergio Galindo * 00005 * * 00006 * This program is free software: you can redistribute it and/or modify * 00007 * it under the terms of the GNU General Public License as published by * 00008 * the Free Software Foundation, either version 3 of the License, or * 00009 * any later version. * 00010 * * 00011 * This program is distributed in the hope that it will be useful, * 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 00014 * GNU General Public License for more details. * 00015 * * 00016 * You should have received a copy of the GNU General Public License * 00017 * along with this program. If not, see <http://www.gnu.org/licenses/> * 00018 ************************************************************************/ 00019 00020 #ifndef MECHSYS_MONTECARLO_H 00021 #define MECHSYS_MONTECARLO_H 00022 00023 // STL 00024 #include <cmath> 00025 #include <cfloat> // for DBL_EPSILON 00026 00027 // GSL 00028 #include <gsl/gsl_math.h> 00029 #include <gsl/gsl_monte.h> 00030 #include <gsl/gsl_monte_plain.h> 00031 #include <gsl/gsl_monte_miser.h> 00032 #include <gsl/gsl_monte_vegas.h> 00033 00034 namespace Numerical 00035 { 00036 00038 enum MCMethod 00039 { 00040 PLAIN, 00041 MISER, 00042 VEGAS 00043 }; 00044 00045 template<typename Instance> 00046 class MonteCarlo 00047 { 00048 public: 00049 // Constants 00050 static int WORKSPACE_SIZE; 00051 00052 // Typedefs 00053 typedef double (Instance::*pFun) (double * x); 00054 00056 MonteCarlo (Instance * p2Inst, MCMethod method=VEGAS, size_t NCalls=500000); 00057 00058 // Methods 00059 double Integrate (pFun p2Fun, double * ri, double * rs); 00060 double CallFun (double * r) { return (_p2inst->*_p2fun)(r); } 00061 00062 private: 00063 Instance * _p2inst; 00064 pFun _p2fun; 00065 MCMethod _method; 00066 size_t _NCALLS; 00067 }; 00068 00069 template<typename Instance> 00070 int MonteCarlo<Instance>::WORKSPACE_SIZE = 3; 00071 00074 template<typename Instance> 00075 double __monte_carlo_call_fun__(double * x,size_t dim, void *not_used_for_params) 00076 { 00077 MonteCarlo<Instance> * p2inst = static_cast<MonteCarlo<Instance>*>(not_used_for_params); 00078 return p2inst->CallFun(x); 00079 } 00080 00081 00083 00084 template<typename Instance> 00085 inline MonteCarlo<Instance>::MonteCarlo (Instance * p2Inst, MCMethod Method, size_t NCalls) 00086 : _p2inst(p2Inst), _method(Method), _NCALLS(NCalls) 00087 { 00088 } 00089 00090 template<typename Instance> 00091 inline double MonteCarlo<Instance>::Integrate(pFun p2Fun, double * ri, double * rs) 00092 { 00093 // set pointer to function 00094 _p2fun = p2Fun; 00095 00096 // function for GSL 00097 gsl_monte_function f; 00098 f.f = &__monte_carlo_call_fun__<Instance>; 00099 f.dim = WORKSPACE_SIZE; 00100 f.params = this; 00101 const gsl_rng_type *T = gsl_rng_default; 00102 gsl_rng *r = gsl_rng_alloc(T); 00103 00104 // solve 00105 double result,error; 00106 switch (_method) 00107 { 00108 case PLAIN: 00109 { 00110 gsl_monte_plain_state *wsp; 00111 wsp = gsl_monte_plain_alloc (WORKSPACE_SIZE); 00112 gsl_monte_plain_integrate(&f,ri,rs,3,_NCALLS,r,wsp,&result,&error); 00113 gsl_monte_plain_free (wsp); 00114 break; 00115 } 00116 case MISER: 00117 { 00118 gsl_monte_miser_state *wsm; 00119 wsm = gsl_monte_miser_alloc (WORKSPACE_SIZE); 00120 gsl_monte_miser_integrate(&f,ri,rs,3,_NCALLS,r,wsm,&result,&error); 00121 gsl_monte_miser_free (wsm); 00122 break; 00123 } 00124 case VEGAS: 00125 { 00126 gsl_monte_vegas_state *wsv; 00127 wsv = gsl_monte_vegas_alloc (WORKSPACE_SIZE); 00128 gsl_monte_vegas_integrate(&f,ri,rs,3,_NCALLS,r,wsv,&result,&error); 00129 //do 00130 //{ 00131 //gsl_monte_vegas_integrate(&f,ri,rs,3,_NCALLS/5,r,wsv,&result,&error); 00132 //} 00133 //while(fabs(gsl_monte_vegas_chisq(wsv)-1.0)>0.01); 00134 gsl_monte_vegas_free (wsv); 00135 break; 00136 } 00137 }; 00138 gsl_rng_free(r); 00139 00140 // Results 00141 return result; 00142 } 00143 00144 }; // namespace Numerical 00145 00146 #endif // MECHSYS_MONTECARLO_H