|
||||
File indexing completed on 2025-01-18 10:10:16
0001 // @(#)root/mathcore:$Id$ 0002 // Author: L. Moneta Fri Sep 22 15:06:47 2006 0003 0004 /********************************************************************** 0005 * * 0006 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * 0007 * * 0008 * * 0009 **********************************************************************/ 0010 0011 // Header file for class DistSampler 0012 0013 #ifndef ROOT_Math_DistSampler 0014 #define ROOT_Math_DistSampler 0015 0016 #include "Math/IFunctionfwd.h" 0017 0018 #include "Math/WrappedFunction.h" 0019 0020 #include <vector> 0021 #include <cassert> 0022 0023 class TRandom; 0024 0025 namespace ROOT { 0026 0027 namespace Fit { 0028 0029 class DataRange; 0030 class BinData; 0031 class UnBinData; 0032 } 0033 0034 namespace Math { 0035 0036 class DistSamplerOptions; 0037 0038 /** 0039 @defgroup Random Interface classes for Random number generation 0040 0041 Pseudo-random numbers generator classes and for generation of random number distributions. 0042 These classes implement several pseudo-random number generators and method for generation of random numbers 0043 according to arbitrary distributions 0044 0045 @ingroup MathCore 0046 0047 */ 0048 0049 /** 0050 Interface class for generic sampling of a distribution, 0051 i.e. generating random numbers according to arbitrary distributions 0052 0053 @ingroup Random 0054 */ 0055 0056 0057 class DistSampler { 0058 0059 public: 0060 0061 /// default constructor 0062 DistSampler() : fOwnFunc(false), fRange(nullptr), fFunc(nullptr) {} 0063 0064 0065 /// virtual destructor 0066 virtual ~DistSampler(); 0067 0068 0069 0070 /// set the parent function distribution to use for sampling (generic case) 0071 template<class Function> 0072 void SetFunction(Function & func, unsigned int dim) { 0073 WrappedMultiFunction<Function &> wf(func, dim); 0074 fData.resize(dim); 0075 // need to clone to avoid temporary 0076 DoSetFunction(wf,true); 0077 } 0078 0079 /// set the parent function distribution to use for random sampling (one dim case) 0080 virtual void SetFunction(const ROOT::Math::IGenFunction & func) { 0081 SetFunction<const ROOT::Math::IGenFunction>(func, 1); 0082 } 0083 0084 0085 /// set the parent function distribution to use for random sampling (multi-dim case) 0086 virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func) { 0087 DoSetFunction(func,false); 0088 } 0089 0090 /// return the dimension of the parent distribution (and the data) 0091 unsigned int NDim() const { return fData.size(); } 0092 0093 0094 /** 0095 Initialize the sampling generator with the given algorithm. 0096 Implemented by the derived classes who needs it 0097 (like UnuranSampler). 0098 If nothing is specified use default algorithm 0099 from DistSamplerOptions::SetDefaultAlgorithm 0100 */ 0101 virtual bool Init(const char * =""/* algorithm */) { return true;} 0102 0103 /** 0104 Initialize the generators with the given DistSamplerOption object. 0105 The string will include the algorithm and in case additional options 0106 which can be interpreted by a re-implemented method in the derived class. 0107 The default implementation just calls the above method 0108 passing just the algorithm name 0109 */ 0110 virtual bool Init(const DistSamplerOptions & opt ); 0111 0112 0113 /** 0114 Set the random engine to be used. 0115 To be implemented by the derived classes who provides 0116 random sampling 0117 */ 0118 virtual void SetRandom(TRandom * ) {} 0119 0120 /** 0121 Set the random seed for the TRandom instances used by the sampler 0122 classes. 0123 To be implemented by the derived classes who provides random sampling 0124 */ 0125 virtual void SetSeed(unsigned int /*seed*/ ) {} 0126 0127 /** 0128 Get the random engine used by the sampler. 0129 To be implemented by the derived classes who needs it 0130 Returns zero by default 0131 */ 0132 virtual TRandom * GetRandom() { return nullptr; } 0133 0134 /// Set the range in a given dimension. 0135 void SetRange(double xmin, double xmax, int icoord = 0); 0136 0137 /// Set the range for all dimensions. 0138 void SetRange(const double * xmin, const double * xmax); 0139 /// Set the range for all dimensions (use std::vector) 0140 void SetRange(const std::vector<double> & xmin, const std::vector<double> & xmax){ 0141 assert(xmin.size() >= NDim() && xmax.size() >= NDim()); 0142 SetRange(xmin.data(),xmax.data()); 0143 } 0144 0145 /// Set the range using the ROOT::Fit::DataRange class. 0146 void SetRange(const ROOT::Fit::DataRange & range); 0147 0148 /// Set the mode of the distribution (1D case). 0149 /// It could be useful or needed by some sampling methods. 0150 /// It is implemented by derived classes if needed (e.g. TUnuranSampler) 0151 virtual void SetMode(double ) {} 0152 0153 /// Set the mode of the distribution (Multi-dim case). 0154 virtual void SetMode(const std::vector<double> &) {} 0155 0156 /// Set the normalization area of distribution. 0157 /// Implemented by derived classes if needed 0158 virtual void SetArea(double) {} 0159 0160 /// Use the log of the provided pdf. 0161 /// Implemented by the derived classes 0162 virtual void SetUseLogPdf(bool = true) {} 0163 0164 /// Set usage of Derivative of PDF. 0165 /// Can be implemented by derived class 0166 virtual void SetDPdf(const ROOT::Math::IGenFunction & ) {} 0167 0168 /// Set usage of Cumulative of PDF. 0169 /// Can be implemented by derived class 0170 virtual void SetCdf(const ROOT::Math::IGenFunction &) {} 0171 0172 /// Get the parent distribution function (must be called after setting the function). 0173 const ROOT::Math::IMultiGenFunction & ParentPdf() const { 0174 return *fFunc; 0175 } 0176 0177 /// Check if there is a parent distribution defined. 0178 bool HasParentPdf() const { return fFunc != nullptr; } 0179 0180 /** 0181 Sample one event in one dimension. 0182 Specialized implementation could be provided by the derived classes 0183 */ 0184 virtual double Sample1D() { 0185 Sample(&fData[0]); 0186 return fData[0]; 0187 } 0188 0189 /** 0190 Sample one event and return an array x with 0191 sample coordinates values. 0192 */ 0193 const double * Sample() { 0194 Sample(&fData[0]); 0195 return &fData.front(); 0196 } 0197 0198 /** 0199 Sample one event in multi-dimension by filling the given array. 0200 Return false if the sampling failed. 0201 Abstract method to be re-implemented by the derived classes 0202 */ 0203 virtual bool Sample(double * x) = 0; 0204 0205 /** 0206 Sample one bin given an estimate of the pdf in the bin. 0207 (this can be function value at the center or its integral in the bin 0208 divided by the bin width) 0209 By default do not do random sample, just return the function values 0210 Typically Poisson statistics will be used 0211 */ 0212 virtual bool SampleBin(double prob, double & value, double * error = nullptr) { 0213 value = prob; 0214 if (error) *error = 0; 0215 return true; 0216 } 0217 /** 0218 Sample a set of bins given a vector of probabilities 0219 Typically multinomial statistics will be used and the sum of the probabilities 0220 will be equal to the total number of events to be generated 0221 For sampling the bins independently, SampleBin should be used 0222 */ 0223 virtual bool SampleBins(unsigned int n, const double * prob, double * values, double * errors = nullptr) { 0224 std::copy(prob,prob+n, values); // default impl returns prob values (Asimov data) 0225 if (errors) std::fill(errors,errors+n,0); 0226 return true; 0227 } 0228 0229 0230 /** 0231 Generate a un-binned data set by filling the given data set object. 0232 If the data set object is not empty, the new generated data will be appended to the 0233 existing one. 0234 */ 0235 virtual bool Generate(unsigned int nevt, ROOT::Fit::UnBinData & data); 0236 /** 0237 Generate a vector of events by filling the passed data vector. 0238 The flag eventRow indicates how the events are arranged in the multi-dim case. 0239 The can be arranged in rows or in columns. 0240 With eventRow=false events are the columns in data: {x1,x2,.....,xn},{y1,....yn} 0241 With eventRow=true events are rows in data: {x1,y1},{x2,y2},.....{xn,yn} 0242 */ 0243 virtual bool Generate(unsigned int nevt, double * data, bool eventRow = false); 0244 0245 /** 0246 Generate a binned data set. 0247 A range must have been set before (otherwise inf is returned) 0248 and the bins are equidistant in the previously defined range 0249 bin center values must be present in given data set 0250 If the sampler is implemented by a random one, the entries 0251 will be binned according to the Poisson distribution 0252 It is assumed the distribution is normalized, otherwise the nevt must be scaled 0253 accordingly. The expected value/bin nexp = f(x_i) * binArea/ nevt 0254 Extend control if use a fixed (i.e. multinomial statistics) or floating total number of events 0255 */ 0256 virtual bool Generate(unsigned int nevt, const int * nbins, ROOT::Fit::BinData & data, bool extend = true, bool expErr = true); 0257 /** 0258 Same as before but passing the range in case of 1 dim data. 0259 */ 0260 bool Generate(unsigned int nevt, int nbins, double xmin, double xmax, ROOT::Fit::BinData & data, bool extend = true, bool expErr = true ) { 0261 SetRange(xmin,xmax); 0262 int nbs[1]; nbs[0] = nbins; 0263 return Generate(nevt, nbs, data, extend, expErr); 0264 } 0265 0266 0267 protected: 0268 0269 // internal method to set the function 0270 virtual void DoSetFunction(const ROOT::Math::IMultiGenFunction & func, bool copy); 0271 // internal method to set the dimension 0272 virtual void DoSetDimension(unsigned int ndim); 0273 // check if generator have been initialized correctly and one can start generating 0274 bool IsInitialized() ; 0275 /// return the data range of the Pdf . Must be called after setting the function 0276 const ROOT::Fit::DataRange & PdfRange() const { 0277 assert(fRange); 0278 return *fRange; 0279 } 0280 0281 private: 0282 0283 // private methods 0284 0285 bool fOwnFunc; ///< flag to indicate if the function is owned 0286 mutable std::vector<double> fData; ///<! internal array used to cached the sample data 0287 ROOT::Fit::DataRange * fRange; ///< data range 0288 const ROOT::Math::IMultiGenFunction * fFunc; ///< internal function (ND) 0289 0290 0291 }; 0292 0293 } // end namespace Math 0294 0295 } // end namespace ROOT 0296 0297 0298 #endif /* ROOT_Math_DistSampler */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.3.7 LXR engine. The LXR team |