GSLMCIntegrator.cxx

Go to the documentation of this file.
00001 // @(#)root/mathmore:$Id: GSLMCIntegrator.cxx 36822 2010-11-21 12:28:12Z moneta $
00002 // Author: Magdalena Slawinska  08/2007
00003 
00004  /**********************************************************************
00005   *                                                                    *
00006   * Copyright (c) 2007 ROOT Foundation,  CERN/PH-SFT                   *
00007   *                                                                    *
00008   * This library is free software; you can redistribute it and/or      *
00009   * modify it under the terms of the GNU General Public License        *
00010   * as published by the Free Software Foundation; either version 2     *
00011   * of the License, or (at your option) any later version.             *
00012   *                                                                    *
00013   * This library 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 GNU   *
00016   * General Public License for more details.                           *
00017   *                                                                    *
00018   * You should have received a copy of the GNU General Public License  *
00019   * along with this library (see file COPYING); if not, write          *
00020   * to the Free Software Foundation, Inc., 59 Temple Place, Suite      *
00021   * 330, Boston, MA 02111-1307 USA, or contact the author.             *
00022   *                                                                    *
00023   **********************************************************************/
00024 //
00025 // implementation file for class GSLMCIntegrator
00026 // Author: Magdalena Slawinska
00027 // 
00028 //
00029 
00030 #include "Math/IFunctionfwd.h"
00031 #include "Math/IFunction.h"
00032 #include "Math/Error.h"
00033 #include <vector>
00034 
00035 #include "GSLMonteFunctionWrapper.h"
00036 
00037 #include "Math/GSLMCIntegrator.h"
00038 #include "GSLMCIntegrationWorkspace.h"
00039 #include "GSLRngWrapper.h"
00040 
00041 #include <algorithm>
00042 #include <functional>
00043 #include <ctype.h>   // need to use c version of tolower defined here
00044 
00045 
00046 #include "gsl/gsl_monte_vegas.h"
00047 #include "gsl/gsl_monte_miser.h"
00048 #include "gsl/gsl_monte_plain.h"
00049 
00050 
00051 
00052 namespace ROOT {
00053 namespace Math {
00054 
00055 
00056                       
00057 // constructors
00058 
00059 // GSLMCIntegrator::GSLMCIntegrator():
00060 //    fResult(0),fError(0),fStatus(-1),
00061 //    fWorkspace(0),
00062 //    fFunction(0)
00063 // {
00064 //    // constructor of GSL MCIntegrator.Vegas MC is set as default integration type
00065 //    //set random number generator
00066 //    fRng = new GSLRngWrapper();      
00067 //    fRng->Allocate();
00068 //    // use the default options 
00069 //    ROOT::Math::IntegratorMultiDimOptions opts;  // this create the default options
00070 //    SetOptions(opts); 
00071 // }
00072 
00073     
00074 GSLMCIntegrator::GSLMCIntegrator(MCIntegration::Type type, double absTol, double relTol, unsigned int calls):
00075    fType(type),
00076    fDim(0),
00077    fCalls((calls > 0)  ? calls : IntegratorMultiDimOptions::DefaultNCalls()),
00078    fAbsTol((absTol >0) ? absTol : IntegratorMultiDimOptions::DefaultAbsTolerance() ),
00079    fRelTol((relTol >0) ? relTol : IntegratorMultiDimOptions::DefaultRelTolerance() ),
00080    fResult(0),fError(0),fStatus(-1),
00081    fWorkspace(0),
00082    fFunction(0)
00083 {
00084    // constructor of GSL MCIntegrator using enumeration as type 
00085    SetType(type);
00086    //set random number generator
00087    fRng = new GSLRngWrapper();      
00088    fRng->Allocate();
00089    // use the default options for the needed extra parameters 
00090    // use the default options for the needed extra parameters 
00091    if (fType == MCIntegration::kVEGAS) {    
00092       IOptions * opts = IntegratorMultiDimOptions::FindDefault("VEGAS");
00093       if (opts != 0) SetParameters( VegasParameters(*opts) );
00094    }
00095    else  if (fType == MCIntegration::kMISER) { 
00096       IOptions * opts = IntegratorMultiDimOptions::FindDefault("MISER");
00097       if (opts != 0)  SetParameters( MiserParameters(*opts) );
00098    }
00099    
00100 }
00101 
00102 GSLMCIntegrator::GSLMCIntegrator(const char * type, double absTol, double relTol, unsigned int calls):
00103    fDim(0),
00104    fCalls(calls),
00105    fAbsTol(absTol),
00106    fRelTol(relTol),
00107    fResult(0),fError(0),fStatus(-1),
00108    fWorkspace(0),
00109    fFunction(0)
00110 {
00111    // constructor of GSL MCIntegrator. Vegas MC is set as default integration type if type == 0
00112    SetTypeName(type);
00113    
00114    //set random number generator
00115    fRng = new GSLRngWrapper();      
00116    fRng->Allocate();
00117    // use the default options for the needed extra parameters 
00118    if (fType == MCIntegration::kVEGAS) {    
00119       IOptions * opts = IntegratorMultiDimOptions::FindDefault("VEGAS");
00120       if (opts != 0) SetParameters( VegasParameters(*opts) );
00121    }
00122    else  if (fType == MCIntegration::kMISER) { 
00123       IOptions * opts = IntegratorMultiDimOptions::FindDefault("MISER");
00124       if (opts != 0)  SetParameters( MiserParameters(*opts) );
00125    }
00126                              
00127 }
00128        
00129       
00130       
00131 GSLMCIntegrator::~GSLMCIntegrator()
00132 {
00133    // delete workspace 
00134    if (fWorkspace) delete fWorkspace;
00135    if (fRng != 0) delete fRng;
00136    if (fFunction != 0) delete fFunction;
00137    fRng = 0;
00138    
00139 }
00140       
00141       
00142 // disable copy ctrs
00143   
00144          
00145 GSLMCIntegrator::GSLMCIntegrator(const GSLMCIntegrator &) : 
00146    VirtualIntegratorMultiDim()
00147 {}
00148 
00149 GSLMCIntegrator & GSLMCIntegrator::operator=(const GSLMCIntegrator &) { return *this; }
00150       
00151    
00152                  
00153               
00154          
00155 void GSLMCIntegrator::SetFunction(const IMultiGenFunction &f)
00156 {
00157    // method to set the a generic integration function
00158    if(fFunction == 0) fFunction = new  GSLMonteFunctionWrapper();
00159    fFunction->SetFunction(f);
00160    fDim = f.NDim();
00161 } 
00162       
00163 void GSLMCIntegrator::SetFunction( GSLMonteFuncPointer f,  unsigned int dim, void * p  )
00164 {
00165    // method to set the a generic integration function
00166    if(fFunction == 0) fFunction = new  GSLMonteFunctionWrapper();
00167    fFunction->SetFuncPointer( f );
00168    fFunction->SetParams ( p );
00169    fDim = dim;
00170 }
00171 
00172 
00173 
00174 double GSLMCIntegrator::Integral(const double* a, const double* b)
00175 {
00176    // evaluate the Integral of a over the defined interval (a[],b[])
00177    assert(fRng != 0);
00178    gsl_rng* fr = fRng->Rng();
00179    assert(fr != 0);
00180    if (!CheckFunction()) return 0;  
00181 
00182    // initialize by  creating the right WS 
00183    // (if dimension and type are different than previous calculation)
00184    DoInitialize(); 
00185 
00186    if ( fType == MCIntegration::kVEGAS) 
00187    {
00188       GSLVegasIntegrationWorkspace * ws = dynamic_cast<GSLVegasIntegrationWorkspace *>(fWorkspace); 
00189       assert(ws != 0);
00190       fStatus = gsl_monte_vegas_integrate( fFunction->GetFunc(), (double *) a, (double*) b , fDim, fCalls, fr, ws->GetWS(),  &fResult, &fError);
00191    }
00192    else if (fType ==  MCIntegration::kMISER) 
00193    {
00194       GSLMiserIntegrationWorkspace * ws = dynamic_cast<GSLMiserIntegrationWorkspace *>(fWorkspace); 
00195       assert(ws != 0); 
00196       fStatus = gsl_monte_miser_integrate( fFunction->GetFunc(), (double *) a, (double *) b , fDim, fCalls, fr, ws->GetWS(),  &fResult, &fError);
00197    }
00198    else if (fType ==  MCIntegration::kPLAIN) 
00199    {
00200       GSLPlainIntegrationWorkspace * ws = dynamic_cast<GSLPlainIntegrationWorkspace *>(fWorkspace); 
00201       assert(ws != 0); 
00202       fStatus = gsl_monte_plain_integrate( fFunction->GetFunc(), (double *) a, (double *) b , fDim, fCalls, fr, ws->GetWS(),  &fResult, &fError);
00203    }
00204    /**/
00205    else 
00206    {
00207       
00208       fResult = 0;
00209       fError = 0;
00210       fStatus = -1;
00211       std::cerr << "GSLIntegrator - Error: Unknown integration type" << std::endl;
00212       throw std::exception(); 
00213    }
00214    
00215    return fResult;
00216    
00217 }
00218 
00219      
00220 double GSLMCIntegrator::Integral(const GSLMonteFuncPointer & f, unsigned int dim, double* a, double* b, void * p )
00221 {
00222    // evaluate the Integral for a function f over the defined interval (a[],b[])
00223    SetFunction(f,dim,p);
00224    return Integral(a,b);
00225 }
00226 
00227 
00228 /* to be added later           
00229    double GSLMCIntegrator::Integral(GSLMonteFuncPointer f, void * p, double* a, double* b)
00230    {
00231 
00232    }
00233       
00234 */
00235 //MCIntegration::Type GSLMCIntegrator::MCType() const {return fType;}
00236 
00237 /**
00238    return  the Result of the last Integral calculation
00239 */
00240 double GSLMCIntegrator::Result() const { return fResult; }
00241       
00242 /**
00243    return the estimate of the absolute Error of the last Integral calculation
00244 */
00245 double GSLMCIntegrator::Error() const { return fError; }
00246       
00247 /**
00248    return the Error Status of the last Integral calculation
00249 */
00250 int GSLMCIntegrator::Status() const { return fStatus; }
00251       
00252       
00253 // setter for control Parameters  (getters are not needed so far )
00254       
00255 /**
00256    set the desired relative Error
00257 */
00258 void GSLMCIntegrator::SetRelTolerance(double relTol){ this->fRelTol = relTol; }
00259            
00260 /**
00261    set the desired absolute Error
00262 */
00263 void GSLMCIntegrator::SetAbsTolerance(double absTol){ this->fAbsTol = absTol; }
00264            
00265 void GSLMCIntegrator::SetGenerator(GSLRngWrapper* r){ this->fRng = r; } 
00266       
00267 void GSLMCIntegrator::SetType (MCIntegration::Type type)
00268 {
00269    // create workspace according to the type 
00270    fType=type;
00271    if (fWorkspace != 0) { 
00272       if (type == fWorkspace->Type() ) return; 
00273       delete fWorkspace;  // delete because is a different type 
00274       fWorkspace = 0;
00275    }
00276    //create Workspace according to type
00277    if (type == MCIntegration::kPLAIN) { 
00278       fWorkspace = new  GSLPlainIntegrationWorkspace();
00279    }
00280    else if (type == MCIntegration::kMISER) { 
00281       fWorkspace = new  GSLMiserIntegrationWorkspace();
00282    }
00283    else {
00284        // default: use  VEGAS
00285       if (type != MCIntegration::kVEGAS) { 
00286          MATH_WARN_MSG("GSLMCIntegration","Invalid integration type : use Vegas as default");
00287          fType =  MCIntegration::kVEGAS; 
00288       }
00289       fWorkspace = new  GSLVegasIntegrationWorkspace();
00290    }
00291 }
00292 
00293 void GSLMCIntegrator::SetTypeName(const char * type)
00294 {
00295    // set the integration type using a string
00296    std::string typeName = (type!=0) ? type : "VEGAS";
00297    if (type == 0) MATH_INFO_MSG("GSLMCIntegration::SetTypeName","use default Vegas integrator method");
00298    std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper ); 
00299 
00300    MCIntegration::Type integType =  MCIntegration::kVEGAS;  // default
00301 
00302    if (typeName == "PLAIN") { 
00303       integType =  MCIntegration::kPLAIN;
00304    }
00305    else if (typeName == "MISER") { 
00306       integType =  MCIntegration::kMISER;
00307    }
00308    else if (typeName != "VEGAS")  {
00309       MATH_WARN_MSG("GSLMCIntegration::SetTypeName","Invalid integration type : use Vegas as default");
00310    }
00311 
00312    // create the fWorkspace object
00313    if (integType != fType) SetType(integType);
00314 }
00315 
00316 
00317 void GSLMCIntegrator::SetMode(MCIntegration::Mode mode)
00318 {
00319    //   set integration mode for VEGAS method
00320    if(fType ==  ROOT::Math::MCIntegration::kVEGAS)
00321    {  
00322       GSLVegasIntegrationWorkspace * ws = dynamic_cast<GSLVegasIntegrationWorkspace *>(fWorkspace); 
00323       assert(ws != 0);
00324       if(mode == MCIntegration::kIMPORTANCE) ws->GetWS()->mode = GSL_VEGAS_MODE_IMPORTANCE;
00325       else if(mode == MCIntegration::kSTRATIFIED) ws->GetWS()->mode = GSL_VEGAS_MODE_STRATIFIED;
00326       else if(mode == MCIntegration::kIMPORTANCE_ONLY) ws->GetWS()->mode = GSL_VEGAS_MODE_IMPORTANCE_ONLY;
00327    }
00328 
00329    else std::cerr << "Mode not matching integration type";
00330 }
00331 
00332 void GSLMCIntegrator::SetOptions(const ROOT::Math::IntegratorMultiDimOptions & opt)
00333 {
00334    //   set integration options
00335    SetTypeName(opt.Integrator().c_str() );
00336    SetAbsTolerance( opt.AbsTolerance() );
00337    SetRelTolerance( opt.RelTolerance() );
00338    fCalls = opt.NCalls();
00339 
00340    //std::cout << fType << "   " <<  MCIntegration::kVEGAS << std::endl;
00341 
00342    // specific options
00343    ROOT::Math::IOptions * extraOpt = opt.ExtraOptions(); 
00344    if (extraOpt) { 
00345       if (fType ==  MCIntegration::kVEGAS ) { 
00346          VegasParameters p(*extraOpt); 
00347          SetParameters(p);
00348       }
00349       else if (fType ==  MCIntegration::kMISER ) { 
00350          MiserParameters p(fDim); // if possible pass dimension 
00351          p = (*extraOpt); 
00352          SetParameters(p);
00353       }
00354       else {
00355          MATH_WARN_MSG("GSLMCIntegrator::SetOptions","Invalid options set for the chosen integration type - ignore them");
00356       }
00357    }
00358 }
00359 
00360 
00361 void GSLMCIntegrator::SetParameters(const VegasParameters &p)
00362 {
00363    // set method parameters
00364    if (fType ==  MCIntegration::kVEGAS) 
00365    {
00366       GSLVegasIntegrationWorkspace * ws = dynamic_cast<GSLVegasIntegrationWorkspace *>(fWorkspace); 
00367       assert(ws != 0);
00368       ws->SetParameters(p);
00369    }
00370    else 
00371       MATH_ERROR_MSG("GSLIntegrator::SetParameters"," Parameters not matching integration type");
00372 }
00373 
00374 void GSLMCIntegrator::SetParameters(const MiserParameters &p)
00375 {
00376    // set method parameters
00377    if (fType ==  MCIntegration::kMISER) 
00378    {
00379       GSLMiserIntegrationWorkspace * ws = dynamic_cast<GSLMiserIntegrationWorkspace *>(fWorkspace); 
00380       assert(ws != 0); 
00381       ws->SetParameters(p);
00382    }
00383    else
00384       MATH_ERROR_MSG("GSLIntegrator::SetParameters"," Parameters not matching integration type");
00385 }
00386 
00387         
00388 void GSLMCIntegrator::DoInitialize ( )
00389 {
00390    //    initialize by setting  integration type 
00391   
00392    if (fWorkspace == 0) return; 
00393    if (fDim == fWorkspace->NDim() && fType == fWorkspace->Type() ) 
00394       return; // can use previously existing ws
00395 
00396    // otherwise clear workspace 
00397    fWorkspace->Clear(); 
00398    // and create a new one
00399    fWorkspace->Init(fDim);
00400 }  
00401 
00402 
00403 
00404 //----------- methods specific for VEGAS
00405 
00406 double GSLMCIntegrator::Sigma()
00407 {
00408    // returns the error sigma from the last iteration of the VEGAS algorithm
00409    if(fType == MCIntegration::kVEGAS)
00410    {
00411       GSLVegasIntegrationWorkspace * ws = dynamic_cast<GSLVegasIntegrationWorkspace *>(fWorkspace);
00412       assert (ws != 0);
00413       return ws->GetWS()->sigma;
00414    }
00415    else 
00416    {  
00417       std::cerr << "Parameter not mathcing integration type";
00418       return 0;
00419    }
00420 
00421 }
00422 
00423 
00424 /**
00425 */  
00426 double GSLMCIntegrator::ChiSqr()
00427 {
00428    //   returns chi-squared per degree of freedom for the estimate of the integral
00429    if(fType == MCIntegration::kVEGAS)
00430    {
00431       GSLVegasIntegrationWorkspace * ws = dynamic_cast<GSLVegasIntegrationWorkspace *>(fWorkspace);
00432       assert(ws != 0);
00433       return ws->GetWS()->chisq;
00434    }
00435    else 
00436    {
00437       std::cerr << "Parameter not mathcing integration type";
00438       return 0;
00439    }
00440 }
00441 
00442 
00443 
00444 bool GSLMCIntegrator::CheckFunction() 
00445 { 
00446    // internal method to check validity of GSL function pointer
00447    return true;
00448    /*
00449    // check if a function has been previously set.
00450    if (fFunction->IsValid()) return true; 
00451    fStatus = -1; fResult = 0; fError = 0;
00452    std::cerr << "GS:Integrator - Error : Function has not been specified " << std::endl; 
00453    return false; */
00454 }
00455       
00456 const char * GSLMCIntegrator::GetTypeName() const { 
00457    if (fType == MCIntegration::kVEGAS) return "VEGAS";
00458    if (fType == MCIntegration::kMISER) return "MISER";
00459    if (fType == MCIntegration::kPLAIN) return "PLAIN";
00460    return "UNDEFINED";
00461 }    
00462 
00463 ROOT::Math::IntegratorMultiDimOptions  GSLMCIntegrator::Options() const { 
00464    IOptions * extraOpts = ExtraOptions(); 
00465    ROOT::Math::IntegratorMultiDimOptions opt(extraOpts); 
00466    opt.SetAbsTolerance(fAbsTol); 
00467    opt.SetRelTolerance(fRelTol); 
00468    opt.SetNCalls(fCalls); 
00469    opt.SetWKSize(0);
00470    opt.SetIntegrator(GetTypeName() );
00471    return opt; 
00472 }
00473 
00474 ROOT::Math::IOptions *  GSLMCIntegrator::ExtraOptions() const { 
00475    if (!fWorkspace) return 0; 
00476    return fWorkspace->Options(); 
00477 }
00478 
00479 
00480 } // namespace Math
00481 } // namespace ROOT
00482 
00483 
00484 

Generated on Tue Jul 5 14:34:56 2011 for ROOT_528-00b_version by  doxygen 1.5.1