 ROOT   Reference Guide DistSampler.cxx
Go to the documentation of this file.
1// @(#)root/mathcore:$Id$
2// Author: L. Moneta Fri Sep 22 15:06:47 2006
3
4/**********************************************************************
5 * *
6 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT *
7 * *
8 * *
9 **********************************************************************/
10
11// implementation file for class DistSampler
12
13#include "Math/DistSampler.h"
15#include "Math/Error.h"
16
17#include "Math/IFunction.h"
18#include "Math/IFunctionfwd.h"
19#include "Fit/BinData.h"
20#include "Fit/UnBinData.h"
21#include "Fit/DataRange.h"
22
23
24namespace ROOT {
25
26
27namespace Math {
28
30 // destructor
31 if (fOwnFunc && fFunc != 0) delete fFunc;
32 if (fRange) delete fRange;
33}
34
36 // default initialization with algorithm name
37 return Init(opt.Algorithm().c_str() );
38}
39
40void DistSampler::SetRange(double xmin, double xmax, int icoord) {
41 if (!fRange) {
42 MATH_ERROR_MSG("DistSampler::SetRange","Need to set function before setting the range");
43 return;
44 }
45 fRange->SetRange(icoord,xmin,xmax);
46}
47
48void DistSampler::SetRange(const double * xmin, const double * xmax) {
49 // set range specifying a vector for all coordinates
50 if (!fRange) {
51 MATH_ERROR_MSG("DistSampler::SetRange","Need to set function before setting the range");
52 return;
53 }
54 for (unsigned int icoord = 0; icoord < NDim(); ++icoord)
55 fRange->SetRange(icoord,xmin[icoord],xmax[icoord]);
56}
57
59 // copy the given range
60 *fRange = range;
61}
62
64 // set the internal function
65 // if a range exists and it is compatible it will be re-used
66 if (fOwnFunc && fFunc != 0) delete fFunc;
67 if (copy) {
68 fOwnFunc = true;
69 fFunc = func.Clone();
70 }
71 else {
72 fOwnFunc = false;
73 fFunc = &func;
74 }
75 DoSetDimension(func.NDim() );
76}
77
78void DistSampler::DoSetDimension(unsigned int ndim) {
79 // set function dimension (might be needed to initialize correctly the sampler)
80 fData = std::vector<double>(ndim);
81 // delete a range if exists and it is not compatible
82 if (fRange && fRange->NDim() != ndim ) {
83 delete fRange;
84 fRange = nullptr;
85 }
86 if (!fRange) fRange = new ROOT::Fit::DataRange(ndim);
87}
88
90 // test if sampler is initialized
91 // trying to generate one event (for this cannot be const)
92 if (NDim() == 0) return false;
93 if (fFunc && fFunc->NDim() != NDim() ) return false;
94 // test one event
95 if (!Sample(&fData) ) return false;
96 return true;
97}
98
99bool DistSampler::Generate(unsigned int nevt, ROOT::Fit::UnBinData & data) {
100 // generate a un-binned data sets (fill the given data set)
101 // if dataset has already data append to it
102 if (!IsInitialized()) {
103 MATH_WARN_MSG("DistSampler::Generate","sampler has not been initialized correctly");
104 return false;
105 }
106
107 data.Append( nevt, NDim() );
108 for (unsigned int i = 0; i < nevt; ++i) {
109 const double * x = Sample();
111 }
112 return true;
113}
114
115bool DistSampler::Generate(unsigned int nevt, double * data, bool eventRow) {
116 if (!IsInitialized()) {
117 MATH_WARN_MSG("DistSampler::Generate","sampler has not been initialized correctly");
118 return false;
119 }
120 unsigned int ndim = NDim();
121 for (unsigned int i = 0; i < nevt; ++i) {
122 const double * x = Sample();
123 assert(x != nullptr);
124 if (eventRow)
125 std::copy(x,x+ndim,data+i*ndim);
126 else {
127 for (unsigned int j = 0; j < ndim; ++j) {
128 data[j*nevt+i] = x[j];
129 }
130 }
131 }
132 return true;
133}
134
135bool DistSampler::Generate(unsigned int nevt, const int * nbins, ROOT::Fit::BinData & data, bool extend, bool expErr) {
136 // generate a bin data set from given bin center values
137 // bin center values must be present in given data set
138 if (!IsInitialized()) {
139 MATH_WARN_MSG("DistSampler::Generate","sampler has not been initialized correctly");
140 return false;
141 }
142
143 int ntotbins = 1;
144 for (unsigned int j = 0; j < NDim(); ++j) {
145 ntotbins *= nbins[j];
146 }
147
148 data.Append(ntotbins, NDim(), ROOT::Fit::BinData::kValueError); // store always the error
149 // use for the moment bin center (should use bin integral)
150 std::vector<double> dx(NDim() );
151 std::vector<double> x(NDim() );
152 double binVolume = 1;
153 for (unsigned int j = 0; j < dx.size(); ++j) {
154 double x1 = 0,x2 = 0;
155 if (!fRange || !fRange->Size(j)) {
156 MATH_WARN_MSG("DistSampler::Generate","sampler has not a range defined for all coordinates");
157 return false;
158 }
159 fRange->GetRange(j,x1,x2);
160 dx[j] = (x2-x1)/double(nbins[j]);
161 assert(dx[j] > 0 && 1./dx[j] > 0 ); // avoid dx <= 0 and not inf
162 x[j] = x1 + dx[j]/2; // use bin centers
163 binVolume *= dx[j];
164 }
165 double nnorm = nevt * binVolume;
166
167 if (extend) {
168
169 bool ret = true;
170 for (int j = NDim()-1; j >=0; --j) {
171 for (int i = 0; i < nbins[j]; ++i) {
172 //const double * v = Sample();
173 double val = 0;
174 double yval = (ParentPdf())(&x.front());
175 double nexp = yval * nnorm;
176 ret &= SampleBin(nexp,val,nullptr);
177 double eval = (expErr) ? std::sqrt(nexp) : std::sqrt(val);
179 x[j] += dx[j]; // increment x bin the bin
180 }
181 if (!ret) {
182 MATH_WARN_MSG("DistSampler::Generate","error returned from SampleBin");
183 return false;
184 }
185 }
186 }
187 else {
188 MATH_WARN_MSG("DistSampler::Generate","generation with fixed events not yet impelmented");
189 return false;
190 }
191 return true;
192}
193
194} // end namespace Math
195} // end namespace ROOT
#define MATH_ERROR_MSG(loc, str)
Definition: Error.h:83
#define MATH_WARN_MSG(loc, str)
Definition: Error.h:80
static const double x2
static const double x1
float xmin
Definition: THbookFile.cxx:95
float xmax
Definition: THbookFile.cxx:95
Class describing the binned data sets : vectors of x coordinates, y values and optionally error on y ...
Definition: BinData.h:52
void Append(unsigned int newPoints, unsigned int dim=1, ErrorType err=kValueError)
preallocate a data set with given size , dimension and error type (to get the full point size) If the...
Definition: BinData.cxx:322
add one dim data with only coordinate and values
Definition: BinData.cxx:416
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:35
unsigned int NDim() const
get range dimension
Definition: DataRange.h:65
unsigned int Size(unsigned int icoord=0) const
return range size for coordinate icoord (starts from zero) Size == 0 indicates no range is present [-...
Definition: DataRange.h:71
void GetRange(unsigned int irange, unsigned int icoord, double &xmin, double &xmax) const
get the i-th range for given coordinate.
Definition: DataRange.h:104
void SetRange(unsigned int icoord, double xmin, double xmax)
set a range [xmin,xmax] for the new coordinate icoord If more range exists for other coordinates,...
Definition: DataRange.cxx:124
Class describing the unbinned data sets (just x coordinates values) of any dimensions.
Definition: UnBinData.h:42
preallocate a data set given size and dimension of the coordinates if a vector already exists with co...
Definition: UnBinData.h:200
void Append(unsigned int newPoints, unsigned int dim=1, bool isWeighted=false)
Definition: UnBinData.h:288
DistSampler options class.
const std::string & Algorithm() const
type of algorithm (method)
const double * Sample()
Sample one event and return an array x with sample coordinates values.
Definition: DistSampler.h:193
virtual bool SampleBin(double prob, double &value, double *error=0)
Sample one bin given an estimate of the pdf in the bin.
Definition: DistSampler.h:212
ROOT::Fit::DataRange * fRange
data range
Definition: DistSampler.h:287
virtual void DoSetFunction(const ROOT::Math::IMultiGenFunction &func, bool copy)
Definition: DistSampler.cxx:63
const ROOT::Math::IMultiGenFunction & ParentPdf() const
Get the parent distribution function (must be called after setting the function).
Definition: DistSampler.h:173
unsigned int NDim() const
return the dimension of the parent distribution (and the data)
Definition: DistSampler.h:91
virtual ~DistSampler()
virtual destructor
Definition: DistSampler.cxx:29
virtual bool Generate(unsigned int nevt, ROOT::Fit::UnBinData &data)
Generate a un-binned data set by filling the given data set object.
Definition: DistSampler.cxx:99
const ROOT::Math::IMultiGenFunction * fFunc
internal function (ND)
Definition: DistSampler.h:288
void SetRange(double xmin, double xmax, int icoord=0)
Set the range in a given dimension.
Definition: DistSampler.cxx:40
virtual void DoSetDimension(unsigned int ndim)
Definition: DistSampler.cxx:78
virtual bool Init(const char *="")
Initialize the sampling generator with the given algorithm.
Definition: DistSampler.h:101
std::vector< double > fData
! internal array used to cached the sample data
Definition: DistSampler.h:286
bool fOwnFunc
flag to indicate if the function is owned
Definition: DistSampler.h:285
Documentation for the abstract class IBaseFunctionMultiDim.
Definition: IFunction.h:62
virtual IBaseFunctionMultiDimTempl< T > * Clone() const =0
Clone a function.
virtual unsigned int NDim() const =0
Retrieve the dimension of the function.
Double_t x[n]
Definition: legend1.C:17
Namespace for new Math classes and functions.
VecExpr< UnaryOp< Sqrt< T >, VecExpr< A, T, D >, T >, T, D > sqrt(const VecExpr< A, T, D > &rhs)
This file contains a specialised ROOT message handler to test for diagnostic in unit tests.