Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooBinIntegrator.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 RooBinIntegrator.cxx
21\class RooBinIntegrator
22\ingroup Roofitcore
23
24Computes the integral over a binned distribution by summing the bin contents of all bins.
25**/
26
27#include "RooBinIntegrator.h"
28
29#include "RooArgSet.h"
30#include "RooRealVar.h"
31#include "RooNumber.h"
32#include "RooNumIntConfig.h"
33#include "RooNumIntFactory.h"
34#include "RooMsgService.h"
35#include "RooRealBinding.h"
36
37#include <cassert>
38#include <memory>
39
40
41using std::endl, std::list;
42
43// Register this class with RooNumIntConfig
44
45////////////////////////////////////////////////////////////////////////////////
46/// Register RooBinIntegrator, is parameters and capabilities with RooNumIntFactory
47
48void RooBinIntegrator::registerIntegrator(RooNumIntFactory& fact)
49{
50 RooRealVar numBins("numBins","Number of bins in range",100) ;
51
52 std::string name = "RooBinIntegrator";
53
54 auto creator = [](const RooAbsFunc &function, const RooNumIntConfig &config) {
55 return std::make_unique<RooBinIntegrator>(function, config);
56 };
57
58 fact.registerPlugin(name, creator, {numBins},
59 /*canIntegrate1D=*/true,
60 /*canIntegrate2D=*/true,
61 /*canIntegrateND=*/true,
62 /*canIntegrateOpenEnded=*/false);
63
64 RooNumIntConfig::defaultConfig().method1D().setLabel(name);
65}
66
67
68////////////////////////////////////////////////////////////////////////////////
69/// Construct integrator on given function binding binding
70
71RooBinIntegrator::RooBinIntegrator(const RooAbsFunc &function, int numBins)
72 : RooAbsIntegrator(function), _useIntegrandLimits(true)
73{
74 assert(_function && _function->isValid());
75
76 // Allocate coordinate buffer size after number of function dimensions
77 _x.resize(_function->getDimension());
78 _numBins = numBins;
79
80 _xmin.resize(_function->getDimension()) ;
81 _xmax.resize(_function->getDimension()) ;
82
83 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
84 _xmin[i]= _function->getMinLimit(i);
85 _xmax[i]= _function->getMaxLimit(i);
86
87 // Retrieve bin configuration from integrand
88 std::unique_ptr<list<double>> tmp{ _function->binBoundaries(i) };
89 if (!tmp) {
90 oocoutW(nullptr,Integration) << "RooBinIntegrator::RooBinIntegrator WARNING: integrand provide no binning definition observable #"
91 << i << " substituting default binning of " << _numBins << " bins" << std::endl ;
92 tmp = std::make_unique<list<double>>( );
93 for (Int_t j=0 ; j<=_numBins ; j++) {
94 j*(_xmax[i]-_xmin[i])/_numBins) ;
95 }
96 }
97 tmp->end());
98
99 }
100 checkLimits();
101
102}
103
104
105////////////////////////////////////////////////////////////////////////////////
106/// Construct integrator on given function binding binding
107
108RooBinIntegrator::RooBinIntegrator(const RooAbsFunc& function, const RooNumIntConfig& config) :
109 RooBinIntegrator(function, static_cast<int>(config.getConfigSection("RooBinIntegrator").getRealValue("numBins")))
110{
111}
112
113
114////////////////////////////////////////////////////////////////////////////////
115/// Change our integration limits. Return true if the new limits are
116/// ok, or otherwise false. Always returns false and does nothing
117/// if this object was constructed to always use our integrand's limits.
118
119bool RooBinIntegrator::setLimits(double *xmin, double *xmax)
120{
121 if(_useIntegrandLimits) {
122 oocoutE(nullptr,Integration) << "RooBinIntegrator::setLimits: cannot override integrand's limits" << std::endl;
123 return false;
124 }
125 _xmin[0]= *xmin;
126 _xmax[0]= *xmax;
127 return checkLimits();
128}
129
130
131////////////////////////////////////////////////////////////////////////////////
132/// Check that our integration range is finite and otherwise return false.
133/// Update the limits from the integrand if requested.
134
135bool RooBinIntegrator::checkLimits() const
136{
137 if(_useIntegrandLimits) {
138 assert(nullptr != integrand() && integrand()->isValid());
139 _xmin.resize(_function->getDimension()) ;
140 _xmax.resize(_function->getDimension()) ;
141 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
142 _xmin[i]= integrand()->getMinLimit(i);
143 _xmax[i]= integrand()->getMaxLimit(i);
144 }
145 }
146 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
147 if (_xmax[i]<=_xmin[i]) {
148 oocoutE(nullptr,Integration) << "RooBinIntegrator::checkLimits: bad range with min >= max (_xmin = " << _xmin[i] << " _xmax = " << _xmax[i] << ")" << std::endl;
149 return false;
150 }
151 if (RooNumber::isInfinite(_xmin[i]) || RooNumber::isInfinite(_xmax[i])) {
152 return false ;
153 }
154 }
155
156 return true;
157}
158
159
160////////////////////////////////////////////////////////////////////////////////
161/// Calculate numeric integral at given set of function binding parameters,
162/// for any number of dimensions.
163double RooBinIntegrator::integral(const double *)
164{
165 assert(isValid());
166 if (_function->getDimension() < 1) return 0.;
167
169
171
172 return sum.Sum();
173}
174
175/**
176 * @brief It performs recursively for loops to calculate N-dimensional integration
177 * @param d the current recursivity depth (dimension currently being for-looped)
178 * @param delta the (d-1)-dimensional bin width/area/volume/hypervolume...
179 * @param sum the resulting integral where to accumulate the integral, passed by reference
180 */
181void RooBinIntegrator::recursive_integration(const UInt_t d, const double delta, ROOT::Math::KahanSum<double>& sum) {
182 const std::vector<double>& binb = _binb[d];
183 const bool isLastDim = d+1 == _function->getDimension();
184 for (unsigned int ibin=0; ibin < binb.size() - 1; ++ibin) {
185 const double hi = binb[ibin + 1];
186 const double lo = binb[ibin];
187 const double mid = (hi+lo)/2.;
188 _x[d] = mid;
189 if (isLastDim) {
190 const double binInt = integrand(_x.data())*(hi-lo)*delta;
191 sum += binInt ;
192 }
193 else {
194 recursive_integration(d+1, (hi-lo)*delta, sum);
195 }
196 }
197}
198
199/// \endcond
#define d(i)
Definition RSha256.hxx:102
#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.
char name[80]
Definition TGX11.cxx:110
float xmin
#define hi
float xmax
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:136
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.
static RooNumIntConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
Factory to instantiate numeric integrators from a given function binding and a given configuration.
static constexpr int isInfinite(double x)
Return true if x is infinite by RooNumber internal specification.
Definition RooNumber.h:27
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
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345