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
22Computes the integral over a binned distribution by summing the bin contents of all bins.
23**/
24
25#include "RooBinIntegrator.h"
26
27#include "RooArgSet.h"
28#include "RooRealVar.h"
29#include "RooNumber.h"
30#include "RooNumIntConfig.h"
31#include "RooNumIntFactory.h"
32#include "RooMsgService.h"
33#include "RooRealBinding.h"
34
35#include "TClass.h"
36#include "Math/Util.h"
37
38#include <cassert>
39#include <memory>
40
41
42
43using namespace std;
44
45
46// Register this class with RooNumIntConfig
47
48////////////////////////////////////////////////////////////////////////////////
49/// Register RooBinIntegrator, is parameters and capabilities with RooNumIntFactory
50
52{
53 RooRealVar numBins("numBins","Number of bins in range",100) ;
54
55 std::string name = "RooBinIntegrator";
56
57 auto creator = [](const RooAbsFunc &function, const RooNumIntConfig &config) {
58 return std::make_unique<RooBinIntegrator>(function, config);
59 };
60
61 fact.registerPlugin(name, creator, {numBins},
62 /*canIntegrate1D=*/true,
63 /*canIntegrate2D=*/true,
64 /*canIntegrateND=*/true,
65 /*canIntegrateOpenEnded=*/false);
66
68}
69
70
71////////////////////////////////////////////////////////////////////////////////
72/// Construct integrator on given function binding binding
73
75 : RooAbsIntegrator(function), _useIntegrandLimits(true)
76{
77 assert(_function && _function->isValid());
78
79 // Allocate coordinate buffer size after number of function dimensions
80 _x.resize(_function->getDimension());
81 _numBins = numBins;
82
83 _xmin.resize(_function->getDimension()) ;
84 _xmax.resize(_function->getDimension()) ;
85
86 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
89
90 // Retrieve bin configuration from integrand
91 std::unique_ptr<list<double>> tmp{ _function->binBoundaries(i) };
92 if (!tmp) {
93 oocoutW(nullptr,Integration) << "RooBinIntegrator::RooBinIntegrator WARNING: integrand provide no binning definition observable #"
94 << i << " substituting default binning of " << _numBins << " bins" << endl ;
95 tmp = std::make_unique<list<double>>( );
96 for (Int_t j=0 ; j<=_numBins ; j++) {
97 tmp->push_back(_xmin[i]+j*(_xmax[i]-_xmin[i])/_numBins) ;
98 }
99 }
100 _binb.emplace_back(tmp->begin(), tmp->end());
101
102 }
103 checkLimits();
104
105}
106
107
108////////////////////////////////////////////////////////////////////////////////
109/// Construct integrator on given function binding binding
110
112 RooBinIntegrator(function, static_cast<int>(config.getConfigSection("RooBinIntegrator").getRealValue("numBins")))
113{
114}
115
116
117////////////////////////////////////////////////////////////////////////////////
118/// Change our integration limits. Return true if the new limits are
119/// ok, or otherwise false. Always returns false and does nothing
120/// if this object was constructed to always use our integrand's limits.
121
123{
125 oocoutE(nullptr,Integration) << "RooBinIntegrator::setLimits: cannot override integrand's limits" << endl;
126 return false;
127 }
128 _xmin[0]= *xmin;
129 _xmax[0]= *xmax;
130 return checkLimits();
131}
132
133
134////////////////////////////////////////////////////////////////////////////////
135/// Check that our integration range is finite and otherwise return false.
136/// Update the limits from the integrand if requested.
137
139{
141 assert(nullptr != integrand() && integrand()->isValid());
142 _xmin.resize(_function->getDimension()) ;
143 _xmax.resize(_function->getDimension()) ;
144 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
145 _xmin[i]= integrand()->getMinLimit(i);
146 _xmax[i]= integrand()->getMaxLimit(i);
147 }
148 }
149 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
150 if (_xmax[i]<=_xmin[i]) {
151 oocoutE(nullptr,Integration) << "RooBinIntegrator::checkLimits: bad range with min >= max (_xmin = " << _xmin[i] << " _xmax = " << _xmax[i] << ")" << endl;
152 return false;
153 }
155 return false ;
156 }
157 }
158
159 return true;
160}
161
162
163////////////////////////////////////////////////////////////////////////////////
164/// Calculate numeric integral at given set of function binding parameters.
165double RooBinIntegrator::integral(const double *)
166{
167 assert(isValid());
168
170
171 if (_function->getDimension() == 1) {
172 const std::vector<double>& binb = _binb[0];
173
174 for (unsigned int ibin=0; ibin < binb.size() - 1; ++ibin) {
175 const double xhi = binb[ibin + 1];
176 const double xlo = binb[ibin];
177 const double xcenter = (xhi+xlo)/2.;
178 const double binInt = integrand(xvec(xcenter))*(xhi-xlo) ;
179 sum += binInt ;
180 }
181 } else if (_function->getDimension() == 2) {
182 const std::vector<double>& binbx = _binb[0];
183 const std::vector<double>& binby = _binb[1];
184
185 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
186 const double x1hi = binbx[ibin1 + 1];
187 const double x1lo = binbx[ibin1];
188 double x1center = (x1hi+x1lo)/2 ;
189
190 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
191 const double x2hi = binby[ibin2 + 1];
192 const double x2lo = binby[ibin2];
193 const double x2center = (x2hi+x2lo)/2.;
194
195 const double binInt = integrand(xvec(x1center,x2center))*(x1hi-x1lo)*(x2hi-x2lo) ;
196 sum += binInt ;
197 }
198 }
199 } else if (_function->getDimension() == 3) {
200 const std::vector<double>& binbx = _binb[0];
201 const std::vector<double>& binby = _binb[1];
202 const std::vector<double>& binbz = _binb[2];
203
204 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
205 const double x1hi = binbx[ibin1 + 1];
206 const double x1lo = binbx[ibin1];
207 double x1center = (x1hi+x1lo)/2 ;
208
209 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
210 const double x2hi = binby[ibin2 + 1];
211 const double x2lo = binby[ibin2];
212 const double x2center = (x2hi+x2lo)/2.;
213
214 for (unsigned int ibin3=0; ibin3 < binbz.size() - 1; ++ibin3) {
215 const double x3hi = binbz[ibin3 + 1];
216 const double x3lo = binbz[ibin3];
217 const double x3center = (x3hi+x3lo)/2.;
218
219 const double binInt = integrand(xvec(x1center,x2center,x3center))*(x1hi-x1lo)*(x2hi-x2lo)*(x3hi-x3lo);
220 sum += binInt ;
221 }
222 }
223 }
224 }
225
226 return sum.Sum();
227}
228
229
RooAbsReal & function()
#define oocoutW(o, a)
#define oocoutE(o, a)
char name[80]
Definition TGX11.cxx:110
float xmin
float xmax
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
Abstract interface for integrators of real-valued functions that implement the RooAbsFunc interface.
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.
Computes the integral over a binned distribution by summing the bin contents of all bins.
std::vector< double > _xmax
! Upper integration bound
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
RooBinIntegrator(const RooAbsFunc &function, int numBins=100)
Construct integrator on given function binding binding.
double * xvec(double xx)
std::vector< double > _x
! do not persist
bool _useIntegrandLimits
If true limits of function binding are ued.
bool checkLimits() const override
Check that our integration range is finite and otherwise return false.
double integral(const double *yvec=nullptr) override
Calculate numeric integral at given set of function binding parameters.
bool setLabel(const char *label, bool printError=true) override
Set value by specifying the name of the desired state.
Holds the configuration parameters of the various numeric integrators used by RooRealIntegral.
RooCategory & method1D()
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.
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...
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
static uint64_t sum(uint64_t i)
Definition Factory.cxx:2345