DistSampler.h

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: DistSampler.h 37371 2010-12-07 16:26:39Z moneta $
00002 // Author: L. Moneta Fri Sep 22 15:06:47 2006
00003 
00004 /**********************************************************************
00005  *                                                                    *
00006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
00007  *                                                                    *
00008  *                                                                    *
00009  **********************************************************************/
00010 
00011 // Header file for class DistSampler
00012 
00013 #ifndef ROOT_Math_DistSampler
00014 #define ROOT_Math_DistSampler
00015 
00016 #ifndef ROOT_Math_IFunctionfwd
00017 #include "Math/IFunctionfwd.h"
00018 #endif
00019 
00020 #ifndef ROOT_Math_WrappedFunction
00021 #include "Math/WrappedFunction.h"
00022 #endif
00023 
00024 #include <vector>
00025 #include <cassert>
00026 
00027 class TRandom;
00028 
00029 namespace ROOT { 
00030    
00031    namespace Fit { 
00032 
00033       class DataRange; 
00034       class BinData;
00035       class UnBinData; 
00036    }
00037 
00038    namespace Math { 
00039 
00040       class DistSamplerOptions;
00041 
00042 /**
00043    @defgroup Random Random number generators and generation of random number distributions
00044    @ingroup Random
00045 
00046    Classes implementing random number generators and classes implementing generation of random numbers 
00047    according to arbitrary distributions
00048 */
00049 
00050 //_______________________________________________________________________________
00051 /**
00052    Interface class for generic sampling of a distribution, 
00053    i.e. generating random numbers according to arbitrary distributions
00054 
00055    @ingroup Random
00056 */
00057 
00058 
00059 class DistSampler { 
00060 
00061 public: 
00062 
00063    /// default constructor 
00064    DistSampler() : fOwnFunc(false), fRange(0), fFunc(0) {}
00065 
00066 
00067    /// virtual destructor 
00068    virtual ~DistSampler();
00069 
00070 
00071 
00072    /// set the parent function distribution to use for sampling (generic case)
00073    template<class Function> 
00074    void SetFunction(Function & func, unsigned int dim) { 
00075       WrappedMultiFunction<Function &> wf(func, dim); 
00076       fData.resize(dim);
00077       // need to clone to avoid temporary
00078       DoSetFunction(wf,true);
00079    }
00080 
00081    /// set the parent function distribution to use for random sampling (one dim case)
00082    virtual void SetFunction(const ROOT::Math::IGenFunction & func)  { 
00083       SetFunction<const ROOT::Math::IGenFunction>(func, 1);
00084    }
00085 
00086 
00087    /// set the parent function distribution to use for random sampling (multi-dim case)
00088    virtual void SetFunction(const ROOT::Math::IMultiGenFunction & func)  { 
00089       DoSetFunction(func,false);
00090    }
00091 
00092    /// return the dimension of the parent distribution (and the data)
00093    unsigned int NDim() const { return fData.size(); }
00094 
00095 
00096    /**
00097       initialize the generators with the given algorithm
00098       Implemented by derived classes who needs it 
00099       (like UnuranSampler)
00100       If nothing is specified use default algorithm
00101       from DistSamplerOptions::SetDefaultAlgorithm
00102    */
00103    virtual bool Init(const char * =""/* algorithm */) { return true;}
00104 
00105    /**
00106       initialize the generators with the given option
00107       which my include the algorithm but also more if 
00108       the method is re-impelmented by derived class
00109       The default implementation calls the above method 
00110       passing just the algorithm name
00111    */
00112    virtual bool Init(const DistSamplerOptions & opt );
00113 
00114 
00115    /** 
00116        Set the random engine to be used 
00117        To be implemented by the derived classes who provides 
00118        random sampling
00119    */ 
00120    virtual void SetRandom(TRandom *  ) {}
00121 
00122    /** 
00123        Set the random seed for the TRandom instances used by the sampler 
00124        classes
00125        To be implemented by the derived classes who provides random sampling       
00126    */ 
00127    virtual void SetSeed(unsigned int /*seed*/ ) {}
00128 
00129    /**
00130       Get the random engine used by the sampler
00131       To be implemented by the derived classes who needs it
00132       Returns zero by default
00133     */
00134    virtual TRandom * GetRandom() { return 0; }
00135  
00136    /// set range in a given dimension 
00137    void SetRange(double xmin, double xmax, int icoord = 0); 
00138 
00139    /// set range for all dimensions
00140    void SetRange(const double * xmin, const double * xmax); 
00141 
00142    /// set range using DataRange class 
00143    void SetRange(const ROOT::Fit::DataRange & range); 
00144 
00145    /// set the mode of the distribution (could be useful to some methods)
00146    /// implemented by derived classes if needed
00147    virtual void SetMode(double  ) {}
00148 
00149    /// set the normalization area of distribution 
00150    /// implemented by derived classes if needed
00151    virtual void SetArea(double) {}
00152 
00153    /// get the parent distribution function (must be called after setting the function) 
00154    const ROOT::Math::IMultiGenFunction & ParentPdf() const { 
00155       return *fFunc;
00156    }
00157 
00158 
00159    /**
00160       sample one event in one dimension
00161       better implementation could be provided by the derived classes   
00162    */
00163    virtual double Sample1D() { 
00164       Sample(&fData[0]);
00165       return fData[0];
00166    }
00167 
00168    /**
00169       sample one event and rerturning array x with coordinates
00170     */
00171    const double *  Sample() { 
00172       Sample(&fData[0]);
00173       return &fData.front();
00174    }
00175 
00176    /**
00177       sample one event in multi-dimension by filling the given array
00178       return false if sampling failed
00179    */
00180    virtual bool Sample(double * x) = 0; 
00181 
00182    /**
00183       sample one bin given an estimated of the pdf in the bin
00184       (this can be function value at the center or its integral in the bin 
00185       divided by the bin width)
00186       By default do not do random sample, just return the function values
00187       Typically Poisson statistics will be used 
00188     */
00189    virtual bool SampleBin(double prob, double & value, double * error = 0) {
00190       value = prob; 
00191       if (error) *error = 0; 
00192       return true; 
00193    }
00194    /**
00195       sample a set of bins given a vector of probabilities
00196       Typically multinomial statistics will be used and the sum of the probabilities 
00197       will be equal to the total number of events to be generated
00198       For sampling the bins indipendently, SampleBin should be used
00199     */
00200    virtual bool SampleBins(unsigned int n, const double * prob, double * values, double * errors  = 0)  {
00201       std::copy(prob,prob+n, values);
00202       if (errors) std::fill(errors,errors+n,0);
00203       return true; 
00204    }
00205 
00206 
00207    /**
00208       generate a un-binned data sets (fill the given data set)
00209       if dataset has already data append to it
00210    */ 
00211    virtual bool Generate(unsigned int nevt, ROOT::Fit::UnBinData & data);  
00212 
00213 
00214    /**
00215       generate a bin data set . 
00216       A range must have been set before (otherwise inf is returned) 
00217       and the bins are equidinstant in the previously defined range
00218       bin center values must be present in given data set
00219       If the sampler is implemented by a random one, the entries 
00220       will be binned according to the Poisson distribution
00221       It is assumed the distribution is normalized, otherwise the nevt must be scaled 
00222       accordingly. The expected value/bin nexp  = f(x_i) * binArea/ nevt
00223       Extend control if use a fixed (i.e. multinomial statistics) or floating total number of events  
00224    */ 
00225    virtual bool Generate(unsigned int nevt, const  int * nbins, ROOT::Fit::BinData & data, bool extend = true);
00226    /**
00227       same as before but passing the range in case of 1 dim data
00228     */
00229    bool Generate(unsigned int nevt, int nbins, double xmin, double xmax, ROOT::Fit::BinData & data, bool extend = true) { 
00230       SetRange(xmin,xmax); 
00231       int nbs[1]; nbs[0] = nbins;
00232       return Generate(nevt, nbs, data, extend); 
00233    }
00234 
00235 
00236 protected: 
00237 
00238    // internal method to set the function 
00239    virtual void DoSetFunction(const ROOT::Math::IMultiGenFunction & func, bool copy);
00240    // check if generator have been initialized correctly and one can start generating
00241    bool IsInitialized() ; 
00242    /// return the data range of the Pdf . Must be called after setting the function
00243    const ROOT::Fit::DataRange & PdfRange() const { 
00244       assert(fRange);
00245       return *fRange; 
00246    }
00247    
00248 
00249    
00250    
00251 private: 
00252 
00253    // private methods
00254 
00255    bool fOwnFunc;                         // flag to indicate if the function is owned
00256    mutable std::vector<double> fData;     // internal array used to cached the sample data 
00257    ROOT::Fit::DataRange    *   fRange;    // data range 
00258    const ROOT::Math::IMultiGenFunction * fFunc; // internal function (ND)
00259 
00260 
00261 };
00262 
00263    } // end namespace Math
00264 
00265 } // end namespace ROOT
00266 
00267 
00268 #endif /* ROOT_Math_DistSampler */

Generated on Tue Jul 5 14:25:12 2011 for ROOT_528-00b_version by  doxygen 1.5.1