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