Logo ROOT  
Reference Guide
 
Loading...
Searching...
No Matches
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 fData = std::vector<double>(func.NDim());
76 // delete a range if exists and it is not compatible
77 if (fRange && fRange->NDim() != fData.size() ) {
78 delete fRange;
79 fRange = 0;
80 }
81 if (!fRange) fRange = new ROOT::Fit::DataRange(func.NDim() );
82}
83
85 // test if sampler is initialized
86 // tryying to generate one event (for this cannot be const)
87 if (NDim() == 0) return false;
88 if (fFunc == 0) return false;
89 if (fFunc->NDim() != NDim() ) return false;
90 // test one event
91 if (!Sample(&fData[0]) ) return false;
92 return true;
93}
94
95bool DistSampler::Generate(unsigned int nevt, ROOT::Fit::UnBinData & data) {
96 // generate a un-binned data sets (fill the given data set)
97 // if dataset has already data append to it
98 if (!IsInitialized()) {
99 MATH_WARN_MSG("DistSampler::Generate","sampler has not been initialized correctly");
100 return false;
101 }
102
103 data.Append( nevt, NDim() );
104 for (unsigned int i = 0; i < nevt; ++i) {
105 const double * x = Sample();
106 data.Add( x );
107 }
108 return true;
109}
110
111
112 bool DistSampler::Generate(unsigned int nevt, const int * nbins, ROOT::Fit::BinData & data, bool extend) {
113 // generate a bin data set from given bin center values
114 // bin center values must be present in given data set
115 //if (!IsInitialized()) {
116 if (NDim() == 0 || fFunc == 0 ) {
117 MATH_WARN_MSG("DistSampler::Generate","sampler has not been initialized correctly");
118 return false;
119 }
120
121
122 int ntotbins = 1;
123 for (unsigned int j = 0; j < NDim(); ++j) {
124 ntotbins *= nbins[j];
125 }
126
127 data.Append(ntotbins, NDim(), ROOT::Fit::BinData::kValueError); // store always the error
128 // use for the moment bin center (should use bin integral)
129 std::vector<double> dx(NDim() );
130 std::vector<double> x(NDim() );
131 double binVolume = 1;
132 for (unsigned int j = 0; j < dx.size(); ++j) {
133 double x1 = 0,x2 = 0;
134 if (!fRange || !fRange->Size(j)) {
135 MATH_WARN_MSG("DistSampler::Generate","sampler has not a range defined for all coordinates");
136 return false;
137 }
138 fRange->GetRange(j,x1,x2);
139 dx[j] = (x2-x1)/double(nbins[j]);
140 assert(dx[j] > 0 && 1./dx[j] > 0 ); // avoid dx <= 0 and not inf
141 x[j] = x1 + dx[j]/2; // use bin centers
142 binVolume *= dx[j];
143 }
144 double nnorm = nevt * binVolume;
145
146 if (extend) {
147
148 bool ret = true;
149 for (int j = NDim()-1; j >=0; --j) {
150 for (int i = 0; i < nbins[j]; ++i) {
151 //const double * v = Sample();
152 double val = 0;
153 double eval = 0;
154 double yval = (ParentPdf())(&x.front());
155 double nexp = yval * nnorm;
156 ret &= SampleBin(nexp,val,&eval);
157 data.Add(&x.front(), val, eval);
158 x[j] += dx[j]; // increment x bin the bin
159 }
160 if (!ret) {
161 MATH_WARN_MSG("DistSampler::Generate","error returned from SampleBin");
162 return false;
163 }
164 }
165 }
166 else {
167 MATH_WARN_MSG("DistSampler::Generate","generation with fixed events not yet impelmented");
168 return false;
169 }
170 return true;
171}
172
173} // end namespace Math
174} // 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[5]
static const double x1[5]
float xmin
float xmax
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
void Add(double x, double y)
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,...
Class describing the unbinned data sets (just x coordinates values) of any dimensions.
Definition UnBinData.h:42
void Add(double x)
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
const double * Sample()
sample one event and rerturning array x with coordinates
virtual bool SampleBin(double prob, double &value, double *error=0)
sample one bin given an estimated of the pdf in the bin (this can be function value at the center or ...
ROOT::Fit::DataRange * fRange
virtual void DoSetFunction(const ROOT::Math::IMultiGenFunction &func, bool copy)
const ROOT::Math::IMultiGenFunction & ParentPdf() const
get the parent distribution function (must be called after setting the function)
unsigned int NDim() const
return the dimension of the parent distribution (and the data)
Definition DistSampler.h:91
virtual ~DistSampler()
virtual destructor
virtual bool Generate(unsigned int nevt, ROOT::Fit::UnBinData &data)
generate a un-binned data sets (fill the given data set) if dataset has already data append to it
const ROOT::Math::IMultiGenFunction * fFunc
void SetRange(double xmin, double xmax, int icoord=0)
set range in a given dimension
virtual bool Init(const char *="")
initialize the generators with the given algorithm Implemented by derived classes who needs it (like ...
std::vector< double > fData
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.
tbb::task_arena is an alias of tbb::interface7::task_arena, which doesn't allow to forward declare tb...