00001 // @(#)root/unuran:$Id: TUnuran.h 36306 2010-10-11 18:55:19Z moneta $ 00002 // Author: L. Moneta Tue Sep 26 16:25:09 2006 00003 00004 /********************************************************************** 00005 * * 00006 * Copyright (c) 2006 LCG ROOT Math Team, CERN/PH-SFT * 00007 * * 00008 * * 00009 **********************************************************************/ 00010 00011 // Header file for class TUnuran 00012 00013 #ifndef ROOT_TUnuran 00014 #define ROOT_TUnuran 00015 00016 #include <string> 00017 00018 #ifndef ROOT_Math_TUnuranBaseDist 00019 #include "TUnuranBaseDist.h" 00020 #endif 00021 00022 00023 class TUnuranContDist; 00024 class TUnuranDiscrDist; 00025 class TUnuranMultiContDist; 00026 class TUnuranEmpDist; 00027 00028 #include <memory> 00029 00030 //______________________________________________________________________ 00031 /** 00032 TUnuran class. 00033 Interface to the UNU.RAN package for generating non uniform random 00034 numbers. This class wraps the UNU.RAN calls in C++ methods. 00035 It provides methods for initializing Unuran and then to sample the 00036 desired distribution. 00037 It provides support for initializing UNU.RAN in these following way (various signatures 00038 for TUnuran::Init) 00039 - with string API via TUnuran::Init passing the distribution type and the method 00040 - using a one-dimensional distribution object defined by TUnuranContDist 00041 - using a multi-dimensional distribution object defined by TUnuranMultiContDist 00042 - using a discrete one-dimensional distribution object defined by TUnuranDiscrDist 00043 - using an empirical distribution defined by TUnuranEmpDist 00044 - using pre-defined distributions. Presently only support for Poisson (TUnuran::InitPoisson) 00045 and Binomial (TUnuran::InitBinomial) are provided. Other distributions can however be generated 00046 using the previous methods (in particular via the string API) 00047 00048 The sampling is provided via these methods: 00049 - TUnuran::Sample() returns a double for all one-dimensional distribution 00050 - TUnuran::SampleDiscr() returns an integer for one-dimensional discrete distribution 00051 - TUnuran::Sample(double *) sample a multi-dimensional distribution. A pointer to a vector with 00052 size at least equal to the distribution dimension must be passed 00053 00054 In addition is possible to set the random number generator in the constructor of the class, its seed 00055 via the TUnuran::SetSeed() method. 00056 */ 00057 /////////////////////////////////////////////////////////////////////// 00058 00059 00060 //class TUnuranGenerator; 00061 struct unur_gen; 00062 typedef struct unur_gen UNUR_GEN; 00063 00064 // struct unur_urng_generic; 00065 // typedef struct unur_urng_generic UNUR_URNG; 00066 00067 struct unur_distr; 00068 typedef struct unur_distr UNUR_DISTR; 00069 00070 struct unur_urng; 00071 typedef struct unur_urng UNUR_URNG; 00072 00073 00074 class TRandom; 00075 class TH1; 00076 00077 class TUnuran { 00078 00079 public: 00080 00081 /** 00082 Constructor with a generator instance and given level of log output 00083 */ 00084 TUnuran (TRandom * r = 0, unsigned int log = 0); 00085 00086 00087 /** 00088 Destructor 00089 */ 00090 ~TUnuran (); 00091 00092 private: 00093 // usually copying is non trivial, so we make this unaccessible 00094 00095 /** 00096 Copy constructor 00097 */ 00098 TUnuran(const TUnuran &); 00099 00100 /** 00101 Assignment operator 00102 */ 00103 TUnuran & operator = (const TUnuran & rhs); 00104 00105 public: 00106 00107 00108 /** 00109 initialize with Unuran string interface 00110 */ 00111 bool Init(const std::string & distr, const std::string & method); 00112 00113 00114 /** 00115 Initialize method for continuous one-dimensional distribution. 00116 User must provide a distribution object (which is copied inside) and a string for a method. 00117 For the list of available method for 1D cont. distribution see the 00118 <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCONT">UnuRan doc</A>. 00119 A re-initialization is needed whenever distribution parameters have been changed. 00120 */ 00121 bool Init(const TUnuranContDist & distr, const std::string & method = "auto"); 00122 00123 /** 00124 Initialize method for continuous multi-dimensional distribution. 00125 User must provide a distribution object (which is copied inside) and a string for a method. 00126 For the list of available method for multivariate cont. distribution see the 00127 <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCVEC">UnuRan doc</A> 00128 A re-initialization is needed whenever distribution parameters have been changed. 00129 00130 */ 00131 bool Init(const TUnuranMultiContDist & distr, const std::string & method = "hitro"); 00132 00133 00134 /** 00135 Initialize method for continuous one-dimensional discrete distribution. 00136 User must provide a distribution object (which is copied inside) and a string for a method. 00137 For the list of available method for 1D discrete distribution see the 00138 <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fDISCR">UnuRan doc</A> 00139 A re-initialization is needed whenever distribution parameters have been changed. 00140 00141 */ 00142 bool Init(const TUnuranDiscrDist & distr, const std::string & method = "auto"); 00143 00144 00145 /** 00146 Initialize method for continuous empirical distribution. 00147 User must provide a distribution object (which is copied inside) and a string for a method. 00148 The distribution object can represent binned (only 1D) or unbinned (1D or multi-dim) data 00149 The method for the unbinned empirical distribution are based on the kernel smoothing, see 00150 <A href="http://statmath.wu-wien.ac.at/software/unuran/doc/unuran.html#EMPK">UnuRan doc</A> 00151 A re-initialization is needed whenever distribution parameters have been changed. 00152 00153 */ 00154 bool Init(const TUnuranEmpDist & distr, const std::string & method = "empk"); 00155 00156 00157 /** 00158 Initialize method for the Poisson distribution 00159 Used to generate poisson numbers for a constant parameter mu of the Poisson distribution. 00160 Use after the method TUnuran::SampleDiscr to generate the numbers. 00161 The flag reinit perform a fast re-initialization when only the distribution parameters 00162 are changed in the subsequent calls. 00163 If the same TUnuran object is used to generate with other distributions it cannot be used. 00164 */ 00165 bool InitPoisson(double mu, const std::string & method = "dstd"); 00166 00167 /** 00168 Initialize method for the Binomial distribution 00169 Used to generate poisson numbers for a constant parameters (n,p) of the Binomial distribution. 00170 Use after the method TUnuran::SampleDiscr to generate the numbers. 00171 The flag reinit perform a fast re-initialization when only the distribution parameters 00172 are changed in the subsequent calls. 00173 If the same TUnuran object is used to generate with other distributions it cannot be used. 00174 */ 00175 bool InitBinomial(unsigned int ntot, double prob, const std::string & method = "dstd"); 00176 00177 /** 00178 Reinitialize UNURAN by changing the distribution parameters but mantaining same distribution and method 00179 It is implemented now only for predefined discrete distributions like the poisson or the binomial 00180 */ 00181 bool ReInitDiscrDist(unsigned int npar, double * params); 00182 00183 /** 00184 Sample 1D distribution 00185 User is responsible for having previously correctly initialized with TUnuran::Init 00186 */ 00187 double Sample(); 00188 00189 /** 00190 Sample multidimensional distributions 00191 User is responsible for having previously correctly initialized with TUnuran::Init 00192 */ 00193 bool SampleMulti(double * x); 00194 00195 /** 00196 Sample discrete distributions 00197 User is responsible for having previously correctly initialized with TUnuran::Init 00198 */ 00199 int SampleDiscr(); 00200 00201 /** 00202 set the random engine. 00203 Must be called before init to have effect 00204 */ 00205 void SetRandom(TRandom * r) { 00206 fRng = r; 00207 } 00208 00209 /** 00210 return instance of the random engine used 00211 */ 00212 TRandom * GetRandom() { 00213 return fRng; 00214 } 00215 00216 00217 /** 00218 set the seed for the random number generator 00219 */ 00220 void SetSeed(unsigned int seed); 00221 00222 /** 00223 set log level 00224 */ 00225 bool SetLogLevel(unsigned int iflag = 1); 00226 00227 /** 00228 set stream for log and error (not yet implemented) 00229 */ 00230 bool SetLogStream() { return false;} 00231 00232 /** 00233 used Unuran method 00234 */ 00235 const std::string & MethodName() const { return fMethod; } 00236 00237 protected: 00238 00239 00240 bool SetRandomGenerator(); 00241 00242 bool SetContDistribution(const TUnuranContDist & dist ); 00243 00244 bool SetMultiDistribution(const TUnuranMultiContDist & dist ); 00245 00246 bool SetDiscreteDistribution(const TUnuranDiscrDist & dist ); 00247 00248 bool SetEmpiricalDistribution(const TUnuranEmpDist & dist ); 00249 00250 /** 00251 change the method and initialize Unuran with the previously given distribution 00252 */ 00253 bool SetMethodAndInit(); 00254 00255 00256 00257 // private: 00258 00259 UNUR_GEN * fGen; //pointer to the UnuRan C generator struct 00260 UNUR_DISTR * fUdistr; //pointer to the UnuRan C distribution struct 00261 UNUR_URNG * fUrng; // pointer to Unuran C random generator struct 00262 std::auto_ptr<TUnuranBaseDist> fDist; // pointer for distribution wrapper 00263 TRandom * fRng; //pointer to ROOT random number generator 00264 std::string fMethod; //string representing the method 00265 00266 }; 00267 00268 00269 #endif /* ROOT_Math_TUnuran */