00001 // @(#)root/unuran:$Id: TUnuranDiscrDist.h 34077 2010-06-23 10:09:18Z moneta $ 00002 // Authors: L. Moneta, J. Leydold Wed Feb 28 2007 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * 00007 * * 00008 * * 00009 **********************************************************************/ 00010 00011 // Header file for class TUnuranDiscrDist 00012 00013 00014 #ifndef ROOT_Math_TUnuranDiscrDist 00015 #define ROOT_Math_TUnuranDiscrDist 00016 00017 #ifndef ROOT_Math_TUnuranBaseDist 00018 #include "TUnuranBaseDist.h" 00019 #endif 00020 00021 #ifndef ROOT_Math_IFunctionfwd 00022 #include "Math/IFunctionfwd.h" 00023 #endif 00024 00025 00026 #include <vector> 00027 00028 00029 class TF1; 00030 00031 //____________________________________________________________________ 00032 /** 00033 TUnuranDiscrDist class for one dimensional discrete distribution. 00034 It is used by TUnuran to generate integer random numbers according to this distribution via 00035 TUnuran::SampleDiscr(). 00036 00037 The class can be constructed from a one-dimensional function (TF1 pointer) 00038 representing the discrete distribution (probability mesh function) 00039 (for example a TF1("f","TMath::PoissonI(x,[0])") ) or from a 00040 vector of probability, used by passing an iterator specifying the begin and the end of the vector. 00041 In the latter case the domain of the distribution will be defined by the vector, while in the first case is by 00042 default (0,+inf). 00043 a Method to set the domain of the distribution ( SetDomain ) is provided and it defines the range 00044 of the generated random numbers. 00045 00046 The derivatives of the pdf which are used by some UNURAN methods are estimated numerically in the 00047 Derivative() method. 00048 Some extra information (like distribution mode, cdf function, probability sum, etc..) 00049 can be set as well otherwise will be estimated internally if required. 00050 00051 00052 */ 00053 class TUnuranDiscrDist : public TUnuranBaseDist { 00054 00055 public: 00056 00057 /** 00058 Constructor from a generic function object specifying the pdf 00059 */ 00060 TUnuranDiscrDist (const ROOT::Math::IGenFunction & func, bool copyFunc = false ); 00061 00062 /** 00063 Constructor from a TF1 objects specifying the pdf 00064 */ 00065 TUnuranDiscrDist (TF1 * func ); 00066 00067 /** 00068 Constructor from a vector of probability 00069 */ 00070 template<class Iterator> 00071 TUnuranDiscrDist (Iterator * begin, Iterator * end) : 00072 fPVec(begin,end), 00073 fPmf(0), 00074 fCdf(0), 00075 fXmin(1), 00076 fXmax(-1), 00077 fMode(0), 00078 fSum(0), 00079 fHasDomain(0), 00080 fHasMode(0), 00081 fHasSum(0), 00082 fOwnFunc(false) 00083 {} 00084 00085 /** 00086 Destructor 00087 */ 00088 virtual ~TUnuranDiscrDist (); 00089 00090 /** 00091 Copy constructor 00092 */ 00093 TUnuranDiscrDist(const TUnuranDiscrDist &); 00094 00095 /** 00096 Assignment operator 00097 */ 00098 TUnuranDiscrDist & operator = (const TUnuranDiscrDist & rhs); 00099 00100 /** 00101 Clone (required by base class) 00102 */ 00103 virtual TUnuranDiscrDist * Clone() const { return new TUnuranDiscrDist(*this); } 00104 00105 /** 00106 set cdf distribution from a generic function interface. If a method requires it 00107 and is not set it is estimated numerically 00108 */ 00109 void SetCdf(const ROOT::Math::IGenFunction & cdf); 00110 00111 /** 00112 set cdf distribution from a TF1 pointer. If a method requires it 00113 and is not set it is estimated numerically 00114 */ 00115 void SetCdf(TF1 * cdf); 00116 00117 00118 /** 00119 Set the distribution domain, by default the domain is [0,INT_MAX] 00120 If xmin >= xmax a domain is removed 00121 */ 00122 void SetDomain(int xmin, int xmax) { 00123 fXmin = xmin; 00124 fXmax = xmax; 00125 if (fXmin < fXmax) 00126 fHasDomain = true; 00127 else 00128 fHasDomain = false; 00129 } 00130 00131 00132 /** 00133 set the mode of the distribution (location of maximum probability) 00134 */ 00135 void SetMode(int mode) { fMode = mode; fHasMode=true;} 00136 00137 /** 00138 set the value of the sum of the probabilities in the given domain 00139 */ 00140 void SetProbSum(double sum) { fSum = sum; fHasSum=true; } 00141 00142 /** 00143 check if distribution has domain and return in case its domain 00144 */ 00145 bool GetDomain(int & xmin, int & xmax) const { 00146 xmin = fXmin; 00147 xmax = fXmax; 00148 return fHasDomain; 00149 } 00150 00151 /** 00152 get the mode (x location of function maximum) 00153 */ 00154 int Mode() const { return fMode; } 00155 00156 /** 00157 return area of the pdf 00158 */ 00159 double ProbSum() const { return fSum; } 00160 00161 00162 /** 00163 flag to control if distribution provides the mode 00164 */ 00165 bool HasMode() const { return fHasMode; } 00166 00167 00168 /** 00169 flag to control if distribution provides the total area of the probability function 00170 */ 00171 bool HasProbSum() const { return fHasSum; } 00172 00173 /** 00174 flag to control if distribution provides also a Cdf 00175 */ 00176 bool HasCdf() const { return fCdf != 0; } 00177 00178 00179 /** 00180 retrieve a reference to the vector of the probabilities : Prob(i) 00181 If the distribution is defined from a function (i.e. for distribution with undefined domain) 00182 the vector is empty. 00183 */ 00184 const std::vector<double> & ProbVec() const { return fPVec; } 00185 00186 /** 00187 evaluate the distribution (probability mesh function) at the integer value x. 00188 Used internally by UnuRan 00189 For integer values outside the domain the function must return 0.0 00190 */ 00191 double Pmf ( int x) const; 00192 00193 /** 00194 evaluate the integral (cdf) on the given domain 00195 */ 00196 double Cdf(int x) const; 00197 00198 00199 protected: 00200 00201 00202 private: 00203 00204 std::vector<double> fPVec; //Vector of the probabilities 00205 mutable std::vector<double> fPVecSum; //Vector of the sum of the probabilities 00206 const ROOT::Math::IGenFunction *fPmf; //pointer to a function calculating the probability 00207 const ROOT::Math::IGenFunction *fCdf; //pointer to the cumulative distribution function 00208 int fXmin; //lower value of the domain 00209 int fXmax; //upper value of the domain 00210 int fMode; //mode of the distribution 00211 double fSum; //total sum of the probabilities in the given domain 00212 // flags 00213 bool fHasDomain; //flag to control if distribution has a defined domain (otherwise is [0,INT_MAX]) 00214 bool fHasMode; //flag to control if distribution has a pre-computed mode 00215 bool fHasSum; //flag to control if distribution has a pre-computed sum of the probabilities 00216 bool fOwnFunc; // flag to control if distribution owns the funcitno pointers 00217 00218 ClassDef(TUnuranDiscrDist,1) //Wrapper class for one dimensional discrete distribution 00219 00220 00221 }; 00222 00223 00224 00225 #endif /* ROOT_Math_TUnuranDiscrDist */