Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooBinIntegrator.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 RooBinIntegrator.cxx
19\class RooBinIntegrator
20\ingroup Roofitcore
21
22RooBinIntegrator computes the integral over a binned distribution by summing the bin
23contents of all bins.
24**/
25
26#include "RooBinIntegrator.h"
27
28#include "RooArgSet.h"
29#include "RooRealVar.h"
30#include "RooNumber.h"
32#include "RooNumIntConfig.h"
33#include "RooNumIntFactory.h"
34#include "RooMsgService.h"
35#include "RunContext.h"
36#include "RooRealBinding.h"
37
38#include "TClass.h"
39#include "Math/Util.h"
40
41#include <assert.h>
42
43
44
45using namespace std;
46
48;
49
50// Register this class with RooNumIntConfig
51
52////////////////////////////////////////////////////////////////////////////////
53/// Register RooBinIntegrator, is parameters and capabilities with RooNumIntFactory
54
56{
57 RooRealVar numBins("numBins","Number of bins in range",100) ;
59 fact.storeProtoIntegrator(proto,RooArgSet(numBins)) ;
61}
62
63
64
65////////////////////////////////////////////////////////////////////////////////
66/// Default constructor
67
68RooBinIntegrator::RooBinIntegrator() : _numBins(0), _useIntegrandLimits(false), _x(0)
69{
70}
71
72
73////////////////////////////////////////////////////////////////////////////////
74/// Construct integrator on given function binding binding
75
76RooBinIntegrator::RooBinIntegrator(const RooAbsFunc& function, int numBins):
77 RooAbsIntegrator(function)
78{
80 assert(_function && _function->isValid());
81
82 // Allocate coordinate buffer size after number of function dimensions
83 _x.resize(_function->getDimension());
84 _numBins = numBins;
85
86 _xmin.resize(_function->getDimension()) ;
87 _xmax.resize(_function->getDimension()) ;
88
89 auto realBinding = dynamic_cast<const RooRealBinding*>(_function);
90
91 // We could use BatchMode for RooRealBindings as they implement getValues().
92 // However, this is not efficient right now, because every time getValue() is
93 // called, a new RooFitDriver is created. Needs to be refactored.
94
95 //const bool useBatchMode = realBinding;
96 const bool useBatchMode = false;
97
98 if (useBatchMode) {
99 _evalData = std::make_unique<RooBatchCompute::RunContext>();
100 _evalDataOrig = std::make_unique<RooBatchCompute::RunContext>();
101 }
102
103 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
106
107 // Retrieve bin configuration from integrand
108 std::unique_ptr<list<double>> tmp{ _function->binBoundaries(i) };
109 if (!tmp) {
110 oocoutW(nullptr,Integration) << "RooBinIntegrator::RooBinIntegrator WARNING: integrand provide no binning definition observable #"
111 << i << " substituting default binning of " << _numBins << " bins" << endl ;
112 tmp.reset( new list<double> );
113 for (Int_t j=0 ; j<=_numBins ; j++) {
114 tmp->push_back(_xmin[i]+j*(_xmax[i]-_xmin[i])/_numBins) ;
115 }
116 }
117 _binb.emplace_back(tmp->begin(), tmp->end());
118
119 if (useBatchMode) {
120 const std::vector<double>& binb = _binb.back();
121 RooSpan<double> binCentres = _evalDataOrig->makeBatch(realBinding->observable(i), binb.size() - 1);
122 for (unsigned int ibin = 0; ibin < binb.size() - 1; ++ibin) {
123 binCentres[ibin] = (binb[ibin + 1] + binb[ibin]) / 2.;
124 }
125 }
126 }
127 checkLimits();
128
129}
130
131
132////////////////////////////////////////////////////////////////////////////////
133/// Construct integrator on given function binding binding
134
136 RooBinIntegrator(function, static_cast<int>(config.getConfigSection("RooBinIntegrator").getRealValue("numBins")))
137{
138}
139
140
141////////////////////////////////////////////////////////////////////////////////
142/// Clone integrator with new function binding and configuration. Needed by RooNumIntFactory
143
145{
146 return new RooBinIntegrator(function,config) ;
147}
148
149
150
151
152
153////////////////////////////////////////////////////////////////////////////////
154/// Destructor
155
157{
158}
159
160
161////////////////////////////////////////////////////////////////////////////////
162/// Change our integration limits. Return true if the new limits are
163/// ok, or otherwise false. Always returns false and does nothing
164/// if this object was constructed to always use our integrand's limits.
165
167{
169 oocoutE(nullptr,Integration) << "RooBinIntegrator::setLimits: cannot override integrand's limits" << endl;
170 return false;
171 }
172 _xmin[0]= *xmin;
173 _xmax[0]= *xmax;
174 return checkLimits();
175}
176
177
178////////////////////////////////////////////////////////////////////////////////
179/// Check that our integration range is finite and otherwise return false.
180/// Update the limits from the integrand if requested.
181
183{
185 assert(0 != integrand() && integrand()->isValid());
186 _xmin.resize(_function->getDimension()) ;
187 _xmax.resize(_function->getDimension()) ;
188 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
189 _xmin[i]= integrand()->getMinLimit(i);
190 _xmax[i]= integrand()->getMaxLimit(i);
191 }
192 }
193 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
194 if (_xmax[i]<=_xmin[i]) {
195 oocoutE(nullptr,Integration) << "RooBinIntegrator::checkLimits: bad range with min >= max (_xmin = " << _xmin[i] << " _xmax = " << _xmax[i] << ")" << endl;
196 return false;
197 }
199 return false ;
200 }
201 }
202
203 return true;
204}
205
206
207////////////////////////////////////////////////////////////////////////////////
208/// Calculate numeric integral at given set of function binding parameters.
209double RooBinIntegrator::integral(const double *)
210{
211 assert(isValid());
212
214
215 if (_function->getDimension() == 1) {
216 const std::vector<double>& binb = _binb[0];
217
218 if (_evalData) {
219 // Real bindings support batch evaluations. Can fast track now.
220 auto realBinding = static_cast<const RooRealBinding*>(integrand());
221
222 // Reset computation results to only contain known bin centres, and keep all memory intact:
223 _evalData->spans = _evalDataOrig->spans;
224 auto results = realBinding->getValuesOfBoundFunction(*_evalData);
225 assert(results.size() == binb.size() - 1);
226
227 for (unsigned int ibin = 0; ibin < binb.size() - 1; ++ibin) {
228 const double width = binb[ibin + 1] - binb[ibin];
229 sum += results[ibin] * width;
230 }
231 } else {
232 // Need to use single-value interface
233 for (unsigned int ibin=0; ibin < binb.size() - 1; ++ibin) {
234 const double xhi = binb[ibin + 1];
235 const double xlo = binb[ibin];
236 const double xcenter = (xhi+xlo)/2.;
237 const double binInt = integrand(xvec(xcenter))*(xhi-xlo) ;
238 sum += binInt ;
239 }
240 }
241 } else if (_function->getDimension() == 2) {
242 const std::vector<double>& binbx = _binb[0];
243 const std::vector<double>& binby = _binb[1];
244
245 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
246 const double x1hi = binbx[ibin1 + 1];
247 const double x1lo = binbx[ibin1];
248 double x1center = (x1hi+x1lo)/2 ;
249
250 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
251 const double x2hi = binby[ibin2 + 1];
252 const double x2lo = binby[ibin2];
253 const double x2center = (x2hi+x2lo)/2.;
254
255 const double binInt = integrand(xvec(x1center,x2center))*(x1hi-x1lo)*(x2hi-x2lo) ;
256 sum += binInt ;
257 }
258 }
259 } else if (_function->getDimension() == 3) {
260 const std::vector<double>& binbx = _binb[0];
261 const std::vector<double>& binby = _binb[1];
262 const std::vector<double>& binbz = _binb[2];
263
264 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
265 const double x1hi = binbx[ibin1 + 1];
266 const double x1lo = binbx[ibin1];
267 double x1center = (x1hi+x1lo)/2 ;
268
269 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
270 const double x2hi = binby[ibin2 + 1];
271 const double x2lo = binby[ibin2];
272 const double x2center = (x2hi+x2lo)/2.;
273
274 for (unsigned int ibin3=0; ibin3 < binbz.size() - 1; ++ibin3) {
275 const double x3hi = binbz[ibin3 + 1];
276 const double x3lo = binbz[ibin3];
277 const double x3center = (x3hi+x3lo)/2.;
278
279 const double binInt = integrand(xvec(x1center,x2center,x3center))*(x1hi-x1lo)*(x2hi-x2lo)*(x3hi-x3lo);
280 sum += binInt ;
281 }
282 }
283 }
284 }
285
286 return sum.Sum();
287}
288
289
#define oocoutW(o, a)
#define oocoutE(o, a)
#define ClassImp(name)
Definition Rtypes.h:377
Option_t Option_t width
float xmin
float xmax
const char * proto
Definition civetweb.c:17502
The Kahan summation is a compensated summation algorithm, which significantly reduces numerical error...
Definition Util.h:122
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Definition RooAbsFunc.h:27
bool isValid() const
Definition RooAbsFunc.h:37
virtual double getMaxLimit(UInt_t dimension) const =0
virtual double getMinLimit(UInt_t dimension) const =0
UInt_t getDimension() const
Definition RooAbsFunc.h:33
virtual std::list< double > * binBoundaries(Int_t) const
Definition RooAbsFunc.h:69
RooAbsIntegrator is the abstract interface for integrators of real-valued functions that implement th...
bool isValid() const
Is integrator in valid state.
const RooAbsFunc * _function
Pointer to function binding of integrand.
const RooAbsFunc * integrand() const
Return integrand function binding.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:55
RooBinIntegrator computes the integral over a binned distribution by summing the bin contents of all ...
std::vector< double > _xmax
! Upper integration bound
RooAbsIntegrator * clone(const RooAbsFunc &function, const RooNumIntConfig &config) const override
Clone integrator with new function binding and configuration. Needed by RooNumIntFactory.
static void registerIntegrator(RooNumIntFactory &fact)
Register RooBinIntegrator, is parameters and capabilities with RooNumIntFactory.
Int_t _numBins
! Size of integration range
bool setLimits(double *xmin, double *xmax) override
Change our integration limits.
std::vector< std::vector< double > > _binb
! list of bin boundaries
std::vector< double > _xmin
! Lower integration bound
double * xvec(double xx)
std::unique_ptr< RooBatchCompute::RunContext > _evalDataOrig
! Run context to save bin centres in between invocations.
std::vector< double > _x
! do not persist
bool _useIntegrandLimits
If true limits of function binding are ued.
RooBinIntegrator()
Default constructor.
bool checkLimits() const override
Check that our integration range is finite and otherwise return false.
std::unique_ptr< RooBatchCompute::RunContext > _evalData
! Run context for evaluating a function.
double integral(const double *yvec=nullptr) override
Calculate numeric integral at given set of function binding parameters.
~RooBinIntegrator() override
Destructor.
bool setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
RooNumIntConfig holds the configuration parameters of the various numeric integrators used by RooReal...
RooCategory & method1D()
static RooNumIntConfig & defaultConfig()
Return reference to instance of default numeric integrator configuration object.
RooNumIntFactory is a factory to instantiate numeric integrators from a given function binding and a ...
bool storeProtoIntegrator(RooAbsIntegrator *proto, const RooArgSet &defConfig, const char *depName="")
Method accepting registration of a prototype numeric integrator along with a RooArgSet of its default...
static constexpr int isInfinite(double x)
Return true if x is infinite by RooNumber internal specification.
Definition RooNumber.h:34
Lightweight interface adaptor that binds a RooAbsReal object to a subset of its servers and present i...
RooSpan< const double > getValuesOfBoundFunction(RooBatchCompute::RunContext &evalData) const
Evaluate the bound object at all locations indicated by the data in evalData.
RooRealVar represents a variable that can be changed from the outside.
Definition RooRealVar.h:40
A simple container to hold a batch of data values.
Definition RooSpan.h:34
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345