00001 // @(#)root/unuran:$Id: TUnuranMultiContDist.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 TUnuranMultiContDist 00012 00013 #ifndef ROOT_Math_TUnuranMultiContDist 00014 #define ROOT_Math_TUnuranMultiContDist 00015 00016 #ifndef ROOT_Math_TUnuranBaseDist 00017 #include "TUnuranBaseDist.h" 00018 #endif 00019 00020 #ifndef ROOT_Math_IFunction 00021 #include "Math/IFunction.h" 00022 #endif 00023 00024 00025 00026 #include <vector> 00027 00028 class TF1; 00029 00030 00031 //___________________________________________________________________________________________ 00032 /** 00033 TUnuranMultiContDist class describing multi dimensional continuous distributions. 00034 It is used by TUnuran to generate a set of random numbers according to this distribution via 00035 TUnuran::Sample(double *). 00036 The class can be constructed from a multi-dimensional function (TF1 pointer, which can be actually also a 00037 TF2 or a TF3). 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,...)(+inf,+inf,...)], indipendently of the 00040 range set in the TF1 class used to construct the distribution. 00041 00042 The derivatives of the pdf which are used by some UNURAN methods are estimated numerically in the 00043 Derivative() method. Some extra information (like distribution mode) can be set using SetMode. 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 ///////////////////////////////////////////////////////////// 00049 class TUnuranMultiContDist : public TUnuranBaseDist { 00050 00051 public: 00052 00053 00054 /** 00055 Constructor from a TF1 object representing the Probability density function. 00056 The derivatives of the Pdf are estimated, when required by the UNURAN algorithm, 00057 using numerical derivation. 00058 If a value of dim 0 is passed , the dimension of the function is taken from TF1::GetNdim(). 00059 This works only for 2D and 3D (for TF2 and TF3 objects). 00060 */ 00061 TUnuranMultiContDist (TF1 * func = 0, unsigned int dim = 0, bool isLogPdf = false); 00062 00063 00064 /** 00065 Constructor as before but from a generic function object interface for multi-dim functions 00066 */ 00067 TUnuranMultiContDist (const ROOT::Math::IMultiGenFunction & pdf, bool isLogPdf = false); 00068 00069 /** 00070 Destructor 00071 */ 00072 virtual ~TUnuranMultiContDist (); 00073 00074 00075 /** 00076 Copy constructor 00077 */ 00078 TUnuranMultiContDist(const TUnuranMultiContDist &); 00079 00080 /** 00081 Assignment operator 00082 */ 00083 TUnuranMultiContDist & operator = (const TUnuranMultiContDist & rhs); 00084 00085 /** 00086 Clone (required by base class) 00087 */ 00088 virtual TUnuranMultiContDist * Clone() const { return new TUnuranMultiContDist(*this); } 00089 00090 00091 /** 00092 get number of dimension of the distribution 00093 */ 00094 unsigned int NDim() const { 00095 return fPdf->NDim(); 00096 } 00097 00098 /** 00099 set the domain of the distribution giving an array of minimum and maximum values 00100 By default otherwise the domain is undefined, i.e. is [-inf,+inf] 00101 To remove the domain do a SetDomain(0,0). 00102 There is no possibility to have a domain defined in only one coordinate. Use instead inf or DOUBLE_MAX to 00103 specify un infinite domain in that coordinate 00104 */ 00105 void SetDomain(const double *xmin, const double *xmax) { 00106 if (xmin == 0 || xmax == 0) return; 00107 fXmin = std::vector<double>(xmin,xmin+NDim()); 00108 fXmax = std::vector<double>(xmax,xmax+NDim()); 00109 } 00110 00111 /** 00112 set the mode of the distribution (coordinates of the distribution maximum values) 00113 */ 00114 void SetMode(const double * x) { 00115 fMode = std::vector<double>(x,x+NDim()); 00116 } 00117 00118 /** 00119 get the distribution lower domain values. Return a null pointer if domain is not defined 00120 */ 00121 const double * GetLowerDomain() const { 00122 if (fXmin.size() == 0 || ( fXmin.size() != fXmax.size() ) ) return 0; 00123 return &fXmin[0]; 00124 } 00125 /** 00126 get the distribution upper domain values. Return a null pointer if domain is not defined 00127 */ 00128 const double * GetUpperDomain() const { 00129 if (fXmax.size() == 0 || ( fXmin.size() != fXmax.size() ) ) return 0; 00130 return &fXmax[0]; 00131 } 00132 00133 00134 /** 00135 get the mode (vector of coordinate positions of the maxima of the distribution) 00136 If a mode has not defined return a NULL pointer 00137 */ 00138 const double * GetMode( ) const { 00139 if (fMode.size() == 0 ) return 0; 00140 return &fMode.front(); 00141 } 00142 00143 00144 /** 00145 flag to control if given function represent the log of a pdf 00146 */ 00147 bool IsLogPdf() const { return fIsLogPdf; } 00148 00149 /** 00150 evaluate the probability density function, used by UnuRan 00151 */ 00152 double Pdf ( const double * x) const; 00153 00154 /** 00155 evaluate the gradient vector of the Pdf. Used by UnuRan 00156 */ 00157 void Gradient( const double * x, double * grad) const; 00158 00159 /** 00160 evaluate the partial derivative for the given coordinate. Used by UnuRan 00161 */ 00162 double Derivative( const double * x, int icoord) const; 00163 00164 00165 00166 private: 00167 00168 const ROOT::Math::IMultiGenFunction * fPdf; //pointer to the pdf 00169 00170 std::vector<double> fXmin; //vector with lower x values of the domain 00171 std::vector<double> fXmax; //vector with upper x values of the domain 00172 std::vector<double> fMode; //vector representing the x coordinates of the maximum of the pdf 00173 00174 bool fIsLogPdf; //flag to control if function pointer represent log of pdf 00175 bool fOwnFunc; // flag to indicate if class manages the function pointers 00176 00177 00178 ClassDef(TUnuranMultiContDist,1) //Wrapper class for multi dimensional continuous distribution 00179 00180 00181 }; 00182 00183 00184 00185 #endif /* ROOT_Math_TUnuranMultiContDist */