Logo ROOT   6.30.04
Reference Guide
 All Namespaces Files Pages
DistSampler.h
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 // Header file for class DistSampler
12 
13 #ifndef ROOT_Math_DistSampler
14 #define ROOT_Math_DistSampler
15 
16 #include "Math/IFunctionfwd.h"
17 
18 #include "Math/WrappedFunction.h"
19 
20 #include <vector>
21 #include <cassert>
22 
23 class TRandom;
24 
25 namespace ROOT {
26 
27  namespace Fit {
28 
29  class DataRange;
30  class BinData;
31  class UnBinData;
32  }
33 
34  namespace Math {
35 
36  class DistSamplerOptions;
37 
38 /**
39  @defgroup Random Random Classes
40 
41  Pseudo-random numbers generator classes and for generation of random number distributions.
42  These classes implement several pseudo-random number generators and method for generation of random numbers
43  according to arbitrary distributions
44 
45  @ingroup MathCore
46 
47 */
48 
49 /**
50  Interface class for generic sampling of a distribution,
51  i.e. generating random numbers according to arbitrary distributions
52 
53  @ingroup Random
54 */
55 
56 
57 class DistSampler {
58 
59 public:
60 
61  /// default constructor
62  DistSampler() : fOwnFunc(false), fRange(0), fFunc(0) {}
63 
64 
65  /// virtual destructor
66  virtual ~DistSampler();
67 
68 
69 
70  /// set the parent function distribution to use for sampling (generic case)
71  template<class Function>
72  void SetFunction(Function & func, unsigned int dim) {
73  WrappedMultiFunction<Function &> wf(func, dim);
74  fData.resize(dim);
75  // need to clone to avoid temporary
76  DoSetFunction(wf,true);
77  }
78 
79  /// set the parent function distribution to use for random sampling (one dim case)
80  virtual void SetFunction(const ROOT::Math::IGenFunction & func) {
81  SetFunction<const ROOT::Math::IGenFunction>(func, 1);
82  }
83 
84 
85  /// set the parent function distribution to use for random sampling (multi-dim case)
86  virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func) {
87  DoSetFunction(func,false);
88  }
89 
90  /// return the dimension of the parent distribution (and the data)
91  unsigned int NDim() const { return fData.size(); }
92 
93 
94  /**
95  initialize the generators with the given algorithm
96  Implemented by derived classes who needs it
97  (like UnuranSampler)
98  If nothing is specified use default algorithm
99  from DistSamplerOptions::SetDefaultAlgorithm
100  */
101  virtual bool Init(const char * =""/* algorithm */) { return true;}
102 
103  /**
104  initialize the generators with the given option
105  which my include the algorithm but also more if
106  the method is re-impelmented by derived class
107  The default implementation calls the above method
108  passing just the algorithm name
109  */
110  virtual bool Init(const DistSamplerOptions & opt );
111 
112 
113  /**
114  Set the random engine to be used
115  To be implemented by the derived classes who provides
116  random sampling
117  */
118  virtual void SetRandom(TRandom * ) {}
119 
120  /**
121  Set the random seed for the TRandom instances used by the sampler
122  classes
123  To be implemented by the derived classes who provides random sampling
124  */
125  virtual void SetSeed(unsigned int /*seed*/ ) {}
126 
127  /**
128  Get the random engine used by the sampler
129  To be implemented by the derived classes who needs it
130  Returns zero by default
131  */
132  virtual TRandom * GetRandom() { return 0; }
133 
134  /// set range in a given dimension
135  void SetRange(double xmin, double xmax, int icoord = 0);
136 
137  /// set range for all dimensions
138  void SetRange(const double * xmin, const double * xmax);
139 
140  /// set range using DataRange class
141  void SetRange(const ROOT::Fit::DataRange & range);
142 
143  /// set the mode of the distribution (could be useful to some methods)
144  /// implemented by derived classes if needed
145  virtual void SetMode(double ) {}
146 
147  /// set the normalization area of distribution
148  /// implemented by derived classes if needed
149  virtual void SetArea(double) {}
150 
151  /// get the parent distribution function (must be called after setting the function)
152  const ROOT::Math::IMultiGenFunction & ParentPdf() const {
153  return *fFunc;
154  }
155 
156 
157  /**
158  sample one event in one dimension
159  better implementation could be provided by the derived classes
160  */
161  virtual double Sample1D() {
162  Sample(&fData[0]);
163  return fData[0];
164  }
165 
166  /**
167  sample one event and rerturning array x with coordinates
168  */
169  const double * Sample() {
170  Sample(&fData[0]);
171  return &fData.front();
172  }
173 
174  /**
175  sample one event in multi-dimension by filling the given array
176  return false if sampling failed
177  */
178  virtual bool Sample(double * x) = 0;
179 
180  /**
181  sample one bin given an estimated of the pdf in the bin
182  (this can be function value at the center or its integral in the bin
183  divided by the bin width)
184  By default do not do random sample, just return the function values
185  Typically Poisson statistics will be used
186  */
187  virtual bool SampleBin(double prob, double & value, double * error = 0) {
188  value = prob;
189  if (error) *error = 0;
190  return true;
191  }
192  /**
193  sample a set of bins given a vector of probabilities
194  Typically multinomial statistics will be used and the sum of the probabilities
195  will be equal to the total number of events to be generated
196  For sampling the bins indipendently, SampleBin should be used
197  */
198  virtual bool SampleBins(unsigned int n, const double * prob, double * values, double * errors = 0) {
199  std::copy(prob,prob+n, values);
200  if (errors) std::fill(errors,errors+n,0);
201  return true;
202  }
203 
204 
205  /**
206  generate a un-binned data sets (fill the given data set)
207  if dataset has already data append to it
208  */
209  virtual bool Generate(unsigned int nevt, ROOT::Fit::UnBinData & data);
210 
211 
212  /**
213  generate a bin data set .
214  A range must have been set before (otherwise inf is returned)
215  and the bins are equidinstant in the previously defined range
216  bin center values must be present in given data set
217  If the sampler is implemented by a random one, the entries
218  will be binned according to the Poisson distribution
219  It is assumed the distribution is normalized, otherwise the nevt must be scaled
220  accordingly. The expected value/bin nexp = f(x_i) * binArea/ nevt
221  Extend control if use a fixed (i.e. multinomial statistics) or floating total number of events
222  */
223  virtual bool Generate(unsigned int nevt, const int * nbins, ROOT::Fit::BinData & data, bool extend = true);
224  /**
225  same as before but passing the range in case of 1 dim data
226  */
227  bool Generate(unsigned int nevt, int nbins, double xmin, double xmax, ROOT::Fit::BinData & data, bool extend = true) {
228  SetRange(xmin,xmax);
229  int nbs[1]; nbs[0] = nbins;
230  return Generate(nevt, nbs, data, extend);
231  }
232 
233 
234 protected:
235 
236  // internal method to set the function
237  virtual void DoSetFunction(const ROOT::Math::IMultiGenFunction & func, bool copy);
238  // check if generator have been initialized correctly and one can start generating
239  bool IsInitialized() ;
240  /// return the data range of the Pdf . Must be called after setting the function
241  const ROOT::Fit::DataRange & PdfRange() const {
242  assert(fRange);
243  return *fRange;
244  }
245 
246 
247 
248 
249 private:
250 
251  // private methods
252 
253  bool fOwnFunc; // flag to indicate if the function is owned
254  mutable std::vector<double> fData; // internal array used to cached the sample data
255  ROOT::Fit::DataRange * fRange; // data range
256  const ROOT::Math::IMultiGenFunction * fFunc; // internal function (ND)
257 
258 
259 };
260 
261  } // end namespace Math
262 
263 } // end namespace ROOT
264 
265 
266 #endif /* ROOT_Math_DistSampler */