00001
00002
00003
00004
00005
00006
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
00026
00027
00028
00029 #include <algorithm>
00030 #include <functional>
00031 #include <ctype.h>
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
00103
00104 unsigned int ndim = f.NDim();
00105 assert (icoord < ndim);
00106 ROOT::Math::OneDimMultiFunctionAdapter<> adapter(f,ndim,icoord);
00107
00108 if (x != 0) adapter.SetX(x, x+ ndim);
00109 SetFunction(adapter,true);
00110 }
00111
00112
00113
00114
00115 VirtualIntegratorOneDim * IntegratorOneDim::CreateIntegrator(IntegrationOneDim::Type type , double absTol, double relTol, unsigned int size, int rule) {
00116
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
00124
00125
00126
00127
00128 #ifndef R__HAS_MATHMORE
00129
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
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
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
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
00191 type = IntegrationMultiDim::kADAPTIVE;
00192 #endif
00193
00194
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
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 }
00234 }