MechSys  1.0
Computing library for simulations in continuum and discrete mechanics
/home/dorival/mechsys/lib/numerical/montecarlo.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines