Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooAdaptiveIntegratorND.cxx
Go to the documentation of this file.
1/*****************************************************************************
2 * Project: RooFit *
3 * Package: RooFitCore *
4 * @(#)root/roofitcore:$Id$
5 * Authors: *
6 * WV, Wouter Verkerke, UC Santa Barbara, verkerke@slac.stanford.edu *
7 * DK, David Kirkby, UC Irvine, dkirkby@uci.edu *
8 * *
9 * Copyright (c) 2000-2005, Regents of the University of California *
10 * and Stanford University. All rights reserved. *
11 * *
12 * Redistribution and use in source and binary forms, *
13 * with or without modification, are permitted according to the terms *
14 * listed in LICENSE (http://roofit.sourceforge.net/license.txt) *
15 *****************************************************************************/
16
17/**
18\file RooAdaptiveIntegratorND.cxx
19\class RooAdaptiveIntegratorND
20\ingroup Roofitcore
21
22Adaptive one-dimensional numerical integration algorithm.
23**/
24
25
26#include "Riostream.h"
27
28#include "TClass.h"
30#include "RooFunctor.h"
31#include "RooArgSet.h"
32#include "RooRealVar.h"
33#include "RooNumber.h"
34#include "RooMsgService.h"
35#include "RooNumIntFactory.h"
37#include "Math/Functor.h"
38
39#include <cassert>
40
41
42
43using namespace std;
44
45
46// Register this class with RooNumIntConfig
47
48////////////////////////////////////////////////////////////////////////////////
49/// Register RooAdaptiveIntegratorND, its parameters, dependencies and capabilities with RooNumIntFactory
50
52{
53 RooRealVar maxEval2D("maxEval2D","Max number of function evaluations for 2-dim integrals",100000) ;
54 RooRealVar maxEval3D("maxEval3D","Max number of function evaluations for 3-dim integrals",1000000) ;
55 RooRealVar maxEvalND("maxEvalND","Max number of function evaluations for >3-dim integrals",10000000) ;
56 RooRealVar maxWarn("maxWarn","Max number of warnings on precision not reached that is printed",5) ;
57
58 auto creator = [](const RooAbsFunc &function, const RooNumIntConfig &config) {
59 return std::make_unique<RooAdaptiveIntegratorND>(function, config);
60 };
61
62 fact.registerPlugin("RooAdaptiveIntegratorND", creator, {maxEval2D,maxEval3D,maxEvalND,maxWarn},
63 /*canIntegrate1D=*/false,
64 /*canIntegrate2D=*/true,
65 /*canIntegrateND=*/true,
66 /*canIntegrateOpenEnded=*/false);
67}
68
69
70
71////////////////////////////////////////////////////////////////////////////////
72/// Constructor of integral on given function binding and with given configuration. The
73/// integration limits are taken from the definition in the function binding
74///_func = function.
75
78 _nWarn(static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxWarn")))
79{
80
81 _rooFunctor = std::make_unique<RooFunctor>(function);
82 _func = std::make_unique<ROOT::Math::Functor>(*_rooFunctor, static_cast<unsigned int>(_rooFunctor->nObs()));
83
84 switch (_func->NDim()) {
85 case 1: throw string(Form("RooAdaptiveIntegratorND::ctor ERROR dimension of function must be at least 2")) ;
86 case 2: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval2D")) ; break ;
87 case 3: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval3D")) ; break ;
88 default: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEvalND")) ; break ;
89 }
90 // by default do not use absolute tolerance (see https://root.cern/phpBB3/viewtopic.php?f=15&t=20071 )
91 _epsAbs = 0.0;
92 _epsRel = config.epsRel();
96
97 _nError = 0 ;
98 _nWarn = 0 ;
99 checkLimits() ;
100 _intName = function.getName() ;
101}
102
103
104////////////////////////////////////////////////////////////////////////////////
105/// Destructor
106
108{
109 delete _integrator ;
110 if (_nError>_nWarn) {
111 oocoutW(nullptr, NumIntegration) << "RooAdaptiveIntegratorND::dtor(" << _intName
112 << ") WARNING: Number of suppressed warningings about integral evaluations where target precision was not reached is " << _nError-_nWarn << std::endl;
113 }
114
115}
116
117
118
119////////////////////////////////////////////////////////////////////////////////
120/// Check that our integration range is finite and otherwise return false.
121/// Update the limits from the integrand if requested.
122
124{
125 if (_xmin.empty()) {
126 _xmin.resize(_func->NDim());
127 _xmax.resize(_func->NDim());
128 }
129
131 for (UInt_t i=0 ; i<_func->NDim() ; i++) {
132 _xmin[i]= integrand()->getMinLimit(i);
133 _xmax[i]= integrand()->getMaxLimit(i);
134 }
135 }
136
137 return true ;
138}
139
140
141////////////////////////////////////////////////////////////////////////////////
142/// Change our integration limits. Return true if the new limits are
143/// ok, or otherwise false. Always returns false and does nothing
144/// if this object was constructed to always use our integrand's limits.
145
147{
149 oocoutE(nullptr,Integration) << "RooAdaptiveIntegratorND::setLimits: cannot override integrand's limits" << endl;
150 return false;
151 }
152 for (UInt_t i=0 ; i<_func->NDim() ; i++) {
153 _xmin[i]= xmin[i];
154 _xmax[i]= xmax[i];
155 }
156
157 return checkLimits();
158}
159
160
161
162
163////////////////////////////////////////////////////////////////////////////////
164/// Evaluate integral at given function binding parameter values
165
166double RooAdaptiveIntegratorND::integral(const double* /*yvec*/)
167{
168 double ret = _integrator->Integral(_xmin.data(),_xmax.data());
169 if (_integrator->Status()==1) {
170 _nError++ ;
171 if (_nError<=_nWarn) {
172 oocoutW(nullptr, NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName() << ") WARNING: target rel. precision not reached due to nEval limit of "
173 << _nmax << ", estimated rel. precision is " << Form("%3.1e",_integrator->RelError()) << endl ;
174 }
175 if (_nError==_nWarn) {
176 oocoutW(nullptr, NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName()
177 << ") Further warnings on target precision are suppressed conform specification in integrator specification" << endl ;
178 }
179 }
180 return ret ;
181}
182
RooAbsReal & function()
#define oocoutW(o, a)
#define oocoutE(o, a)
float xmin
float xmax
char * Form(const char *fmt,...)
Formats a string in a circular formatting buffer.
Definition TString.cxx:2489
Class for adaptive quadrature integration in multi-dimensions using rectangular regions.
int Status() const override
return status of integration
double Integral(const double *xmin, const double *xmax) override
evaluate the integral with the previously given function between xmin[] and xmax[]
void SetFunction(const IMultiGenFunction &f) override
set the integration function (must implement multi-dim function interface: IBaseFunctionMultiDim)
double RelError() const
return relative error
double getRealValue(const char *name, double defVal=0.0, bool verbose=false) const
Get value of a RooAbsReal stored in set with given name.
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Definition RooAbsFunc.h:27
virtual double getMaxLimit(UInt_t dimension) const =0
virtual double getMinLimit(UInt_t dimension) const =0
virtual const char * getName() const
Name of function binding.
Definition RooAbsFunc.h:65
Abstract interface for integrators of real-valued functions that implement the RooAbsFunc interface.
const RooAbsFunc * integrand() const
Return integrand function binding.
Int_t _nmax
Max number of divisions.
bool checkLimits() const override
Check that our integration range is finite and otherwise return false.
bool _useIntegrandLimits
If true limits of function binding are used.
double integral(const double *yvec=nullptr) override
Evaluate integral at given function binding parameter values.
std::unique_ptr< RooFunctor > _rooFunctor
! RooFunctor binding
bool setLimits(double *xmin, double *xmax) override
Change our integration limits.
RooAdaptiveIntegratorND(const RooAbsFunc &function, const RooNumIntConfig &config)
Constructor of integral on given function binding and with given configuration.
std::vector< double > _xmin
Lower bound in each dimension.
double _epsRel
Relative precision.
double _epsAbs
Absolute precision.
TString _intName
Integrand name.
~RooAdaptiveIntegratorND() override
Destructor.
static void registerIntegrator(RooNumIntFactory &fact)
Register RooAdaptiveIntegratorND, its parameters, dependencies and capabilities with RooNumIntFactory...
Int_t _nError
Number of error occurrences.
std::unique_ptr< ROOT::Math::IMultiGenFunction > _func
! ROOT::Math multi-parameter function binding
ROOT::Math::AdaptiveIntegratorMultiDim * _integrator
std::vector< double > _xmax
Upper bound in each dimension.
Int_t _nWarn
Max number of warnings to be issued ;.
Holds the configuration parameters of the various numeric integrators used by RooRealIntegral.
const RooArgSet & getConfigSection(const char *name) const
Retrieve configuration information specific to integrator with given name.
double epsRel() const
Factory to instantiate numeric integrators from a given function binding and a given configuration.
bool registerPlugin(std::string const &name, Creator const &creator, const RooArgSet &defConfig, bool canIntegrate1D, bool canIntegrate2D, bool canIntegrateND, bool canIntegrateOpenEnded, const char *depName="")
Method accepting registration of a prototype numeric integrator along with a RooArgSet of its default...
Variable that can be changed from the outside.
Definition RooRealVar.h:37