Logo ROOT  
Reference Guide
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(kFALSE), _x(0)
69{
70}
71
72
73////////////////////////////////////////////////////////////////////////////////
74/// Construct integrator on given function binding binding
75
78{
80 assert(_function && _function->isValid());
81
82 // Allocate coordinate buffer size after number of function dimensions
84 _numBins = 100 ;
85
86 _xmin.resize(_function->getDimension()) ;
87 _xmax.resize(_function->getDimension()) ;
88
89 auto realBinding = dynamic_cast<const RooRealBinding*>(_function);
90 if (realBinding) {
93 }
94
95 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
98
99 // Retrieve bin configuration from integrand
100 std::unique_ptr<list<Double_t>> tmp{ _function->binBoundaries(i) };
101 if (!tmp) {
102 oocoutW((TObject*)0,Integration) << "RooBinIntegrator::RooBinIntegrator WARNING: integrand provide no binning definition observable #"
103 << i << " substituting default binning of " << _numBins << " bins" << endl ;
104 tmp.reset( new list<Double_t> );
105 for (Int_t j=0 ; j<=_numBins ; j++) {
106 tmp->push_back(_xmin[i]+j*(_xmax[i]-_xmin[i])/_numBins) ;
107 }
108 }
109 _binb.emplace_back(tmp->begin(), tmp->end());
110
111 if (realBinding) {
112 const std::vector<double>& binb = _binb.back();
113 RooSpan<double> binCentres = _evalDataOrig->makeBatch(realBinding->observable(i), binb.size() - 1);
114 for (unsigned int ibin = 0; ibin < binb.size() - 1; ++ibin) {
115 binCentres[ibin] = (binb[ibin + 1] + binb[ibin]) / 2.;
116 }
117 }
118 }
119 checkLimits();
120
121}
122
123
124////////////////////////////////////////////////////////////////////////////////
125/// Construct integrator on given function binding binding
126
129{
130 const RooArgSet& configSet = config.getConfigSection(IsA()->GetName()) ;
132 _numBins = (Int_t) configSet.getRealValue("numBins") ;
133 assert(_function && _function->isValid());
134
135 // Allocate coordinate buffer size after number of function dimensions
137
138 auto realBinding = dynamic_cast<const RooRealBinding*>(_function);
139 if (realBinding) {
142 }
143
144 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
145 _xmin.push_back(_function->getMinLimit(i));
146 _xmax.push_back(_function->getMaxLimit(i));
147
148 // Retrieve bin configuration from integrand
149 std::unique_ptr<list<Double_t>> tmp{ _function->binBoundaries(i) };
150 if (!tmp) {
151 oocoutW((TObject*)0,Integration) << "RooBinIntegrator::RooBinIntegrator WARNING: integrand provide no binning definition observable #"
152 << i << " substituting default binning of " << _numBins << " bins" << endl ;
153 tmp.reset( new list<Double_t> );
154 for (Int_t j=0 ; j<=_numBins ; j++) {
155 tmp->push_back(_xmin[i]+j*(_xmax[i]-_xmin[i])/_numBins) ;
156 }
157 }
158 _binb.emplace_back(tmp->begin(), tmp->end());
159
160 if (realBinding) {
161 const std::vector<double>& binb = _binb.back();
162 RooSpan<double> binCentres = _evalDataOrig->makeBatch(realBinding->observable(i), binb.size() - 1);
163 for (unsigned int ibin = 0; ibin < binb.size() - 1; ++ibin) {
164 binCentres[ibin] = (binb[ibin + 1] + binb[ibin]) / 2.;
165 }
166 }
167 }
168
169 checkLimits();
170}
171
172
173////////////////////////////////////////////////////////////////////////////////
174/// Clone integrator with new function binding and configuration. Needed by RooNumIntFactory
175
177{
178 return new RooBinIntegrator(function,config) ;
179}
180
181
182
183
184
185////////////////////////////////////////////////////////////////////////////////
186/// Destructor
187
189{
190 if(_x) delete[] _x;
191}
192
193
194////////////////////////////////////////////////////////////////////////////////
195/// Change our integration limits. Return kTRUE if the new limits are
196/// ok, or otherwise kFALSE. Always returns kFALSE and does nothing
197/// if this object was constructed to always use our integrand's limits.
198
200{
202 oocoutE((TObject*)0,Integration) << "RooBinIntegrator::setLimits: cannot override integrand's limits" << endl;
203 return kFALSE;
204 }
205 _xmin[0]= *xmin;
206 _xmax[0]= *xmax;
207 return checkLimits();
208}
209
210
211////////////////////////////////////////////////////////////////////////////////
212/// Check that our integration range is finite and otherwise return kFALSE.
213/// Update the limits from the integrand if requested.
214
216{
218 assert(0 != integrand() && integrand()->isValid());
219 _xmin.resize(_function->getDimension()) ;
220 _xmax.resize(_function->getDimension()) ;
221 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
222 _xmin[i]= integrand()->getMinLimit(i);
223 _xmax[i]= integrand()->getMaxLimit(i);
224 }
225 }
226 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
227 if (_xmax[i]<=_xmin[i]) {
228 oocoutE((TObject*)0,Integration) << "RooBinIntegrator::checkLimits: bad range with min >= max (_xmin = " << _xmin[i] << " _xmax = " << _xmax[i] << ")" << endl;
229 return kFALSE;
230 }
232 return kFALSE ;
233 }
234 }
235
236 return kTRUE;
237}
238
239
240////////////////////////////////////////////////////////////////////////////////
241/// Calculate numeric integral at given set of function binding parameters.
243{
244 assert(isValid());
245
247
248 if (_function->getDimension() == 1) {
249 const std::vector<double>& binb = _binb[0];
250
251 if (_evalData) {
252 // Real bindings support batch evaluations. Can fast track now.
253 auto realBinding = static_cast<const RooRealBinding*>(integrand());
254
255 // Reset computation results to only contain known bin centres, and keep all memory intact:
256 _evalData->spans = _evalDataOrig->spans;
257 auto results = realBinding->getValuesOfBoundFunction(*_evalData);
258 assert(results.size() == binb.size() - 1);
259
260 for (unsigned int ibin = 0; ibin < binb.size() - 1; ++ibin) {
261 const double width = binb[ibin + 1] - binb[ibin];
262 sum += results[ibin] * width;
263 }
264 } else {
265 // Need to use single-value interface
266 for (unsigned int ibin=0; ibin < binb.size() - 1; ++ibin) {
267 const double xhi = binb[ibin + 1];
268 const double xlo = binb[ibin];
269 const double xcenter = (xhi+xlo)/2.;
270 const double binInt = integrand(xvec(xcenter))*(xhi-xlo) ;
271 sum += binInt ;
272 }
273 }
274 } else if (_function->getDimension() == 2) {
275 const std::vector<double>& binbx = _binb[0];
276 const std::vector<double>& binby = _binb[1];
277
278 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
279 const double x1hi = binbx[ibin1 + 1];
280 const double x1lo = binbx[ibin1];
281 Double_t x1center = (x1hi+x1lo)/2 ;
282
283 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
284 const double x2hi = binby[ibin2 + 1];
285 const double x2lo = binby[ibin2];
286 const double x2center = (x2hi+x2lo)/2.;
287
288 const double binInt = integrand(xvec(x1center,x2center))*(x1hi-x1lo)*(x2hi-x2lo) ;
289 sum += binInt ;
290 }
291 }
292 } else if (_function->getDimension() == 3) {
293 const std::vector<double>& binbx = _binb[0];
294 const std::vector<double>& binby = _binb[1];
295 const std::vector<double>& binbz = _binb[2];
296
297 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
298 const double x1hi = binbx[ibin1 + 1];
299 const double x1lo = binbx[ibin1];
300 Double_t x1center = (x1hi+x1lo)/2 ;
301
302 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
303 const double x2hi = binby[ibin2 + 1];
304 const double x2lo = binby[ibin2];
305 const double x2center = (x2hi+x2lo)/2.;
306
307 for (unsigned int ibin3=0; ibin3 < binbz.size() - 1; ++ibin3) {
308 const double x3hi = binbz[ibin3 + 1];
309 const double x3lo = binbz[ibin3];
310 const double x3center = (x3hi+x3lo)/2.;
311
312 const double binInt = integrand(xvec(x1center,x2center,x3center))*(x1hi-x1lo)*(x2hi-x2lo)*(x3hi-x3lo);
313 sum += binInt ;
314 }
315 }
316 }
317 }
318
319 return sum;
320}
321
322
#define oocoutW(o, a)
Definition: RooMsgService.h:47
#define oocoutE(o, a)
Definition: RooMsgService.h:48
int Int_t
Definition: RtypesCore.h:45
const Bool_t kFALSE
Definition: RtypesCore.h:101
const Bool_t kTRUE
Definition: RtypesCore.h:100
#define ClassImp(name)
Definition: Rtypes.h:375
Option_t Option_t width
float xmin
Definition: THbookFile.cxx:95
float xmax
Definition: THbookFile.cxx:95
const char * proto
Definition: civetweb.c:17493
Double_t getRealValue(const char *name, Double_t defVal=0, Bool_t verbose=kFALSE) 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
Bool_t isValid() const
Definition: RooAbsFunc.h:37
virtual Double_t getMinLimit(UInt_t dimension) const =0
virtual std::list< Double_t > * binBoundaries(Int_t) const
Definition: RooAbsFunc.h:69
virtual Double_t getMaxLimit(UInt_t dimension) const =0
UInt_t getDimension() const
Definition: RooAbsFunc.h:33
RooAbsIntegrator is the abstract interface for integrators of real-valued functions that implement th...
const RooAbsFunc * _function
Pointer to function binding of integrand.
const RooAbsFunc * integrand() const
Return integrand function binding.
Bool_t isValid() const
Is integrator in valid state.
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition: RooArgSet.h:57
RooBinIntegrator computes the integral over a binned distribution by summing the bin contents of all ...
Bool_t setLimits(Double_t *xmin, Double_t *xmax) override
Change our integration limits.
std::vector< Double_t > _xmin
! Lower 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
Double_t * _x
! do not persist
std::vector< Double_t > _xmax
! Upper integration bound
Bool_t _useIntegrandLimits
If true limits of function binding are ued.
Bool_t checkLimits() const override
Check that our integration range is finite and otherwise return kFALSE.
std::vector< std::vector< double > > _binb
! list of bin boundaries
double * xvec(double xx)
std::unique_ptr< RooBatchCompute::RunContext > _evalDataOrig
! Run context to save bin centres in between invocations.
RooBinIntegrator()
Default constructor.
Double_t integral(const Double_t *yvec=0) override
Calculate numeric integral at given set of function binding parameters.
TClass * IsA() const override
std::unique_ptr< RooBatchCompute::RunContext > _evalData
! Run context for evaluating a function.
~RooBinIntegrator() override
Destructor.
Bool_t 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...
const RooArgSet & getConfigSection(const char *name) const
Retrieve configuration information specific to integrator with given name.
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_t 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 Int_t isInfinite(Double_t x)
Return true if x is infinite by RooNumBer internal specification.
Definition: RooNumber.cxx:57
Lightweight interface adaptor that binds a RooAbsReal object to a subset of its servers and present i...
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
Mother of all ROOT objects.
Definition: TObject.h:37
virtual const char * GetName() const
Returns name of object.
Definition: TObject.cxx:359
void function(const Char_t *name_, T fun, const Char_t *docstring=0)
Definition: RExports.h:167
@ Integration
Definition: RooGlobalFunc.h:63
This struct enables passing computation data around between elements of a computation graph.
Definition: RunContext.h:31
static uint64_t sum(uint64_t i)
Definition: Factory.cxx:2345