00001 // @(#)root/unuran:$Id: TUnuranContDist.h 33181 2010-04-25 10:15:08Z 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 TUnuranContDist 00012 00013 00014 #ifndef ROOT_Math_TUnuranContDist 00015 #define ROOT_Math_TUnuranContDist 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 class TF1; 00026 00027 00028 00029 //______________________________________________________________ 00030 /** 00031 TUnuranContDist class describing one dimensional continous distribution. 00032 It is used by TUnuran to generate random numbers according to this distribution via 00033 TUnuran::Sample() 00034 00035 The class can be constructed from a function (TF1) representing the probability density 00036 function of the distribution. Optionally the derivative of the pdf can also be passed. 00037 00038 It provides a method to set the domain of the distribution ( SetDomain ) which will correspond to the range 00039 of the generated random numbers. By default the domain is (-inf, + inf), indipendently of the 00040 range set in the TF1 class used to construct the distribution. 00041 00042 In addition, some UNURAN methods requires extra information (cdf function, distribution mode, 00043 area of pdf, etc...). This information can as well be set. 00044 Some methods require instead of the pdf the log of the pdf. 00045 This can also be controlled by setting a flag when constructing this class. 00046 */ 00047 /////////////////////////////////////////////////////////////////////// 00048 class TUnuranContDist : public TUnuranBaseDist { 00049 00050 public: 00051 00052 00053 /** 00054 Constructor from a TF1 objects specifying the pdf and optionally from another function 00055 representing the derivative of the pdf. The flag isLogPdf can be used to pass instead of the pdf 00056 (and its derivative) the log (and the derivative of the log) of the pdf. 00057 By default the distribution has not domain set (it is defined between [-inf,+inf], no mode, no pdf area and no 00058 cdf explicity defined. UnuRan, if needed, can compute some of this quantities, but the user if he knows them can 00059 set them in order to speed up the algorithm. For example in case of the Cdf, if the user has not set it, a numerical 00060 integration algorithm is used to estimate the Cdf from the Pdf. 00061 In case an algorithm requires only the Cdf (no Pdf), an empty distribution can be constructed and then the user must 00062 set afterwards the Cdf. 00063 */ 00064 explicit TUnuranContDist (TF1 * pdf = 0, TF1 * deriv = 0, bool isLogPdf = false ); 00065 00066 /** 00067 Constructor as before but from a generic function object interface for one-dim functions 00068 */ 00069 explicit TUnuranContDist (const ROOT::Math::IGenFunction & pdf, const ROOT::Math::IGenFunction * dpdf = 0, bool isLogPdf = false, bool copyFunc = false); 00070 00071 00072 /** 00073 Destructor 00074 */ 00075 virtual ~TUnuranContDist (); 00076 00077 00078 /** 00079 Copy constructor 00080 */ 00081 TUnuranContDist(const TUnuranContDist &); 00082 00083 /** 00084 Assignment operator 00085 */ 00086 TUnuranContDist & operator = (const TUnuranContDist & rhs); 00087 00088 /** 00089 Clone (required by base class) 00090 */ 00091 virtual TUnuranContDist * Clone() const { return new TUnuranContDist(*this); } 00092 00093 00094 /** 00095 set cdf distribution. If a method requires it 00096 and is not set it is then estimated using numerical 00097 integration from the pdf 00098 */ 00099 void SetCdf(TF1 * cdf); 00100 00101 /** 00102 set cdf distribution using a generic function interface 00103 */ 00104 void SetCdf(const ROOT::Math::IGenFunction & cdf); 00105 00106 /** 00107 Set the distribution domain. If min < max a domain is defined otherwise is undefined 00108 */ 00109 void SetDomain(double xmin, double xmax) { 00110 fXmin = xmin; 00111 fXmax = xmax; 00112 if (fXmin < fXmax) 00113 fHasDomain = true; 00114 else 00115 fHasDomain = false; 00116 } 00117 00118 /** 00119 set the distribution mode (x position of its maximum) 00120 */ 00121 void SetMode(double mode) { fMode = mode; fHasMode=true;} 00122 00123 /** 00124 set the area below the pdf 00125 */ 00126 void SetPdfArea(double area) { fArea = area; fHasArea=true;} 00127 00128 /** 00129 check if distribution has a defined domain and return in case its domain 00130 */ 00131 bool GetDomain(double & xmin, double & xmax) const { 00132 xmin = fXmin; 00133 xmax = fXmax; 00134 return fHasDomain; 00135 } 00136 00137 /** 00138 check if a cdf function is provided for the distribution 00139 */ 00140 bool HasCdf() const { return fCdf != 0; } 00141 00142 /** 00143 check if distribution has a pre-computed mode 00144 */ 00145 bool HasMode() const { return fHasMode; } 00146 00147 00148 /** 00149 check if distribution has a pre-computed area below the Pdf 00150 */ 00151 bool HasPdfArea() const { return fHasArea; } 00152 00153 /** 00154 return the mode (x location of maximum of the pdf) 00155 */ 00156 double Mode() const { return fMode; } 00157 00158 /** 00159 return area below the pdf 00160 */ 00161 double PdfArea() const { return fArea; } 00162 00163 00164 /** 00165 flag to control if given function represent the log of a pdf 00166 */ 00167 bool IsLogPdf() const { return fIsLogPdf; } 00168 00169 /** 00170 evaluate the Probability Density function. Used by the UnuRan algorithms 00171 */ 00172 double Pdf ( double x) const; 00173 00174 /** 00175 evaluate the derivative of the pdf. Used by UnuRan 00176 */ 00177 double DPdf( double x) const; 00178 00179 /** 00180 evaluate the integral (cdf) on the domain. Used by Unuran algorithm 00181 */ 00182 double Cdf(double x) const; 00183 00184 00185 protected: 00186 00187 00188 private: 00189 00190 00191 const ROOT::Math::IGenFunction * fPdf; // pointer to the pdf 00192 const ROOT::Math::IGenFunction * fDPdf; //pointer to the derivative of the pdf 00193 const ROOT::Math::IGenFunction * fCdf; //pointer to the cdf (cumulative dist.) 00194 00195 double fXmin; //lower value of the domain 00196 double fXmax; //upper value of the domain 00197 double fMode; //mode of the distribution 00198 double fArea; //area below pdf 00199 00200 // flags 00201 bool fIsLogPdf; //flag to control if function pointer represent log of pdf 00202 bool fHasDomain; //flag to control if distribution has a defined domain (otherwise is [-inf,+inf] 00203 bool fHasMode; //flag to control if distribution has a pre-computed mode 00204 bool fHasArea; //flag to control if distribution has a pre-computed area below the pdf 00205 bool fOwnFunc; // flag to indicate if class manages the function pointers 00206 //mutable double fX[1]; //! cached vector for using TF1::EvalPar 00207 00208 ClassDef(TUnuranContDist,1) //Wrapper class for one dimensional continuous distribution 00209 00210 00211 }; 00212 00213 00214 00215 #endif /* ROOT_Math_TUnuranContDist */