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