Logo ROOT   6.13/01
Reference Guide
TUnuranSampler.cxx
Go to the documentation of this file.
1 // @(#)root/unuran:$Id$
2 // Authors: L. Moneta, J. Leydold Wed Feb 28 2007
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2010 LCG ROOT Math Team, CERN/PH-SFT *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Implementation file for class TUnuranSampler
12 #include "TUnuranSampler.h"
13 
14 #include "TUnuranContDist.h"
15 #include "TUnuranDiscrDist.h"
16 #include "TUnuranMultiContDist.h"
17 #include "TUnuran.h"
20 #include "Fit/DataRange.h"
21 //#include "Math/WrappedTF1.h"
22 
23 #include "TRandom.h"
24 #include "TError.h"
25 
26 #include "TF1.h"
27 #include <cassert>
28 #include <cmath>
29 
30 ClassImp(TUnuranSampler);
31 
33  fOneDim(false),
34  fDiscrete(false),
35  fHasMode(false), fHasArea(false),
36  fMode(0), fArea(0),
37  fFunc1D(0),
38  fUnuran(new TUnuran() )
39 {
41 }
42 
44  assert(fUnuran != 0);
45  delete fUnuran;
46 }
47 
48 bool TUnuranSampler::Init(const char * algo) {
49  // initialize unuran classes using the given algorithm
50  assert (fUnuran != 0 );
51  if (NDim() == 0) {
52  Error("TUnuranSampler::Init","Distribution function has not been set ! Need to call SetFunction first.");
53  return false;
54  }
55 
57 
58  TString method(algo);
59  if (method.IsNull() ) {
62  }
63  method.ToUpper();
64 
65  bool ret = false;
66  if (NDim() == 1) {
67  // check if distribution is discrete by
68  // using first string in the method name is "D"
69  if (method.First("D") == 0) {
70  if (fLevel>1) Info("TUnuranSampler::Init","Initialize one-dim discrete distribution with method %s",method.Data());
71  ret = DoInitDiscrete1D(method);
72  }
73  else {
74  if (fLevel>1) Info("TUnuranSampler::Init","Initialize one-dim continuous distribution with method %s",method.Data());
75  ret = DoInit1D(method);
76  }
77  }
78  else {
79  if (fLevel>1) Info("TUnuranSampler::Init","Initialize multi-dim continuous distribution with method %s",method.Data());
80  ret = DoInitND(method);
81  }
82  // set print level in UNURAN (must be done after having initialized) -
83  if (fLevel>0) {
84  //fUnuran->SetLogLevel(fLevel); ( seems not to work disable for the time being)
85  if (ret) Info("TUnuranSampler::Init","Successfully initailized Unuran with method %s",method.Data() );
86  else Error("TUnuranSampler::Init","Failed to initailize Unuran with method %s",method.Data() );
87  // seems not to work in UNURAN (cll only when level > 0 )
88  }
89  return ret;
90 }
91 
92 
94  // default initialization with algorithm name
95  SetPrintLevel(opt.PrintLevel() );
96  return Init(opt.Algorithm().c_str() );
97 }
98 
99 
100 bool TUnuranSampler::DoInit1D(const char * method) {
101  // initilize for 1D sampling
102  // need to create 1D interface from Multidim one
103  // (to do: use directly 1D functions ??)
104  fOneDim = true;
105  TUnuranContDist * dist = 0;
106  if (fFunc1D == 0) {
108  dist = new TUnuranContDist(function,0,false,true);
109  }
110  else {
111  dist = new TUnuranContDist(*fFunc1D); // no need to copy the function
112  }
113  // set range in distribution (support only one range)
114  const ROOT::Fit::DataRange & range = PdfRange();
115  if (range.Size(0) > 0) {
116  double xmin, xmax;
117  range.GetRange(0,xmin,xmax);
118  dist->SetDomain(xmin,xmax);
119  }
120  if (fHasMode) dist->SetMode(fMode);
121  if (fHasArea) dist->SetPdfArea(fArea);
122 
123  bool ret = false;
124  if (method) ret = fUnuran->Init(*dist, method);
125  else ret = fUnuran->Init(*dist);
126  delete dist;
127  return ret;
128 }
129 
130 bool TUnuranSampler::DoInitDiscrete1D(const char * method) {
131  // initilize for 1D sampling of discrete distributions
132  fOneDim = true;
133  fDiscrete = true;
134  TUnuranDiscrDist * dist = 0;
135  if (fFunc1D == 0) {
136  // need to copy the passed function pointer in this case
138  dist = new TUnuranDiscrDist(function,true);
139  }
140  else {
141  // no need to copy the function since fFunc1D is managed outside
142  dist = new TUnuranDiscrDist(*fFunc1D, false);
143  }
144  // set range in distribution (support only one range)
145  // otherwise 0, inf is assumed
146  const ROOT::Fit::DataRange & range = PdfRange();
147  if (range.Size(0) > 0) {
148  double xmin, xmax;
149  range.GetRange(0,xmin,xmax);
150  if (xmin < 0) {
151  Warning("DoInitDiscrete1D","range starts from negative values - set minimum to zero");
152  xmin = 0;
153  }
154  dist->SetDomain(int(xmin+0.1),int(xmax+0.1));
155  }
156  if (fHasMode) dist->SetMode(int(fMode+0.1));
157  if (fHasArea) dist->SetProbSum(fArea);
158 
159  bool ret = fUnuran->Init(*dist, method);
160  delete dist;
161  return ret;
162 }
163 
164 
165 bool TUnuranSampler::DoInitND(const char * method) {
166  // initilize for 1D sampling
168  // set range in distribution (support only one range)
169  const ROOT::Fit::DataRange & range = PdfRange();
170  if (range.IsSet()) {
171  std::vector<double> xmin(range.NDim() );
172  std::vector<double> xmax(range.NDim() );
173  range.GetRange(&xmin[0],&xmax[0]);
174  dist.SetDomain(&xmin.front(),&xmax.front());
175 // std::cout << " range is min = ";
176 // for (int j = 0; j < NDim(); ++j) std::cout << xmin[j] << " ";
177 // std::cout << " max = ";
178 // for (int j = 0; j < NDim(); ++j) std::cout << xmax[j] << " ";
179 // std::cout << std::endl;
180  }
181  fOneDim = false;
182  if (method) return fUnuran->Init(dist, method);
183  return fUnuran->Init(dist);
184 }
185 
187  // set function from a TF1 pointer
188  SetFunction<TF1>(*pdf, pdf->GetNdim());
189 }
190 
192  // set random generator (must be called before Init to have effect)
193  fUnuran->SetRandom(r);
194 }
195 
196 void TUnuranSampler::SetSeed(unsigned int seed) {
197  // set random generator seed (must be called before Init to have effect)
198  fUnuran->SetSeed(seed);
199 }
200 
202  // get random generator used
203  return fUnuran->GetRandom();
204 }
205 
207  // sample 1D distributions
208  return (fDiscrete) ? (double) fUnuran->SampleDiscr() : fUnuran->Sample();
209 }
210 
211 bool TUnuranSampler::Sample(double * x) {
212  // sample multi-dim distributions
213  if (!fOneDim) return fUnuran->SampleMulti(x);
214  x[0] = Sample1D();
215  return true;
216 }
217 
218 
219 bool TUnuranSampler::SampleBin(double prob, double & value, double *error) {
220  // sample a bin according to Poisson statistics
221 
222  TRandom * r = fUnuran->GetRandom();
223  if (!r) return false;
224  value = r->Poisson(prob);
225  if (error) *error = std::sqrt(value);
226  return true;
227 }
TRandom * GetRandom()
return instance of the random engine used
Definition: TUnuran.h:214
virtual ~TUnuranSampler()
virtual destructor
double dist(Rotation3D const &r1, Rotation3D const &r2)
Definition: 3DDistances.cxx:48
bool DoInitDiscrete1D(const char *algo)
void SetProbSum(double sum)
set the value of the sum of the probabilities in the given domain
TRandom * GetRandom()
Get the random engine used by the sampler.
Namespace for new ROOT classes and functions.
Definition: TFoamSampler.h:19
double Sample()
Sample 1D distribution User is responsible for having previously correctly initialized with TUnuran::...
Definition: TUnuran.cxx:389
const std::string & Algorithm() const
type of algorithm
bool DoInit1D(const char *algo)
const double * Sample()
sample one event and rerturning array x with coordinates
Definition: DistSampler.h:169
void SetMode(int mode)
set the mode of the distribution (location of maximum probability)
bool Init(const char *algo="")
initialize the generators with the given algorithm If no algorithm is passed used the default one for...
int SampleDiscr()
Sample discrete distributions User is responsible for having previously correctly initialized with TU...
Definition: TUnuran.cxx:382
bool SampleMulti(double *x)
Sample multidimensional distributions User is responsible for having previously correctly initialized...
Definition: TUnuran.cxx:396
void SetPrintLevel(int level)
Set the print level (if level=-1 use default)
TUnuranSampler()
default constructor
double Sample1D()
sample one event in one dimension better implementation could be provided by the derived classes ...
void SetFunction(const ROOT::Math::IGenFunction &func)
set the parent function distribution to use for random sampling (one dim case)
double sqrt(double)
void GetRange(unsigned int irange, unsigned int icoord, double &xmin, double &xmax) const
get the i-th range for given coordinate.
Definition: DataRange.h:103
OneDimMultiFunctionAdapter class to wrap a multidimensional function in one dimensional one...
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:27
void SetSeed(unsigned int seed)
set the seed for the random number generator
Definition: TUnuran.cxx:404
void SetDomain(int xmin, int xmax)
Set the distribution domain, by default the domain is [0,INT_MAX] If xmin >= xmax a domain is removed...
TUnuranDiscrDist class for one dimensional discrete distribution.
int PrintLevel() const
non-static methods for retrivieng options
static const std::string & DefaultAlgorithmND()
DistSampler options class.
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:70
unsigned int NDim() const
return the dimension of the parent distribution (and the data)
Definition: DistSampler.h:91
void SetDomain(const double *xmin, const double *xmax)
set the domain of the distribution giving an array of minimum and maximum values By default otherwise...
TUnuranMultiContDist class describing multi dimensional continuous distributions. ...
void SetSeed(unsigned int seed)
Set the random seed for the TRandom instances used by the sampler classes Needs to be called before I...
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 ...
* x
Deprecated and error prone model selection interface.
Definition: TRolke.cxx:630
TUnuran * fUnuran
void SetDomain(double xmin, double xmax)
Set the distribution domain.
TUnuran class.
Definition: TUnuran.h:79
class describing the range in the coordinates it supports multiple range in a coordinate.
Definition: DataRange.h:34
bool DoInitND(const char *algo)
void SetPdfArea(double area)
set the area below the pdf
Namespace for new Math classes and functions.
const ROOT::Fit::DataRange & PdfRange() const
return the data range of the Pdf . Must be called after setting the function
Definition: DistSampler.h:241
TUnuranContDist class describing one dimensional continuous distribution.
unsigned int NDim() const
get range dimension
Definition: DataRange.h:64
bool Init(const std::string &distr, const std::string &method)
initialize with Unuran string interface
Definition: TUnuran.cxx:79
void SetRandom(TRandom *r)
Set the random engine to be used Needs to be called before Init to have effect.
TUnuranSampler class class implementing the ROOT::Math::DistSampler interface using the UNU...
bool IsSet() const
return true if a range has been set in any of the coordinates i.e.
Definition: DataRange.h:79
static const std::string & DefaultAlgorithm1D()
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:383
const ROOT::Math::IMultiGenFunction & ParentPdf() const
get the parent distribution function (must be called after setting the function)
Definition: DistSampler.h:152
void SetMode(double mode)
set the distribution mode (x position of its maximum)
void SetRandom(TRandom *r)
set the random engine.
Definition: TUnuran.h:207
const ROOT::Math::IGenFunction * fFunc1D