Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 10:12:31

0001 // @(#)root/unuran:$Id$
0002 // Authors: L. Moneta, J. Leydold Wed Feb 28 2007
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for class TUnuranDiscrDist
0012 
0013 
0014 #ifndef ROOT_Math_TUnuranDiscrDist
0015 #define ROOT_Math_TUnuranDiscrDist
0016 
0017 #include "TUnuranBaseDist.h"
0018 
0019 #include "Math/IFunctionfwd.h"
0020 
0021 
0022 #include <vector>
0023 
0024 
0025 class TF1;
0026 
0027 
0028 /**
0029    TUnuranDiscrDist class for one dimensional discrete distribution.
0030    It is used by TUnuran to generate integer random numbers according to this distribution via
0031    TUnuran::SampleDiscr().
0032 
0033    The class can be constructed from a one-dimensional function (TF1 pointer)
0034    representing the discrete distribution (probability mesh function)
0035    (for example a TF1("f","TMath::PoissonI(x,[0])") ) or from a
0036    vector of probability, used by passing an iterator specifying the begin and the end of the vector.
0037    In the latter case the domain of the distribution will be defined by the vector, while in the first case is by
0038    default (0,+inf).
0039    a Method to set the domain of the distribution ( SetDomain ) is provided and it defines the range
0040    of the generated random numbers.
0041 
0042    The derivatives of the pdf which are used by some UNURAN methods are estimated numerically in the
0043    Derivative() method.
0044    Some extra information (like distribution mode, cdf function, probability sum, etc..)
0045    can be set as well otherwise will be estimated internally if required.
0046 
0047    \class TUnuranDiscrDist
0048    \ingroup Unuran
0049 */
0050 
0051 class TUnuranDiscrDist : public TUnuranBaseDist {
0052 
0053 public:
0054 
0055    /**
0056       Constructor from a generic function object specifying the pdf
0057    */
0058    TUnuranDiscrDist (const ROOT::Math::IGenFunction & func, bool copyFunc = false );
0059 
0060    /**
0061       Constructor from a TF1 objects specifying the pdf
0062    */
0063    TUnuranDiscrDist (TF1 * func );
0064 
0065    /**
0066       Constructor from a vector of probability
0067    */
0068    template<class Iterator>
0069    TUnuranDiscrDist (Iterator * begin, Iterator * end) :
0070       fPVec(begin,end),
0071       fPmf(nullptr),
0072       fCdf(nullptr),
0073       fXmin(1),
0074       fXmax(-1),
0075       fMode(0),
0076       fSum(0),
0077       fHasDomain(false),
0078       fHasMode(false),
0079       fHasSum(false),
0080       fOwnFunc(false)
0081    {}
0082 
0083    /**
0084       Destructor
0085    */
0086    ~TUnuranDiscrDist () override;
0087 
0088    /**
0089       Copy constructor
0090    */
0091    TUnuranDiscrDist(const TUnuranDiscrDist &);
0092 
0093    /**
0094       Assignment operator
0095    */
0096    TUnuranDiscrDist & operator = (const TUnuranDiscrDist & rhs);
0097 
0098    /**
0099       Clone (required by base class)
0100     */
0101    TUnuranDiscrDist * Clone() const override { return new TUnuranDiscrDist(*this); }
0102 
0103    /**
0104       set cdf distribution from a generic function interface. If a method requires it
0105       and is not set it is estimated numerically
0106    */
0107    void SetCdf(const ROOT::Math::IGenFunction & cdf);
0108 
0109    /**
0110       set cdf distribution from a TF1 pointer.  If a method requires it
0111       and is not set it is estimated numerically
0112    */
0113    void SetCdf(TF1 *  cdf);
0114 
0115 
0116    /**
0117       Set the distribution domain, by default the domain is [0,INT_MAX]
0118       If xmin >= xmax a domain is removed
0119     */
0120    void SetDomain(int xmin, int xmax)  {
0121       fXmin = xmin;
0122       fXmax = xmax;
0123       if (fXmin < fXmax)
0124          fHasDomain = true;
0125       else
0126          fHasDomain = false;
0127    }
0128 
0129 
0130    /**
0131       set the mode of the distribution (location of maximum probability)
0132     */
0133    void SetMode(int mode) { fMode = mode; fHasMode=true;}
0134 
0135    /**
0136       set the value of the sum of the probabilities in the given domain
0137     */
0138    void SetProbSum(double sum) { fSum = sum; fHasSum=true; }
0139 
0140    /**
0141       check if distribution has domain and return in case its domain
0142    */
0143    bool GetDomain(int & xmin, int & xmax) const {
0144       xmin = fXmin;
0145       xmax = fXmax;
0146       return fHasDomain;
0147    }
0148 
0149    /**
0150       get the mode   (x location of function maximum)
0151    */
0152    int Mode() const { return fMode; }
0153 
0154    /**
0155       return area of the pdf
0156    */
0157    double ProbSum() const { return fSum; }
0158 
0159 
0160    /**
0161       flag to control if distribution provides the mode
0162     */
0163    bool HasMode() const { return fHasMode; }
0164 
0165 
0166    /**
0167       flag to control if distribution provides the total area of the probability function
0168     */
0169    bool HasProbSum() const { return fHasSum; }
0170 
0171    /**
0172       flag to control if distribution provides also a Cdf
0173     */
0174    bool HasCdf() const { return fCdf != nullptr; }
0175 
0176 
0177    /**
0178       retrieve a reference to the vector of the probabilities : Prob(i)
0179       If the distribution is defined from a function (i.e. for distribution with undefined domain)
0180       the vector is empty.
0181     */
0182    const std::vector<double> & ProbVec() const { return fPVec; }
0183 
0184    /**
0185       evaluate the distribution (probability mesh function) at the integer value x.
0186       Used internally by UnuRan
0187       For integer values outside the domain the function must return 0.0
0188    */
0189    double Pmf ( int x) const;
0190 
0191    /**
0192        evaluate the integral (cdf)  on the given domain
0193    */
0194    double Cdf(int x) const;
0195 
0196 
0197 protected:
0198 
0199 
0200 private:
0201 
0202    std::vector<double> fPVec;            ///< Vector of the probabilities
0203    mutable std::vector<double> fPVecSum; ///< Vector of the sum of the probabilities
0204    const ROOT::Math::IGenFunction *fPmf; ///< pointer to a function calculating the probability
0205    const ROOT::Math::IGenFunction *fCdf; ///< pointer to the cumulative distribution function
0206    int   fXmin;                  ///< lower value of the domain
0207    int   fXmax;                  ///< upper value of the domain
0208    int   fMode;                  ///< mode of the distribution
0209    double fSum;                  ///< total sum of the probabilities in the given domain
0210    // flags
0211    bool  fHasDomain;             ///< flag to control if distribution has a defined domain (otherwise is [0,INT_MAX])
0212    bool  fHasMode;               ///< flag to control if distribution has a pre-computed mode
0213    bool  fHasSum;                ///< flag to control if distribution has a pre-computed sum of the probabilities
0214    bool  fOwnFunc;               ///< flag to control if distribution owns the function pointers
0215 
0216    ClassDefOverride(TUnuranDiscrDist,1)  //Wrapper class for one dimensional discrete distribution
0217 
0218 
0219 };
0220 
0221 
0222 
0223 #endif /* ROOT_Math_TUnuranDiscrDist */