ROOT  6.06/09
Reference Guide
Integrator.cxx
Go to the documentation of this file.
1 // @(#)root/mathmore:$Id: Integrator.cxx 19826 2007-09-19 19:56:11Z rdm $
2 // Authors: L. Moneta, M. Slawinska 10/2007
3 
4  /**********************************************************************
5  * *
6  * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 #include "Math/IFunction.h"
12 #include "Math/VirtualIntegrator.h"
13 #include "Math/Integrator.h"
15 
17 
18 #include "Math/GaussIntegrator.h"
20 
22 
23 
24 #include "RConfigure.h"
25 // #ifndef ROOTINCDIR
26 // #define MATH_NO_PLUGIN_MANAGER
27 // #endif
28 
29 #include <algorithm>
30 #include <functional>
31 #include <ctype.h> // need to use c version of tolower defined here
32 
33 
34 #include <cassert>
35 
36 #ifndef MATH_NO_PLUGIN_MANAGER
37 
38 #include "TROOT.h"
39 #include "TPluginManager.h"
40 
41 #else // case no plugin manager is available
42 #ifdef R__HAS_MATHMORE
43 #include "Math/GSLIntegrator.h"
44 #include "Math/GSLMCIntegrator.h"
45 #endif
46 
47 #endif
48 
49 
50 
51 namespace ROOT {
52 namespace Math {
53 
55  if (name == 0) return IntegrationOneDim::kDEFAULT;
56  std::string typeName(name);
57  std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );
58  if (typeName == "GAUSS") return IntegrationOneDim::kGAUSS;
59  if (typeName == "GAUSSLEGENDRE") return IntegrationOneDim::kLEGENDRE;
60  if (typeName == "ADAPTIVE") return IntegrationOneDim::kADAPTIVE;
61  if (typeName == "ADAPTIVESINGULAR") return IntegrationOneDim::kADAPTIVESINGULAR;
62  if (typeName == "NONADAPTIVE") return IntegrationOneDim::kNONADAPTIVE;
63  if (!typeName.empty()) MATH_WARN_MSG("IntegratorOneDim::GetType","Invalid type name specified - use default integrator" );
65 }
66 
69  if (type == IntegrationOneDim::kGAUSS) return "Gauss";
70  if (type == IntegrationOneDim::kLEGENDRE) return "GaussLegendre";
71  if (type == IntegrationOneDim::kADAPTIVE) return "Adaptive";
72  if (type == IntegrationOneDim::kADAPTIVESINGULAR) return "AdaptiveSingular";
73  if (type == IntegrationOneDim::kNONADAPTIVE) return "NonAdaptive";
74  MATH_WARN_MSG("IntegratorOneDim::GetType","Invalid type specified " );
75  return std::string("undefined");
76 }
77 
78 
80  if (name == 0) return IntegrationMultiDim::kDEFAULT;
81  std::string typeName(name);
82  std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );
83  if (typeName == "ADAPTIVE") return IntegrationMultiDim::kADAPTIVE;
84  if (typeName == "VEGAS") return IntegrationMultiDim::kVEGAS;
85  if (typeName == "MISER") return IntegrationMultiDim::kMISER;
86  if (typeName == "PLAIN") return IntegrationMultiDim::kPLAIN;
87  if (!typeName.empty()) MATH_WARN_MSG("IntegratorMultiDim::GetType","Invalid type name specified - use default integrator " );
89 }
90 
93  if (type == IntegrationMultiDim::kADAPTIVE) return "ADAPTIVE";
94  if (type == IntegrationMultiDim::kVEGAS) return "VEGAS";
95  if (type == IntegrationMultiDim::kMISER) return "MISER";
96  if (type == IntegrationMultiDim::kPLAIN) return "PLAIN";
97  MATH_WARN_MSG("IntegratorMultiDim::GetType","Invalid type specified " );
98  return std::string("Undefined");
99 }
100 
101 void IntegratorOneDim::SetFunction(const IMultiGenFunction &f, unsigned int icoord , const double * x ) {
102  // set function from a multi-dim function
103  // pass also x in case of multi-dim function express the other dimensions (which are fixed)
104  unsigned int ndim = f.NDim();
105  assert (icoord < ndim);
106  ROOT::Math::OneDimMultiFunctionAdapter<> adapter(f,ndim,icoord);
107  // case I pass a vector x which is needed (for example to compute I(y) = Integral( f(x,y) dx) ) need to setCX
108  if (x != 0) adapter.SetX(x, x+ ndim);
109  SetFunction(adapter,true); // need to copy this object
110 }
111 
112 
113 // methods to create integrators
114 
115 VirtualIntegratorOneDim * IntegratorOneDim::CreateIntegrator(IntegrationOneDim::Type type , double absTol, double relTol, unsigned int size, int rule) {
116  // create the concrete class for one-dimensional integration. Use the plug-in manager if needed
117 
119  if (absTol < 0) absTol = IntegratorOneDimOptions::DefaultAbsTolerance();
120  if (relTol < 0) relTol = IntegratorOneDimOptions::DefaultRelTolerance();
121  if (size <= 0) size = IntegratorOneDimOptions::DefaultWKSize();
122  if (rule <= 0) rule = IntegratorOneDimOptions::DefaultNPoints();
123  //if (ncall <= 0) ncall = IntegratorOneDimOptions::DefaultNCalls();
124 
125 
126 
127 
128 #ifndef R__HAS_MATHMORE
129  // default type is GAUSS when Mathmore is not built
130  if (type == IntegrationOneDim::kADAPTIVE ||
134 #endif
135 
136  if (type == IntegrationOneDim::kGAUSS)
137  return new GaussIntegrator(relTol);
138  if (type == IntegrationOneDim::kLEGENDRE) {
139  return new GaussLegendreIntegrator(rule,relTol);
140  }
141 
142  VirtualIntegratorOneDim * ig = 0;
143 
144 #ifdef MATH_NO_PLUGIN_MANAGER // no PM available
145 #ifdef R__HAS_MATHMORE
146  ig = new GSLIntegrator(type, absTol, relTol, size);
147 #else
148  MATH_ERROR_MSG("IntegratorOneDim::CreateIntegrator","Integrator type is not available in MathCore");
149 #endif
150 
151 #else // case of using Plugin Manager
152 
153 
154  {
156  TPluginHandler *h;
157  //gDebug = 3;
158  if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::VirtualIntegrator", "GSLIntegrator"))) {
159  if (h->LoadPlugin() == -1) {
160  MATH_WARN_MSG("IntegratorOneDim::CreateIntegrator","Error loading one dimensional GSL integrator - use Gauss integrator");
161  return new GaussIntegrator();
162  }
163 
164  // plugin manager requires a string
165  std::string typeName = GetName(type);
166 
167  ig = reinterpret_cast<ROOT::Math::VirtualIntegratorOneDim *>( h->ExecPlugin(5,typeName.c_str(), rule, absTol, relTol, size ) );
168  assert(ig != 0);
169  }
170 #ifdef DEBUG
171  std::cout << "Loaded Integrator " << typeid(*ig).name() << std::endl;
172 #endif
173  }
174 #endif
175 
176  return ig;
177 }
178 
180  // create concrete class for multidimensional integration
181 
182 #ifndef R__HAS_MATHMORE
183  // when Mathmore is not built only possible type is ADAPTIVE. There is no other choice
185 #endif
186 
188  if (absTol < 0) absTol = IntegratorMultiDimOptions::DefaultAbsTolerance();
189  if (relTol < 0) relTol = IntegratorMultiDimOptions::DefaultRelTolerance();
190  if (ncall <= 0) ncall = IntegratorMultiDimOptions::DefaultNCalls();
191  unsigned int size = IntegratorMultiDimOptions::DefaultWKSize();
192 
193 
194  // no need for PM in the adaptive case using Genz method (class is in MathCore)
195  if (type == IntegrationMultiDim::kADAPTIVE)
196  return new AdaptiveIntegratorMultiDim(absTol, relTol, ncall, size);
197 
198  // use now plugin-manager for creating the GSL integrator
199 
200  VirtualIntegratorMultiDim * ig = 0;
201 
202 #ifdef MATH_NO_PLUGIN_MANAGER // no PM available
203 #ifdef R__HAS_MATHMORE
204  ig = new GSLMCIntegrator(type, absTol, relTol, ncall);
205 #else
206  MATH_ERROR_MSG("IntegratorMultiDim::CreateIntegrator","Integrator type is not available in MathCore");
207 #endif
208 
209 #else // use ROOT Plugin-Manager to instantiate GSLMCIntegrator
210 
211  {
213  const char * pluginName = "GSLMCIntegrator";
214  TPluginHandler *h = nullptr;
215  //gDebug = 3;
216  if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::VirtualIntegrator", pluginName))) {
217  if (h->LoadPlugin() == -1) {
218  MATH_WARN_MSG("IntegratorMultiDim::CreateIntegrator","Error loading GSL MC multidim integrator - use adaptive method");
219  return new AdaptiveIntegratorMultiDim(absTol, relTol, ncall);
220  }
221 
222  std::string typeName = GetName(type);
223 
224  ig = reinterpret_cast<ROOT::Math::VirtualIntegratorMultiDim *>( h->ExecPlugin(4,typeName.c_str(), absTol, relTol, ncall ) );
225  assert(ig != 0);
226 
227 #ifdef DEBUG
228  std::cout << "Loaded Integrator " << typeid(*ig).name() << std::endl;
229 #endif
230  }
231  }
232 #endif
233  return ig;
234 }
235 
236 
237 
238 
239 } // namespace Math
240 } // namespace ROOT
static IntegrationMultiDim::Type GetType(const char *name)
static function to get the enumeration from a string
Definition: Integrator.cxx:79
Interface (abstract) class for 1D numerical integration It must be implemented by the concrate Integr...
const double absTol
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
Type
enumeration specifying the integration types.
#define assert(cond)
Definition: unittest.h:542
TH1 * h
Definition: legend2.C:5
#define gROOT
Definition: TROOT.h:340
Int_t LoadPlugin()
Load the plugin library for this handler.
R__EXTERN TVirtualMutex * gROOTMutex
Definition: TROOT.h:63
#define MATH_WARN_MSG(loc, str)
Definition: Error.h:47
User class for performing function integration.
Long_t ExecPlugin(int nargs, const T &...params)
Double_t x[n]
Definition: legend1.C:17
OneDimMultiFunctionAdapter class to wrap a multidimensional function in one dimensional one...
UChar_t mod R__LOCKGUARD2(gSrvAuthenticateMutex)
Class for performing numerical integration of a function in one dimension.
Definition: GSLIntegrator.h:98
static IntegrationOneDim::Type DefaultIntegratorType()
#define MATH_ERROR_MSG(loc, str)
Definition: Error.h:50
Interface (abstract) class for multi numerical integration It must be implemented by the concrete Int...
static IntegrationOneDim::Type GetType(const char *name)
static function to get the enumeration from a string
Definition: Integrator.cxx:54
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
static std::string GetName(IntegrationMultiDim::Type)
static function to get a string from the enumeration
Definition: Integrator.cxx:91
User class for performing function integration.
int ncall
Definition: stressTF1.cxx:20
Type
enumeration specifying the integration types.
double f(double x)
void SetX(Iterator begin, Iterator end)
Set X values in case vector is own, iterator size must match previous set dimension.
int type
Definition: TGX11.cxx:120
static std::string GetName(IntegrationOneDim::Type)
static function to get a string from the enumeration
Definition: Integrator.cxx:67
Namespace for new Math classes and functions.
#define name(a, b)
Definition: linkTestLib0.cpp:5
VirtualIntegratorMultiDim * CreateIntegrator(IntegrationMultiDim::Type type, double absTol, double relTol, unsigned int ncall)
Definition: Integrator.cxx:179
void SetFunction(Function &f)
method to set the a generic integration function
Definition: Integrator.h:499
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:63
VirtualIntegratorOneDim * CreateIntegrator(IntegrationOneDim::Type type, double absTol, double relTol, unsigned int size, int rule)
Definition: Integrator.cxx:115
class for adaptive quadrature integration in multi-dimensions using rectangular regions.