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