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(kFALSE), _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
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) {
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_t>> tmp{ _function->binBoundaries(i) };
109 if (!tmp) {
110 oocoutW((TObject*)0,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_t> );
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 if(_x) delete[] _x;
159}
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Change our integration limits. Return kTRUE if the new limits are
164/// ok, or otherwise kFALSE. Always returns kFALSE and does nothing
165/// if this object was constructed to always use our integrand's limits.
166
168{
170 oocoutE((TObject*)0,Integration) << "RooBinIntegrator::setLimits: cannot override integrand's limits" << endl;
171 return kFALSE;
172 }
173 _xmin[0]= *xmin;
174 _xmax[0]= *xmax;
175 return checkLimits();
176}
177
178
179////////////////////////////////////////////////////////////////////////////////
180/// Check that our integration range is finite and otherwise return kFALSE.
181/// Update the limits from the integrand if requested.
182
184{
186 assert(0 != integrand() && integrand()->isValid());
187 _xmin.resize(_function->getDimension()) ;
188 _xmax.resize(_function->getDimension()) ;
189 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
190 _xmin[i]= integrand()->getMinLimit(i);
191 _xmax[i]= integrand()->getMaxLimit(i);
192 }
193 }
194 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
195 if (_xmax[i]<=_xmin[i]) {
196 oocoutE((TObject*)0,Integration) << "RooBinIntegrator::checkLimits: bad range with min >= max (_xmin = " << _xmin[i] << " _xmax = " << _xmax[i] << ")" << endl;
197 return kFALSE;
198 }
200 return kFALSE ;
201 }
202 }
203
204 return kTRUE;
205}
206
207
208////////////////////////////////////////////////////////////////////////////////
209/// Calculate numeric integral at given set of function binding parameters.
211{
212 assert(isValid());
213
215
216 if (_function->getDimension() == 1) {
217 const std::vector<double>& binb = _binb[0];
218
219 if (_evalData) {
220 // Real bindings support batch evaluations. Can fast track now.
221 auto realBinding = static_cast<const RooRealBinding*>(integrand());
222
223 // Reset computation results to only contain known bin centres, and keep all memory intact:
224 _evalData->spans = _evalDataOrig->spans;
225 auto results = realBinding->getValuesOfBoundFunction(*_evalData);
226 assert(results.size() == binb.size() - 1);
227
228 for (unsigned int ibin = 0; ibin < binb.size() - 1; ++ibin) {
229 const double width = binb[ibin + 1] - binb[ibin];
230 sum += results[ibin] * width;
231 }
232 } else {
233 // Need to use single-value interface
234 for (unsigned int ibin=0; ibin < binb.size() - 1; ++ibin) {
235 const double xhi = binb[ibin + 1];
236 const double xlo = binb[ibin];
237 const double xcenter = (xhi+xlo)/2.;
238 const double binInt = integrand(xvec(xcenter))*(xhi-xlo) ;
239 sum += binInt ;
240 }
241 }
242 } else if (_function->getDimension() == 2) {
243 const std::vector<double>& binbx = _binb[0];
244 const std::vector<double>& binby = _binb[1];
245
246 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
247 const double x1hi = binbx[ibin1 + 1];
248 const double x1lo = binbx[ibin1];
249 Double_t x1center = (x1hi+x1lo)/2 ;
250
251 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
252 const double x2hi = binby[ibin2 + 1];
253 const double x2lo = binby[ibin2];
254 const double x2center = (x2hi+x2lo)/2.;
255
256 const double binInt = integrand(xvec(x1center,x2center))*(x1hi-x1lo)*(x2hi-x2lo) ;
257 sum += binInt ;
258 }
259 }
260 } else if (_function->getDimension() == 3) {
261 const std::vector<double>& binbx = _binb[0];
262 const std::vector<double>& binby = _binb[1];
263 const std::vector<double>& binbz = _binb[2];
264
265 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
266 const double x1hi = binbx[ibin1 + 1];
267 const double x1lo = binbx[ibin1];
268 Double_t x1center = (x1hi+x1lo)/2 ;
269
270 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
271 const double x2hi = binby[ibin2 + 1];
272 const double x2lo = binby[ibin2];
273 const double x2center = (x2hi+x2lo)/2.;
274
275 for (unsigned int ibin3=0; ibin3 < binbz.size() - 1; ++ibin3) {
276 const double x3hi = binbz[ibin3 + 1];
277 const double x3lo = binbz[ibin3];
278 const double x3center = (x3hi+x3lo)/2.;
279
280 const double binInt = integrand(xvec(x1center,x2center,x3center))*(x1hi-x1lo)*(x2hi-x2lo)*(x3hi-x3lo);
281 sum += binInt ;
282 }
283 }
284 }
285 }
286
287 return sum;
288}
289
290
#define oocoutW(o, a)
#define oocoutE(o, a)
const Bool_t kFALSE
Definition RtypesCore.h:101
const Bool_t kTRUE
Definition RtypesCore.h:100
#define ClassImp(name)
Definition Rtypes.h:364
include TDocParser_001 C image html pict1_TDocParser_001 png width
float xmin
float xmax
const char * proto
Definition civetweb.c:16613
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_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:68
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
const RooAbsFunc * integrand() const
Bool_t isValid() const
RooArgSet is a container object that can hold multiple RooAbsArg objects.
Definition RooArgSet.h:35
RooBinIntegrator computes the integral over a binned distribution by summing the bin contents of all ...
std::vector< Double_t > _xmin
static void registerIntegrator(RooNumIntFactory &fact)
Register RooBinIntegrator, is parameters and capabilities with RooNumIntFactory.
Int_t _numBins
list of bin boundaries
std::vector< Double_t > _xmax
Lower integration bound.
virtual ~RooBinIntegrator()
Destructor.
Bool_t _useIntegrandLimits
Size of integration range.
virtual RooAbsIntegrator * clone(const RooAbsFunc &function, const RooNumIntConfig &config) const
Clone integrator with new function binding and configuration. Needed by RooNumIntFactory.
std::vector< std::vector< double > > _binb
Upper integration bound.
virtual Bool_t checkLimits() const
Check that our integration range is finite and otherwise return kFALSE.
virtual Double_t integral(const Double_t *yvec=0)
Calculate numeric integral at given set of function binding parameters.
double * xvec(double xx)
Run context to save bin centres in between invocations.
std::unique_ptr< RooBatchCompute::RunContext > _evalDataOrig
Run context for evaluating a function.
Bool_t setLimits(Double_t *xmin, Double_t *xmax)
Change our integration limits.
RooBinIntegrator()
Default constructor.
std::unique_ptr< RooBatchCompute::RunContext > _evalData
virtual 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...
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:58
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:39
A simple container to hold a batch of data values.
Definition RooSpan.h:34
Mother of all ROOT objects.
Definition TObject.h:41
This struct enables passing computation data around between elements of a computation graph.
Definition RunContext.h:32
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345