// @(#)root/mathcore:$Id$ // Authors: M. Slawinska 08/2007 /********************************************************************** * * * Copyright (c) 2007 , LCG ROOT MathLib Team * * * * * **********************************************************************/ // Header source file for class IntegratorMultiDim #ifndef ROOT_Math_IntegratorMultiDim #define ROOT_Math_IntegratorMultiDim #include "Math/IFunctionfwd.h" #include "Math/AllIntegrationTypes.h" #include "Math/IntegratorOptions.h" #include "Math/VirtualIntegrator.h" #ifndef __CINT__ #include "Math/WrappedFunction.h" #endif #include #include namespace ROOT { namespace Math { //___________________________________________________________________________________________ /** User class for performing multidimensional integration By default uses adaptive multi-dimensional integration using the algorithm from Genz Mallik implemented in the class ROOT::Math::AdaptiveIntegratorMultiDim otherwise it can uses via the plug-in manager the MC integration class (ROOT::Math::GSLMCIntegration) from MathMore. @ingroup Integration */ class IntegratorMultiDim { public: typedef IntegrationMultiDim::Type Type; // for the enumerations defining the types /** Generic constructor of multi dimensional Integrator. By default uses the Adaptive integration method @param type integration type (adaptive, MC methods, etc..) @param absTol desired absolute Error @param relTol desired relative Error @param ncall number of function calls (apply only to MC integration methods) In case no parameter values are passed the default ones used in IntegratorMultiDimOptions are used */ explicit IntegratorMultiDim(IntegrationMultiDim::Type type = IntegrationMultiDim::kDEFAULT, double absTol = -1, double relTol = -1, unsigned int ncall = 0) : fIntegrator(nullptr) { fIntegrator = CreateIntegrator(type, absTol, relTol, ncall); } /** Generic Constructor of multi dimensional Integrator passing a function. By default uses the adaptive integration method @param f integration function (multi-dim interface) @param type integration type (adaptive, MC methods, etc..) @param absTol desired absolute Error @param relTol desired relative Error @param ncall number of function calls (apply only to MC integration methods) */ explicit IntegratorMultiDim(const IMultiGenFunction &f, IntegrationMultiDim::Type type = IntegrationMultiDim::kDEFAULT, double absTol = -1, double relTol = -1, unsigned int ncall = 0) : fIntegrator(nullptr) { fIntegrator = CreateIntegrator(type, absTol, relTol, ncall); SetFunction(f); } // remove template constructor since is ambiguous /** Template Constructor of multi dimensional Integrator passing a generic function. By default uses the adaptive integration method @param f integration function (generic function implementing operator()(const double *) @param dim function dimension @param type integration type (adaptive, MC methods, etc..) @param absTol desired absolute Error @param relTol desired relative Error @param ncall number of function calls (apply only to MC integration methods) */ // this is ambiguous // template // IntegratorMultiDim(Function & f, unsigned int dim, IntegrationMultiDim::Type type = IntegrationMultiDim::kADAPTIVE, double absTol = 1.E-9, double relTol = 1E-6, unsigned int ncall = 100000) { // fIntegrator = CreateIntegrator(type, absTol, relTol, ncall); // SetFunction(f, dim); // } /// destructor virtual ~IntegratorMultiDim() { if (fIntegrator) delete fIntegrator; } // disable copy constructor and assignment operator private: IntegratorMultiDim(const IntegratorMultiDim &) : fIntegrator(nullptr), fFunc(nullptr) {} IntegratorMultiDim & operator=(const IntegratorMultiDim &) { return *this; } public: /** evaluate the integral with the previously given function between xmin[] and xmax[] */ double Integral(const double* xmin, const double * xmax) { return !fIntegrator ? 0 : fIntegrator->Integral(xmin,xmax); } /// evaluate the integral passing a new function double Integral(const IMultiGenFunction &f, const double* xmin, const double * xmax) { SetFunction(f); return Integral(xmin,xmax); } /// evaluate the integral passing a new generic function template double Integral(Function & f , unsigned int dim, const double* xmin, const double * xmax) { SetFunction(f,dim); return Integral(xmin, xmax); } /** set integration function using a generic function implementing the operator()(double *x) The dimension of the function is in this case required */ template void SetFunction(Function & f, unsigned int dim) { fFunc.reset(new WrappedMultiFunction (f, dim) ); fIntegrator->SetFunction(*fFunc); } // set the function without cloning it void SetFunction(const IMultiGenFunction &f) { if (fIntegrator) fIntegrator->SetFunction(f); } /// return result of last integration double Result() const { return !fIntegrator ? 0 : fIntegrator->Result(); } /// return integration error double Error() const { return !fIntegrator ? 0 : fIntegrator->Error(); } /// return the Error Status of the last Integral calculation int Status() const { return !fIntegrator ? -1 : fIntegrator->Status(); } // return number of function evaluations in calculating the integral //unsigned int NEval() const { return fNEval; } /// set the relative tolerance void SetRelTolerance(double relTol) { if (fIntegrator) fIntegrator->SetRelTolerance(relTol); } /// set absolute tolerance void SetAbsTolerance(double absTol) { if (fIntegrator) fIntegrator->SetAbsTolerance(absTol); } /// set the options void SetOptions(const ROOT::Math::IntegratorMultiDimOptions & opt) { if (fIntegrator) fIntegrator->SetOptions(opt); } /// retrieve the options ROOT::Math::IntegratorMultiDimOptions Options() const { return fIntegrator ? fIntegrator->Options() : IntegratorMultiDimOptions(); } /// return a pointer to integrator object VirtualIntegratorMultiDim * GetIntegrator() { return fIntegrator; } /// return name of integrator std::string Name() const { return fIntegrator ? Options().Integrator() : std::string(""); } /// static function to get the enumeration from a string static IntegrationMultiDim::Type GetType(const char * name); /// static function to get a string from the enumeration static std::string GetName(IntegrationMultiDim::Type); protected: VirtualIntegratorMultiDim * CreateIntegrator(IntegrationMultiDim::Type type , double absTol, double relTol, unsigned int ncall); private: VirtualIntegratorMultiDim * fIntegrator; ///< pointer to multi-dimensional integrator base class std::unique_ptr fFunc; ///< pointer to owned function }; }//namespace Math }//namespace ROOT #endif /* ROOT_Math_IntegratorMultiDim */