Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
RooGrid.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 RooGrid.cxx
19\class RooGrid
20\ingroup Roofitcore
21
22RooGrid is a utility class for RooMCIntegrator which
23implements an adaptive multi-dimensional Monte Carlo numerical
24integration, following the VEGAS algorithm.
25**/
26
27#include "RooGrid.h"
28#include "RooAbsFunc.h"
29#include "RooNumber.h"
30#include "RooRandom.h"
31#include "TMath.h"
32#include "RooMsgService.h"
33
34#include <math.h>
35#include "Riostream.h"
36#include <iomanip>
37
38
39
40////////////////////////////////////////////////////////////////////////////////
41/// Constructor with given function binding
42
44 : _valid(true)
45{
46 // check that the input function is valid
47 if(!(_valid= function.isValid())) {
48 oocoutE(nullptr,InputArguments) << "RooGrid: cannot initialize using an invalid function" << std::endl;
49 return;
50 }
51
52 // allocate workspace memory
53 _dim= function.getDimension();
54 _xl.resize(_dim);
55 _xu.resize(_dim);
56 _delx.resize(_dim);
57 _d.resize(_dim*maxBins);
58 _xi.resize(_dim*(maxBins+1));
59 _xin.resize(maxBins+1);
60 _weight.resize(maxBins);
61
62 // initialize the grid
63 _valid= initialize(function);
64}
65
66
67////////////////////////////////////////////////////////////////////////////////
68/// Calculate and store the grid dimensions and volume using the
69/// specified function, and initialize the grid using a single bin.
70/// Return true, or else false if the range is not valid.
71
72bool RooGrid::initialize(const RooAbsFunc &function)
73{
74 _vol= 1;
75 _bins= 1;
76 for(UInt_t index= 0; index < _dim; index++) {
77 _xl[index]= function.getMinLimit(index);
79 oocoutE(nullptr,Integration) << "RooGrid: lower limit of dimension " << index << " is infinite" << std::endl;
80 return false;
81 }
82 _xu[index]= function.getMaxLimit(index);
84 oocoutE(nullptr,Integration) << "RooGrid: upper limit of dimension " << index << " is infinite" << std::endl;
85 return false;
86 }
87 double dx= _xu[index] - _xl[index];
88 if(dx <= 0) {
89 oocoutE(nullptr,Integration) << "RooGrid: bad range for dimension " << index << ": [" << _xl[index]
90 << "," << _xu[index] << "]" << std::endl;
91 return false;
92 }
93 _delx[index]= dx;
94 _vol*= dx;
95 coord(0,index) = 0;
96 coord(1,index) = 1;
97 }
98 return true;
99}
100
101
102////////////////////////////////////////////////////////////////////////////////
103/// Adjust the subdivision of each axis to give the specified
104/// number of bins, using an algorithm that preserves relative
105/// bin density. The new binning can be finer or coarser than
106/// the original binning.
107
109{
110 // is there anything to do?
111 if(bins == _bins) return;
112
113 // weight is ratio of bin sizes
114 double pts_per_bin = (double) _bins / (double) bins;
115
116 // loop over grid dimensions
117 for (UInt_t j = 0; j < _dim; j++) {
118 double xold,xnew(0),dw(0);
119 Int_t i = 1;
120 // loop over bins in this dimension and load _xin[] with new bin edges
121
122 UInt_t k;
123 for(k = 1; k <= _bins; k++) {
124 dw += 1.0;
125 xold = xnew;
126 xnew = coord(k,j);
127 while(dw > pts_per_bin) {
128 dw -= pts_per_bin;
129 newCoord(i++)= xnew - (xnew - xold) * dw;
130 }
131 }
132 // copy the new edges into _xi[j]
133 for(k = 1 ; k < bins; k++) {
134 coord(k, j) = newCoord(k);
135 }
136 coord(bins, j) = 1;
137 }
138 _bins = bins;
139}
140
141
142////////////////////////////////////////////////////////////////////////////////
143/// Reset the values associated with each grid cell.
144
146{
147 for(UInt_t i = 0; i < _bins; i++) {
148 for (UInt_t j = 0; j < _dim; j++) {
149 value(i,j)= 0.0;
150 }
151 }
152}
153
154
155////////////////////////////////////////////////////////////////////////////////
156/// Generate a random vector in the specified box and store its
157/// coordinates in the x[] array provided, the corresponding bin
158/// indices in the bin[] array, and the volume of this bin in vol.
159/// The box is specified by the array box[] of box integer indices
160/// that each range from 0 to getNBoxes()-1.
161
162void RooGrid::generatePoint(const UInt_t box[], double x[], UInt_t bin[], double &vol,
163 bool useQuasiRandom) const
164{
165 vol= 1;
166
167 // generate a vector of quasi-random numbers to use
168 if(useQuasiRandom) {
170 }
171 else {
173 }
174
175 // loop over coordinate axes
176 for(UInt_t j= 0; j < _dim; ++j) {
177
178 // generate a random point uniformly distributed (in box space)
179 // within the box[j]-th box of coordinate axis j.
180 double z= ((box[j] + x[j])/_boxes)*_bins;
181
182 // store the bin in which this point lies along the j-th
183 // coordinate axis and calculate its width and position y
184 // in normalized bin coordinates.
185 Int_t k= static_cast<Int_t>(z);
186 bin[j] = k;
187 double y, bin_width;
188 if(k == 0) {
189 bin_width= coord(1,j);
190 y= z * bin_width;
191 }
192 else {
193 bin_width= coord(k+1,j) - coord(k,j);
194 y= coord(k,j) + (z-k)*bin_width;
195 }
196 // transform from normalized bin coordinates to x space.
197 x[j] = _xl[j] + y*_delx[j];
198
199 // update this bin's calculated volume
200 vol *= bin_width;
201 }
202}
203
204
205
206////////////////////////////////////////////////////////////////////////////////
207/// Reset the specified array of box indices to refer to the first box
208/// in the standard traversal order.
209
211{
212 for(UInt_t i= 0; i < _dim; i++) box[i]= 0;
213}
214
215
216
217////////////////////////////////////////////////////////////////////////////////
218/// Update the specified array of box indices to refer to the next box
219/// in the standard traversal order and return true, or else return
220/// false if we the indices already refer to the last box.
221
223{
224 // try incrementing each index until we find one that does not roll
225 // over, starting from the last index.
226 Int_t j(_dim-1);
227 while (j >= 0) {
228 box[j]= (box[j] + 1) % _boxes;
229 if (0 != box[j]) return true;
230 j--;
231 }
232 // if we get here, then there are no more boxes
233 return false;
234}
235
236
237
238////////////////////////////////////////////////////////////////////////////////
239/// Print info about this object to the specified stream.
240
241void RooGrid::print(std::ostream& os, bool verbose, std::string const& indent) const
242{
243 os << "RooGrid: volume = " << getVolume() << std::endl;
244 os << indent << " Has " << getDimension() << " dimension(s) each subdivided into "
245 << getNBins() << " bin(s) and sampled with " << _boxes << " box(es)" << std::endl;
246 for(std::size_t index= 0; index < getDimension(); index++) {
247 os << indent << " (" << index << ") ["
248 << std::setw(10) << _xl[index] << "," << std::setw(10) << _xu[index] << "]" << std::endl;
249 if(!verbose) continue;
250 for(std::size_t bin= 0; bin < _bins; bin++) {
251 os << indent << " bin-" << bin << " : x = " << coord(bin,index) << " , y = "
252 << value(bin,index) << std::endl;
253 }
254 }
255}
256
257
258////////////////////////////////////////////////////////////////////////////////
259/// Add the specified amount to bin[j] of the 1D histograms associated
260/// with each axis j.
261
262void RooGrid::accumulate(const UInt_t bin[], double amount)
263{
264 for(UInt_t j = 0; j < _dim; j++) value(bin[j],j) += amount;
265}
266
267
268////////////////////////////////////////////////////////////////////////////////
269/// Refine the grid using the values that have been accumulated so far.
270/// The parameter alpha controls the stiffness of the rebinning and should
271/// usually be between 1 (stiffer) and 2 (more flexible). A value of zero
272/// prevents any rebinning.
273
274void RooGrid::refine(double alpha)
275{
276 for (UInt_t j = 0; j < _dim; j++) {
277
278 // smooth this dimension's histogram of grid values and calculate the
279 // new sum of the histogram contents as grid_tot_j
280 double oldg = value(0,j);
281 double newg = value(1,j);
282 value(0,j)= (oldg + newg)/2;
283 double grid_tot_j = value(0,j);
284 // this loop implements value(i,j) = ( value(i-1,j)+value(i,j)+value(i+1,j) ) / 3
285
286 UInt_t i;
287 for (i = 1; i < _bins - 1; i++) {
288 double rc = oldg + newg;
289 oldg = newg;
290 newg = value(i+1,j);
291 value(i,j)= (rc + newg)/3;
292 grid_tot_j+= value(i,j);
293 }
294 value(_bins-1,j)= (newg + oldg)/2;
295 grid_tot_j+= value(_bins-1,j);
296
297 // calculate the weights for each bin of this dimension's histogram of values
298 // and their sum
299 double tot_weight(0);
300 for (i = 0; i < _bins; i++) {
301 _weight[i] = 0;
302 if (value(i,j) > 0) {
303 oldg = grid_tot_j/value(i,j);
304 /* damped change */
305 _weight[i] = TMath::Power(((oldg-1.0)/oldg/log(oldg)), alpha);
306 }
307 tot_weight += _weight[i];
308 }
309
310 double pts_per_bin = tot_weight / _bins;
311
312 double xold;
313 double xnew = 0;
314 double dw = 0;
315
316 i = 1;
317 for (UInt_t k = 0; k < _bins; k++) {
318 dw += _weight[k];
319 xold = xnew;
320 xnew = coord(k+1,j);
321
322 while(dw > pts_per_bin) {
323 dw -= pts_per_bin;
324 newCoord(i++) = xnew - (xnew - xold) * dw / _weight[k];
325 }
326 }
327
328 for (UInt_t k = 1 ; k < _bins ; k++) {
329 coord( k, j) = newCoord(k);
330 }
331
332 coord(_bins, j) = 1;
333 }
334}
#define oocoutE(o, a)
static void indent(ostringstream &buf, int indent_level)
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void char Point_t Rectangle_t WindowAttributes_t index
Option_t Option_t TPoint TPoint const char GetTextMagnitude GetFillStyle GetLineColor GetLineWidth GetMarkerStyle GetTextAlign GetTextColor GetTextSize void value
Abstract interface for evaluating a real-valued function of one real variable and performing numerica...
Definition RooAbsFunc.h:27
UInt_t getDimension() const
Definition RooGrid.h:36
std::vector< double > _xl
! Internal workspace
Definition RooGrid.h:70
@ maxBins
Definition RooGrid.h:53
bool initialize(const RooAbsFunc &function)
Calculate and store the grid dimensions and volume using the specified function, and initialize the g...
Definition RooGrid.cxx:72
double _vol
Volume.
Definition RooGrid.h:68
void generatePoint(const UInt_t box[], double x[], UInt_t bin[], double &vol, bool useQuasiRandom=true) const
Generate a random vector in the specified box and store its coordinates in the x[] array provided,...
Definition RooGrid.cxx:162
double getVolume() const
Definition RooGrid.h:37
std::vector< double > _weight
! Internal workspace
Definition RooGrid.h:76
std::vector< double > _xu
! Internal workspace
Definition RooGrid.h:71
UInt_t _dim
Number of dimensions, bins and boxes.
Definition RooGrid.h:65
UInt_t getNBins() const
Definition RooGrid.h:38
UInt_t _bins
Number of bins.
Definition RooGrid.h:66
bool _valid
Is configuration valid.
Definition RooGrid.h:64
void resetValues()
Reset the values associated with each grid cell.
Definition RooGrid.cxx:145
RooGrid()
Definition RooGrid.h:29
UInt_t _boxes
Numbser of boxes.
Definition RooGrid.h:67
std::vector< double > _xi
! Internal workspace
Definition RooGrid.h:74
void accumulate(const UInt_t bin[], double amount)
Add the specified amount to bin[j] of the 1D histograms associated with each axis j.
Definition RooGrid.cxx:262
std::vector< double > _d
! Internal workspace
Definition RooGrid.h:73
double coord(Int_t i, Int_t j) const
Definition RooGrid.h:56
bool nextBox(UInt_t box[]) const
Update the specified array of box indices to refer to the next box in the standard traversal order an...
Definition RooGrid.cxx:222
std::vector< double > _delx
! Internal workspace
Definition RooGrid.h:72
void resize(UInt_t bins)
Adjust the subdivision of each axis to give the specified number of bins, using an algorithm that pre...
Definition RooGrid.cxx:108
void refine(double alpha=1.5)
Refine the grid using the values that have been accumulated so far.
Definition RooGrid.cxx:274
void firstBox(UInt_t box[]) const
Reset the specified array of box indices to refer to the first box in the standard traversal order.
Definition RooGrid.cxx:210
std::vector< double > _xin
! Internal workspace
Definition RooGrid.h:75
double & newCoord(Int_t i)
Definition RooGrid.h:62
void print(std::ostream &os, bool verbose=false, std::string const &indent="") const
Print info about this object to the specified stream.
Definition RooGrid.cxx:241
static constexpr int isInfinite(double x)
Return true if x is infinite by RooNumber internal specification.
Definition RooNumber.h:34
static double uniform(TRandom *generator=randomGenerator())
Return a number uniformly distributed from (0,1)
Definition RooRandom.cxx:81
static bool quasi(UInt_t dimension, double vector[], RooQuasiRandomGenerator *generator=quasiGenerator())
Return a quasi-random number in the range (0,1) using the Niederreiter base 2 generator described in ...
void box(Int_t pat, Double_t x1, Double_t y1, Double_t x2, Double_t y2)
Definition fillpatterns.C:1
Double_t y[n]
Definition legend1.C:17
Double_t x[n]
Definition legend1.C:17
LongDouble_t Power(LongDouble_t x, LongDouble_t y)
Returns x raised to the power y.
Definition TMath.h:719