ROOT  6.06/08
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 
26 #include <algorithm>
27 #include <functional>
28 #include <ctype.h> // need to use c version of tolower defined here
29 
30 
31 #include <cassert>
32 
33 #ifndef MATH_NO_PLUGIN_MANAGER
34 
35 #include "TROOT.h"
36 #include "TPluginManager.h"
37 
38 #else // case no plugin manager is available
39 #ifdef R__HAS_MATHMORE
40 #include "Math/GSLIntegrator.h"
41 #include "Math/GSLMCIntegrator.h"
42 #endif
43 
44 #endif
45 
46 
47 
48 namespace ROOT {
49 namespace Math {
50 
52  if (name == 0) return IntegrationOneDim::kDEFAULT;
53  std::string typeName(name);
54  std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );
55  if (typeName == "GAUSS") return IntegrationOneDim::kGAUSS;
56  if (typeName == "GAUSSLEGENDRE") return IntegrationOneDim::kLEGENDRE;
57  if (typeName == "ADAPTIVE") return IntegrationOneDim::kADAPTIVE;
58  if (typeName == "ADAPTIVESINGULAR") return IntegrationOneDim::kADAPTIVESINGULAR;
59  if (typeName == "NONADAPTIVE") return IntegrationOneDim::kNONADAPTIVE;
60  if (!typeName.empty()) MATH_WARN_MSG("IntegratorOneDim::GetType","Invalid type name specified - use default integrator" );
62 }
63 
66  if (type == IntegrationOneDim::kGAUSS) return "Gauss";
67  if (type == IntegrationOneDim::kLEGENDRE) return "GaussLegendre";
68  if (type == IntegrationOneDim::kADAPTIVE) return "Adaptive";
69  if (type == IntegrationOneDim::kADAPTIVESINGULAR) return "AdaptiveSingular";
70  if (type == IntegrationOneDim::kNONADAPTIVE) return "NonAdaptive";
71  MATH_WARN_MSG("IntegratorOneDim::GetType","Invalid type specified " );
72  return std::string("undefined");
73 }
74 
75 
77  if (name == 0) return IntegrationMultiDim::kDEFAULT;
78  std::string typeName(name);
79  std::transform(typeName.begin(), typeName.end(), typeName.begin(), (int(*)(int)) toupper );
80  if (typeName == "ADAPTIVE") return IntegrationMultiDim::kADAPTIVE;
81  if (typeName == "VEGAS") return IntegrationMultiDim::kVEGAS;
82  if (typeName == "MISER") return IntegrationMultiDim::kMISER;
83  if (typeName == "PLAIN") return IntegrationMultiDim::kPLAIN;
84  if (!typeName.empty()) MATH_WARN_MSG("IntegratorMultiDim::GetType","Invalid type name specified - use default integrator " );
86 }
87 
90  if (type == IntegrationMultiDim::kADAPTIVE) return "ADAPTIVE";
91  if (type == IntegrationMultiDim::kVEGAS) return "VEGAS";
92  if (type == IntegrationMultiDim::kMISER) return "MISER";
93  if (type == IntegrationMultiDim::kPLAIN) return "PLAIN";
94  MATH_WARN_MSG("IntegratorMultiDim::GetType","Invalid type specified " );
95  return std::string("Undefined");
96 }
97 
98 void IntegratorOneDim::SetFunction(const IMultiGenFunction &f, unsigned int icoord , const double * x ) {
99  // set function from a multi-dim function
100  // pass also x in case of multi-dim function express the other dimensions (which are fixed)
101  unsigned int ndim = f.NDim();
102  assert (icoord < ndim);
103  ROOT::Math::OneDimMultiFunctionAdapter<> adapter(f,ndim,icoord);
104  // case I pass a vector x which is needed (for example to compute I(y) = Integral( f(x,y) dx) ) need to setCX
105  if (x != 0) adapter.SetX(x, x+ ndim);
106  SetFunction(adapter,true); // need to copy this object
107 }
108 
109 
110 // methods to create integrators
111 
112 VirtualIntegratorOneDim * IntegratorOneDim::CreateIntegrator(IntegrationOneDim::Type type , double absTol, double relTol, unsigned int size, int rule) {
113  // create the concrete class for one-dimensional integration. Use the plug-in manager if needed
114 
116  if (absTol < 0) absTol = IntegratorOneDimOptions::DefaultAbsTolerance();
117  if (relTol < 0) relTol = IntegratorOneDimOptions::DefaultRelTolerance();
118  if (size <= 0) size = IntegratorOneDimOptions::DefaultWKSize();
119  if (rule <= 0) rule = IntegratorOneDimOptions::DefaultNPoints();
120  //if (ncall <= 0) ncall = IntegratorOneDimOptions::DefaultNCalls();
121 
122 
123 
124 
125 #ifndef R__HAS_MATHMORE
126  // default type is GAUSS when Mathmore is not built
127  if (type == IntegrationOneDim::kADAPTIVE ||
131 #endif
132 
133  if (type == IntegrationOneDim::kGAUSS)
134  return new GaussIntegrator(relTol);
135  if (type == IntegrationOneDim::kLEGENDRE) {
136  return new GaussLegendreIntegrator(rule,relTol);
137  }
138 
139  VirtualIntegratorOneDim * ig = 0;
140 
141 #ifdef MATH_NO_PLUGIN_MANAGER // no PM available
142 #ifdef R__HAS_MATHMORE
143  ig = new GSLIntegrator(type, absTol, relTol, size);
144 #else
145  MATH_ERROR_MSG("IntegratorOneDim::CreateIntegrator","Integrator type is not available in MathCore");
146 #endif
147 
148 #else // case of using Plugin Manager
149 
150 
151  {
153  TPluginHandler *h;
154  //gDebug = 3;
155  if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::VirtualIntegrator", "GSLIntegrator"))) {
156  if (h->LoadPlugin() == -1) {
157  MATH_WARN_MSG("IntegratorOneDim::CreateIntegrator","Error loading one dimensional GSL integrator - use Gauss integrator");
158  return new GaussIntegrator();
159  }
160 
161  // plugin manager requires a string
162  std::string typeName = GetName(type);
163 
164  ig = reinterpret_cast<ROOT::Math::VirtualIntegratorOneDim *>( h->ExecPlugin(5,typeName.c_str(), rule, absTol, relTol, size ) );
165  assert(ig != 0);
166  }
167 #ifdef DEBUG
168  std::cout << "Loaded Integrator " << typeid(*ig).name() << std::endl;
169 #endif
170  }
171 #endif
172 
173  return ig;
174 }
175 
177  // create concrete class for multidimensional integration
178 
179 #ifndef R__HAS_MATHMORE
180  // when Mathmore is not built only possible type is ADAPTIVE. There is no other choice
182 #endif
183 
185  if (absTol < 0) absTol = IntegratorMultiDimOptions::DefaultAbsTolerance();
186  if (relTol < 0) relTol = IntegratorMultiDimOptions::DefaultRelTolerance();
187  if (ncall <= 0) ncall = IntegratorMultiDimOptions::DefaultNCalls();
188  unsigned int size = IntegratorMultiDimOptions::DefaultWKSize();
189 
190 
191  // no need for PM in the adaptive case using Genz method (class is in MathCore)
192  if (type == IntegrationMultiDim::kADAPTIVE)
193  return new AdaptiveIntegratorMultiDim(absTol, relTol, ncall, size);
194 
195  // use now plugin-manager for creating the GSL integrator
196 
197  VirtualIntegratorMultiDim * ig = 0;
198 
199 #ifdef MATH_NO_PLUGIN_MANAGER // no PM available
200 #ifdef R__HAS_MATHMORE
201  ig = new GSLMCIntegrator(type, absTol, relTol, ncall);
202 #else
203  MATH_ERROR_MSG("IntegratorMultiDim::CreateIntegrator","Integrator type is not available in MathCore");
204 #endif
205 
206 #else // use ROOT Plugin-Manager to instantiate GSLMCIntegrator
207 
208  {
210  const char * pluginName = "GSLMCIntegrator";
211  TPluginHandler *h = nullptr;
212  //gDebug = 3;
213  if ((h = gROOT->GetPluginManager()->FindHandler("ROOT::Math::VirtualIntegrator", pluginName))) {
214  if (h->LoadPlugin() == -1) {
215  MATH_WARN_MSG("IntegratorMultiDim::CreateIntegrator","Error loading GSL MC multidim integrator - use adaptive method");
216  return new AdaptiveIntegratorMultiDim(absTol, relTol, ncall);
217  }
218 
219  std::string typeName = GetName(type);
220 
221  ig = reinterpret_cast<ROOT::Math::VirtualIntegratorMultiDim *>( h->ExecPlugin(4,typeName.c_str(), absTol, relTol, ncall ) );
222  assert(ig != 0);
223 
224 #ifdef DEBUG
225  std::cout << "Loaded Integrator " << typeid(*ig).name() << std::endl;
226 #endif
227  }
228  }
229 #endif
230  return ig;
231 }
232 
233 
234 
235 
236 } // namespace Math
237 } // namespace ROOT
static IntegrationMultiDim::Type GetType(const char *name)
static function to get the enumeration from a string
Definition: Integrator.cxx:76
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:352
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.
Double_t x[n]
Definition: legend1.C:17
OneDimMultiFunctionAdapter class to wrap a multidimensional function in one dimensional one...
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...
Long_t ExecPlugin(int nargs, const T &... params)
static IntegrationOneDim::Type GetType(const char *name)
static function to get the enumeration from a string
Definition: Integrator.cxx:51
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:88
User class for performing function integration.
int ncall
Definition: stressTF1.cxx:20
Type
enumeration specifying the integration types.
#define R__LOCKGUARD2(mutex)
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:64
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:176
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:112
class for adaptive quadrature integration in multi-dimensions using rectangular regions.