Integrator.cxx

Go to the documentation of this file.
00001 // @(#)root/mathmore:$Id: Integrator.cxx 19826 2007-09-19 19:56:11Z rdm $
00002 // Authors: L. Moneta, M. Slawinska 10/2007
00003 
00004  /**********************************************************************
00005   *                                                                    *
00006   * Copyright (c) 2004 ROOT Foundation,  CERN/PH-SFT                   *
00007   *                                                                    *
00008   *                                                                    *
00009   **********************************************************************/
00010 
00011 #include "Math/IFunction.h"
00012 #include "Math/VirtualIntegrator.h"
00013 #include "Math/Integrator.h"
00014 #include "Math/IntegratorMultiDim.h"
00015 
00016 #include "Math/AdaptiveIntegratorMultiDim.h"
00017 
00018 #include "Math/GaussIntegrator.h"
00019 #include "Math/GaussLegendreIntegrator.h"
00020 
00021 #include "Math/OneDimFunctionAdapter.h"
00022 
00023 
00024 #include "RConfigure.h"
00025 // #ifndef ROOTINCDIR
00026 // #define MATH_NO_PLUGIN_MANAGER
00027 // #endif
00028 
00029 #include <algorithm>
00030 #include <functional>
00031 #include <ctype.h>   // need to use c version of tolower defined here
00032 
00033 
00034 #include <cassert>
00035 
00036 #ifndef MATH_NO_PLUGIN_MANAGER
00037 
00038 #include "TROOT.h"
00039 #include "TPluginManager.h"
00040 
00041 #else // case no plugin manager is available
00042 #ifdef R__HAS_MATHMORE
00043 #include "Math/GSLIntegrator.h"
00044 #include "Math/GSLMCIntegrator.h"
00045 #endif
00046 
00047 #endif
00048 
00049 
00050 
00051 namespace ROOT {
00052 namespace Math {
00053 
00054 IntegrationOneDim::Type IntegratorOneDim::GetType(const char *name) { 
00055    if (name == 0) return IntegrationOneDim::kDEFAULT;
00056    std::string typeName(name);
00057    std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );  
00058    if (typeName == "GAUSS") return IntegrationOneDim::kGAUSS;  
00059    if (typeName == "GAUSSLEGENDRE") return IntegrationOneDim::kLEGENDRE;  
00060    if (typeName == "ADAPTIVE") return IntegrationOneDim::kADAPTIVE;  
00061    if (typeName == "ADAPTIVESINGULAR") return IntegrationOneDim::kADAPTIVESINGULAR;  
00062    if (typeName == "NONADAPTIVE") return IntegrationOneDim::kNONADAPTIVE;  
00063    if (!typeName.empty()) MATH_WARN_MSG("IntegratorOneDim::GetType","Invalid type name specified - return default " ); 
00064    return IntegrationOneDim::kDEFAULT; 
00065 }
00066 
00067 std::string IntegratorOneDim::GetName(IntegrationOneDim::Type type) { 
00068    if (type == IntegrationOneDim::kDEFAULT) type = GetType(IntegratorOneDimOptions::DefaultIntegrator().c_str() );
00069    if (type == IntegrationOneDim::kGAUSS) return "Gauss";
00070    if (type == IntegrationOneDim::kLEGENDRE) return "GaussLegendre";
00071    if (type == IntegrationOneDim::kADAPTIVE) return "Adaptive";
00072    if (type == IntegrationOneDim::kADAPTIVESINGULAR) return "AdaptiveSingular";
00073    if (type == IntegrationOneDim::kNONADAPTIVE) return "NonAdaptive";
00074    MATH_WARN_MSG("IntegratorOneDim::GetType","Invalid type specified " ); 
00075    return std::string("undefined");
00076 }
00077    
00078 
00079 IntegrationMultiDim::Type IntegratorMultiDim::GetType(const char *name) { 
00080    if (name == 0) return IntegrationMultiDim::kDEFAULT;
00081    std::string typeName(name); 
00082    std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );  
00083    if (typeName == "ADAPTIVE") return IntegrationMultiDim::kADAPTIVE;  
00084    if (typeName == "VEGAS") return IntegrationMultiDim::kVEGAS;  
00085    if (typeName == "MISER") return IntegrationMultiDim::kMISER;  
00086    if (typeName == "PLAIN") return IntegrationMultiDim::kPLAIN;  
00087    if (!typeName.empty()) MATH_WARN_MSG("IntegratorMultiDim::GetType","Invalid type name specified - return default " ); 
00088    return IntegrationMultiDim::kDEFAULT; 
00089 }
00090 
00091 std::string IntegratorMultiDim::GetName(IntegrationMultiDim::Type type) { 
00092    if (type == IntegrationMultiDim::kDEFAULT) type = GetType(IntegratorMultiDimOptions::DefaultIntegrator().c_str() );
00093    if (type == IntegrationMultiDim::kADAPTIVE) return "ADAPTIVE";
00094    if (type == IntegrationMultiDim::kVEGAS) return "VEGAS";
00095    if (type == IntegrationMultiDim::kMISER) return "MISER";
00096    if (type == IntegrationMultiDim::kPLAIN) return "PLAIN";
00097    MATH_WARN_MSG("IntegratorMultiDim::GetType","Invalid type specified " ); 
00098    return std::string("Undefined");
00099 }
00100 
00101 void IntegratorOneDim::SetFunction(const IMultiGenFunction &f, unsigned int icoord , const double * x ) { 
00102    // set function from a multi-dim function 
00103    // pass also x in case of multi-dim function express the other dimensions (which are fixed) 
00104    unsigned int ndim = f.NDim(); 
00105    assert (icoord < ndim); 
00106    ROOT::Math::OneDimMultiFunctionAdapter<> adapter(f,ndim,icoord);
00107    // case I pass a vector x which is needed (for example to compute I(y) = Integral( f(x,y) dx) ) need to setCX
00108    if (x != 0) adapter.SetX(x, x+ ndim);
00109    SetFunction(adapter,true); // need to copy this object
00110 }
00111 
00112 
00113 // methods to create integrators 
00114 
00115 VirtualIntegratorOneDim * IntegratorOneDim::CreateIntegrator(IntegrationOneDim::Type type , double absTol, double relTol, unsigned int size, int rule) { 
00116    // create the concrete class for one-dimensional integration. Use the plug-in manager if needed 
00117 
00118    if (type == IntegrationOneDim::kDEFAULT) type = IntegratorOneDimOptions::DefaultIntegratorType();
00119    if (absTol <= 0) absTol = IntegratorOneDimOptions::DefaultAbsTolerance(); 
00120    if (relTol <= 0) relTol = IntegratorOneDimOptions::DefaultRelTolerance(); 
00121    if (size <= 0)  size = IntegratorOneDimOptions::DefaultWKSize(); 
00122    if (rule <= 0)  rule = IntegratorOneDimOptions::DefaultNPoints(); 
00123    //if (ncall  <= 0) ncall  = IntegratorOneDimOptions::DefaultNCalls(); 
00124 
00125 
00126    
00127 
00128 #ifndef R__HAS_MATHMORE   
00129    // default type is GAUSS when Mathmore is not built
00130    if (type == IntegrationOneDim::kADAPTIVE ||  
00131        type == IntegrationOneDim::kADAPTIVESINGULAR || 
00132        type == IntegrationOneDim::kNONADAPTIVE )
00133       type = IntegrationOneDim::kGAUSS; 
00134 #endif
00135 
00136    if (type == IntegrationOneDim::kGAUSS)
00137       return new GaussIntegrator(relTol);
00138    if (type == IntegrationOneDim::kLEGENDRE) { 
00139       return new GaussLegendreIntegrator(rule,relTol);
00140    }
00141 
00142    VirtualIntegratorOneDim * ig = 0; 
00143 
00144 #ifdef MATH_NO_PLUGIN_MANAGER    // no PM available
00145 #ifdef R__HAS_MATHMORE   
00146    ig =  new GSLIntegrator(type, absTol, relTol, size);
00147 #else 
00148    MATH_ERROR_MSG("IntegratorOneDim::CreateIntegrator","Integrator type is not available in MathCore");
00149 #endif
00150 
00151 #else  // case of using Plugin Manager
00152    
00153 
00154 
00155    TPluginHandler *h; 
00156    //gDebug = 3; 
00157    if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::VirtualIntegrator", "GSLIntegrator"))) {
00158       if (h->LoadPlugin() == -1) {
00159          MATH_WARN_MSG("IntegratorOneDim::CreateIntegrator","Error loading one dimensional GSL integrator - use Gauss integrator"); 
00160          return new GaussIntegrator();
00161       }
00162       
00163       // plugin manager requires a string
00164       std::string typeName = GetName(type);
00165             
00166       ig = reinterpret_cast<ROOT::Math::VirtualIntegratorOneDim *>( h->ExecPlugin(5,typeName.c_str(), rule, absTol, relTol, size ) ); 
00167       assert(ig != 0);
00168       
00169 
00170 #ifdef DEBUG
00171       std::cout << "Loaded Integrator " << typeid(*ig).name() << std::endl;
00172 #endif
00173    }
00174 
00175 #endif 
00176 
00177    return ig;  
00178 }
00179 
00180 VirtualIntegratorMultiDim * IntegratorMultiDim::CreateIntegrator(IntegrationMultiDim::Type type , double absTol, double relTol, unsigned int ncall) { 
00181    // create concrete class for multidimensional integration 
00182    if (type == IntegrationMultiDim::kDEFAULT) type = GetType(IntegratorMultiDimOptions::DefaultIntegrator().c_str());
00183    if (absTol <= 0) absTol = IntegratorMultiDimOptions::DefaultAbsTolerance(); 
00184    if (relTol <= 0) relTol = IntegratorMultiDimOptions::DefaultRelTolerance(); 
00185    if (ncall  <= 0) ncall  = IntegratorMultiDimOptions::DefaultNCalls(); 
00186    unsigned int size = IntegratorMultiDimOptions::DefaultWKSize(); 
00187 
00188 
00189 #ifndef R__HAS_MATHMORE   
00190    // default type is Adaptive when Mathmore is not built
00191    type = IntegrationMultiDim::kADAPTIVE; 
00192 #endif
00193 
00194    // no need for PM in the adaptive  case using Genz method (class is in MathCore)
00195    if (type == IntegrationMultiDim::kADAPTIVE)
00196       return new AdaptiveIntegratorMultiDim(absTol, relTol, ncall, size);
00197       
00198    VirtualIntegratorMultiDim * ig = 0; 
00199 
00200 #ifdef MATH_NO_PLUGIN_MANAGER  // no PM available 
00201 #ifdef R__HAS_MATHMORE   
00202    ig =  new GSLMCIntegrator(type, absTol, relTol, ncall);
00203 #else 
00204    MATH_ERROR_MSG("IntegratorMultiDim::CreateIntegrator","Integrator type is not available in MathCore");
00205 #endif
00206 
00207 #else  // use ROOT PM 
00208       
00209    TPluginHandler *h; 
00210    //gDebug = 3; 
00211    if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::VirtualIntegrator", "GSLMCIntegrator"))) {
00212       if (h->LoadPlugin() == -1) {
00213          MATH_WARN_MSG("IntegratorMultiDim::CreateIntegrator","Error loading GSL MC multidim integrator - use adaptive method"); 
00214          return new AdaptiveIntegratorMultiDim(absTol, relTol, ncall);
00215       }
00216 
00217       std::string typeName = GetName(type);
00218       
00219       ig = reinterpret_cast<ROOT::Math::VirtualIntegratorMultiDim *>( h->ExecPlugin(4,typeName.c_str(), absTol, relTol, ncall ) ); 
00220       assert(ig != 0);
00221 
00222 #ifdef DEBUG
00223       std::cout << "Loaded Integrator " << typeid(*ig).name() << std::endl;
00224 #endif
00225    }
00226 #endif
00227    return ig;  
00228 }
00229 
00230 
00231 
00232 
00233 } // namespace Math
00234 } // namespace ROOT

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