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
42using std::endl, std::list;
43
44
45// Register this class with RooNumIntConfig
46
47////////////////////////////////////////////////////////////////////////////////
48/// Register RooBinIntegrator, is parameters and capabilities with RooNumIntFactory
49
51{
52 RooRealVar numBins("numBins","Number of bins in range",100) ;
53
54 std::string name = "RooBinIntegrator";
55
56 auto creator = [](const RooAbsFunc &function, const RooNumIntConfig &config) {
57 return std::make_unique<RooBinIntegrator>(function, config);
58 };
59
60 fact.registerPlugin(name, creator, {numBins},
61 /*canIntegrate1D=*/true,
62 /*canIntegrate2D=*/true,
63 /*canIntegrateND=*/true,
64 /*canIntegrateOpenEnded=*/false);
65
67}
68
69
70////////////////////////////////////////////////////////////////////////////////
71/// Construct integrator on given function binding binding
72
74 : RooAbsIntegrator(function), _useIntegrandLimits(true)
75{
76 assert(_function && _function->isValid());
77
78 // Allocate coordinate buffer size after number of function dimensions
79 _x.resize(_function->getDimension());
80 _numBins = numBins;
81
82 _xmin.resize(_function->getDimension()) ;
83 _xmax.resize(_function->getDimension()) ;
84
85 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
88
89 // Retrieve bin configuration from integrand
90 std::unique_ptr<list<double>> tmp{ _function->binBoundaries(i) };
91 if (!tmp) {
92 oocoutW(nullptr,Integration) << "RooBinIntegrator::RooBinIntegrator WARNING: integrand provide no binning definition observable #"
93 << i << " substituting default binning of " << _numBins << " bins" << endl ;
94 tmp = std::make_unique<list<double>>( );
95 for (Int_t j=0 ; j<=_numBins ; j++) {
96 tmp->push_back(_xmin[i]+j*(_xmax[i]-_xmin[i])/_numBins) ;
97 }
98 }
99 _binb.emplace_back(tmp->begin(), tmp->end());
100
101 }
102 checkLimits();
103
104}
105
106
107////////////////////////////////////////////////////////////////////////////////
108/// Construct integrator on given function binding binding
109
111 RooBinIntegrator(function, static_cast<int>(config.getConfigSection("RooBinIntegrator").getRealValue("numBins")))
112{
113}
114
115
116////////////////////////////////////////////////////////////////////////////////
117/// Change our integration limits. Return true if the new limits are
118/// ok, or otherwise false. Always returns false and does nothing
119/// if this object was constructed to always use our integrand's limits.
120
122{
124 oocoutE(nullptr,Integration) << "RooBinIntegrator::setLimits: cannot override integrand's limits" << endl;
125 return false;
126 }
127 _xmin[0]= *xmin;
128 _xmax[0]= *xmax;
129 return checkLimits();
130}
131
132
133////////////////////////////////////////////////////////////////////////////////
134/// Check that our integration range is finite and otherwise return false.
135/// Update the limits from the integrand if requested.
136
138{
140 assert(nullptr != integrand() && integrand()->isValid());
141 _xmin.resize(_function->getDimension()) ;
142 _xmax.resize(_function->getDimension()) ;
143 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
144 _xmin[i]= integrand()->getMinLimit(i);
145 _xmax[i]= integrand()->getMaxLimit(i);
146 }
147 }
148 for (UInt_t i=0 ; i<_function->getDimension() ; i++) {
149 if (_xmax[i]<=_xmin[i]) {
150 oocoutE(nullptr,Integration) << "RooBinIntegrator::checkLimits: bad range with min >= max (_xmin = " << _xmin[i] << " _xmax = " << _xmax[i] << ")" << endl;
151 return false;
152 }
154 return false ;
155 }
156 }
157
158 return true;
159}
160
161
162////////////////////////////////////////////////////////////////////////////////
163/// Calculate numeric integral at given set of function binding parameters.
164double RooBinIntegrator::integral(const double *)
165{
166 assert(isValid());
167
169
170 if (_function->getDimension() == 1) {
171 const std::vector<double>& binb = _binb[0];
172
173 for (unsigned int ibin=0; ibin < binb.size() - 1; ++ibin) {
174 const double xhi = binb[ibin + 1];
175 const double xlo = binb[ibin];
176 const double xcenter = (xhi+xlo)/2.;
177 const double binInt = integrand(xvec(xcenter))*(xhi-xlo) ;
178 sum += binInt ;
179 }
180 } else if (_function->getDimension() == 2) {
181 const std::vector<double>& binbx = _binb[0];
182 const std::vector<double>& binby = _binb[1];
183
184 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
185 const double x1hi = binbx[ibin1 + 1];
186 const double x1lo = binbx[ibin1];
187 double x1center = (x1hi+x1lo)/2 ;
188
189 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
190 const double x2hi = binby[ibin2 + 1];
191 const double x2lo = binby[ibin2];
192 const double x2center = (x2hi+x2lo)/2.;
193
194 const double binInt = integrand(xvec(x1center,x2center))*(x1hi-x1lo)*(x2hi-x2lo) ;
195 sum += binInt ;
196 }
197 }
198 } else if (_function->getDimension() == 3) {
199 const std::vector<double>& binbx = _binb[0];
200 const std::vector<double>& binby = _binb[1];
201 const std::vector<double>& binbz = _binb[2];
202
203 for (unsigned int ibin1=0; ibin1 < binbx.size() - 1; ++ibin1) {
204 const double x1hi = binbx[ibin1 + 1];
205 const double x1lo = binbx[ibin1];
206 double x1center = (x1hi+x1lo)/2 ;
207
208 for (unsigned int ibin2=0; ibin2 < binby.size() - 1; ++ibin2) {
209 const double x2hi = binby[ibin2 + 1];
210 const double x2lo = binby[ibin2];
211 const double x2center = (x2hi+x2lo)/2.;
212
213 for (unsigned int ibin3=0; ibin3 < binbz.size() - 1; ++ibin3) {
214 const double x3hi = binbz[ibin3 + 1];
215 const double x3lo = binbz[ibin3];
216 const double x3center = (x3hi+x3lo)/2.;
217
218 const double binInt = integrand(xvec(x1center,x2center,x3center))*(x1hi-x1lo)*(x2hi-x2lo)*(x3hi-x3lo);
219 sum += binInt ;
220 }
221 }
222 }
223 }
224
225 return sum.Sum();
226}
227
228
#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