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
27
28#include "Riostream.h"
29
30#include "TClass.h"
32#include "RooFunctor.h"
33#include "RooArgSet.h"
34#include "RooRealVar.h"
35#include "RooNumber.h"
36#include "RooMsgService.h"
37#include "RooNumIntFactory.h"
39#include "Math/Functor.h"
40
41#include <cassert>
42
43using std::endl, std::string;
44
45// Register this class with RooNumIntConfig
46
47////////////////////////////////////////////////////////////////////////////////
48/// Register RooAdaptiveIntegratorND, its parameters, dependencies and capabilities with RooNumIntFactory
49
50void RooAdaptiveIntegratorND::registerIntegrator(RooNumIntFactory& fact)
51{
52 RooRealVar maxEval2D("maxEval2D","Max number of function evaluations for 2-dim integrals",100000) ;
53 RooRealVar maxEval3D("maxEval3D","Max number of function evaluations for 3-dim integrals",1000000) ;
54 RooRealVar maxEvalND("maxEvalND","Max number of function evaluations for >3-dim integrals",10000000) ;
55 RooRealVar maxWarn("maxWarn","Max number of warnings on precision not reached that is printed",5) ;
56
57 auto creator = [](const RooAbsFunc &function, const RooNumIntConfig &config) {
58 return std::make_unique<RooAdaptiveIntegratorND>(function, config);
59 };
60
61 fact.registerPlugin("RooAdaptiveIntegratorND", creator, {maxEval2D,maxEval3D,maxEvalND,maxWarn},
62 /*canIntegrate1D=*/false,
63 /*canIntegrate2D=*/true,
64 /*canIntegrateND=*/true,
65 /*canIntegrateOpenEnded=*/false);
66}
67
68
69
70////////////////////////////////////////////////////////////////////////////////
71/// Constructor of integral on given function binding and with given configuration. The
72/// integration limits are taken from the definition in the function binding
73///_func = function.
74
75RooAdaptiveIntegratorND::RooAdaptiveIntegratorND(const RooAbsFunc &function, const RooNumIntConfig &config)
77 _nWarn(static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxWarn")))
78{
79
80 _rooFunctor = std::make_unique<RooFunctor>(function);
81 _func = std::make_unique<ROOT::Math::Functor>(*_rooFunctor, static_cast<unsigned int>(_rooFunctor->nObs()));
82
83 switch (_func->NDim()) {
84 case 1: throw string(Form("RooAdaptiveIntegratorND::ctor ERROR dimension of function must be at least 2")) ;
85 case 2: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval2D")) ; break ;
86 case 3: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEval3D")) ; break ;
87 default: _nmax = static_cast<Int_t>(config.getConfigSection("RooAdaptiveIntegratorND").getRealValue("maxEvalND")) ; break ;
88 }
89 // by default do not use absolute tolerance (see https://root.cern/phpBB3/viewtopic.php?f=15&t=20071 )
90 _epsAbs = 0.0;
91 _epsRel = config.epsRel();
92 _integrator = new ROOT::Math::AdaptiveIntegratorMultiDim(_epsAbs,_epsRel,_nmax) ;
93 _integrator->SetFunction(*_func) ;
94 _useIntegrandLimits=true ;
95
96 _nError = 0 ;
97 _nWarn = 0 ;
98 checkLimits() ;
99 _intName = function.getName() ;
100}
101
102
103////////////////////////////////////////////////////////////////////////////////
104/// Destructor
105
106RooAdaptiveIntegratorND::~RooAdaptiveIntegratorND()
107{
108 delete _integrator ;
109 if (_nError>_nWarn) {
110 oocoutW(nullptr, NumIntegration) << "RooAdaptiveIntegratorND::dtor(" << _intName
111 << ") WARNING: Number of suppressed warningings about integral evaluations where target precision was not reached is " << _nError-_nWarn << std::endl;
112 }
113
114}
115
116
117
118////////////////////////////////////////////////////////////////////////////////
119/// Check that our integration range is finite and otherwise return false.
120/// Update the limits from the integrand if requested.
121
122bool RooAdaptiveIntegratorND::checkLimits() const
123{
124 if (_xmin.empty()) {
125 _xmin.resize(_func->NDim());
126 _xmax.resize(_func->NDim());
127 }
128
129 if (_useIntegrandLimits) {
130 for (UInt_t i=0 ; i<_func->NDim() ; i++) {
131 _xmin[i]= integrand()->getMinLimit(i);
132 _xmax[i]= integrand()->getMaxLimit(i);
133 }
134 }
135
136 return true ;
137}
138
139
140////////////////////////////////////////////////////////////////////////////////
141/// Change our integration limits. Return true if the new limits are
142/// ok, or otherwise false. Always returns false and does nothing
143/// if this object was constructed to always use our integrand's limits.
144
145bool RooAdaptiveIntegratorND::setLimits(double *xmin, double *xmax)
146{
147 if(_useIntegrandLimits) {
148 oocoutE(nullptr,Integration) << "RooAdaptiveIntegratorND::setLimits: cannot override integrand's limits" << std::endl;
149 return false;
150 }
151 for (UInt_t i=0 ; i<_func->NDim() ; i++) {
152 _xmin[i]= xmin[i];
153 _xmax[i]= xmax[i];
154 }
155
156 return checkLimits();
157}
158
159
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Evaluate integral at given function binding parameter values
164
165double RooAdaptiveIntegratorND::integral(const double* /*yvec*/)
166{
167 double ret = _integrator->Integral(_xmin.data(),_xmax.data());
168 if (_integrator->Status()==1) {
169 _nError++ ;
170 if (_nError<=_nWarn) {
171 oocoutW(nullptr, NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName() << ") WARNING: target rel. precision not reached due to nEval limit of "
172 << _nmax << ", estimated rel. precision is " << Form("%3.1e",_integrator->RelError()) << std::endl ;
173 }
174 if (_nError==_nWarn) {
175 oocoutW(nullptr, NumIntegration) << "RooAdaptiveIntegratorND::integral(" << integrand()->getName()
176 << ") Further warnings on target precision are suppressed conform specification in integrator specification" << std::endl ;
177 }
178 }
179 return ret ;
180}
181
182/// \endcond
#define oocoutW(o, a)
#define oocoutE(o, a)
int Int_t
Definition RtypesCore.h:45
unsigned int UInt_t
Definition RtypesCore.h:46
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:2489
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
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
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition RExports.h:167