Back to home page

EIC code displayed by LXR

 
 

    


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

0001 // @(#)root/unuran:$Id$
0002 // Author: L. Moneta Tue Sep 26 16:25:09 2006
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2006  LCG ROOT Math Team, CERN/PH-SFT                *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for class TUnuran
0012 
0013 #ifndef ROOT_TUnuran
0014 #define ROOT_TUnuran
0015 
0016 #include <string>
0017 
0018 #include "TUnuranBaseDist.h"
0019 
0020 
0021 class TUnuranContDist;
0022 class TUnuranDiscrDist;
0023 class TUnuranMultiContDist;
0024 class TUnuranEmpDist;
0025 
0026 #include <memory>
0027 
0028 
0029 /**
0030 
0031    \class TUnuran
0032    \ingroup Unuran
0033 
0034    TUnuran class.
0035    Interface to the UNU.RAN package for generating non uniform random
0036    numbers. This class wraps the UNU.RAN calls in C++ methods.
0037    It provides methods for initializing Unuran and then to sample the
0038    desired distribution.
0039    It provides support for initializing UNU.RAN in these following way (various signatures
0040    for TUnuran::Init)
0041    - with string API via TUnuran::Init passing the distribution type and the method
0042    - using a one-dimensional distribution object defined by TUnuranContDist
0043    - using a multi-dimensional distribution object defined by TUnuranMultiContDist
0044    - using a discrete one-dimensional distribution object defined by TUnuranDiscrDist
0045    - using an empirical distribution defined by TUnuranEmpDist
0046    - using pre-defined distributions. Presently only support for Poisson (TUnuran::InitPoisson)
0047      and Binomial (TUnuran::InitBinomial) are provided. Other distributions can however be generated
0048      using the previous methods (in particular via the string API)
0049 
0050    The sampling is provided via these methods:
0051     - TUnuran::Sample()   returns a double for all one-dimensional distribution
0052     - TUnuran::SampleDiscr()  returns an integer for one-dimensional discrete distribution
0053     - TUnuran::Sample(double *) sample a multi-dimensional distribution. A pointer to a vector with
0054       size at least equal to the distribution dimension must be passed
0055 
0056    In addition is possible to set the random number generator in the constructor of the class, its seed
0057    via the TUnuran::SetSeed() method.
0058 */
0059 
0060 
0061 
0062 //class TUnuranGenerator;
0063 struct unur_gen;
0064 typedef struct unur_gen UNUR_GEN;
0065 
0066 // struct unur_urng_generic;
0067 // typedef struct unur_urng_generic UNUR_URNG;
0068 
0069 struct unur_distr;
0070 typedef struct unur_distr UNUR_DISTR;
0071 
0072 struct unur_urng;
0073 typedef struct unur_urng  UNUR_URNG;
0074 
0075 
0076 class TRandom;
0077 class TH1;
0078 
0079 class TUnuran {
0080 
0081 public:
0082 
0083    /**
0084       Constructor with a generator instance and given level of log output
0085    */
0086    TUnuran (TRandom * r = nullptr, unsigned int log = 0);
0087 
0088 
0089    /**
0090       Destructor
0091    */
0092    ~TUnuran ();
0093 
0094 private:
0095    // usually copying is non trivial, so we make this unaccessible
0096 
0097    /**
0098       Copy constructor
0099    */
0100    TUnuran(const TUnuran &);
0101 
0102    /**
0103       Assignment operator
0104    */
0105    TUnuran & operator = (const TUnuran & rhs);
0106 
0107 public:
0108    /**
0109       Initialize with Unuran string API interface.
0110       See  https://statmath.wu.ac.at/unuran/doc/unuran.html#StringAPI
0111 
0112       @param distr   : UNU.RAN distribution string
0113       @param  method : UNU.RAN  method string
0114 
0115       Here is an example using the string API:
0116       ```
0117       Tunuran unr;
0118       unr.Init("normal(3.,0.75); domain = (0,inf)", "method = tdr; c = 0");
0119       ```
0120    */
0121    bool Init(const std::string & distr, const std::string  & method);
0122 
0123 
0124    /**
0125       Initialize method for continuous one-dimensional distribution.
0126       User must provide a distribution object (which is copied inside) and a string for a method.
0127       For the list of available method for 1D cont. distribution see the
0128       <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCONT">UnuRan doc</A>.
0129       A re-initialization is needed whenever distribution parameters have been changed.
0130       Note that the method string can contain in addition to the method name all the specific method
0131       parameters specified using the UNURAN method string API.
0132       For example a valid string can be `"method=arou; max_segments=1000; max_sqhratio = 0.9"`
0133    */
0134    bool Init(const TUnuranContDist & distr, const std::string & method = "auto");
0135 
0136    /**
0137       Initialize method for continuous multi-dimensional distribution.
0138       User must provide a distribution object (which is copied inside) and a string for a method.
0139       For the list of available method for multivariate cont. distribution see the
0140       <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCVEC">UnuRan doc</A>
0141       A re-initialization is needed whenever distribution parameters have been changed.
0142 
0143       The default method used for multi-dimensional distributions is "vnrou"
0144       Note that some of the multi-dimensional continuous distribution methods like "hitro" are based on Markov-CHain sampler and
0145       they are much faster for sampling but require more time to converge. Furthermore, since they are Markov-Chain methods their
0146       generated sample values are correlated and cannot be used as i.i.d., one can instead use the obtained sample distribution.
0147       (see also the ROOT issue: #10222 ).
0148 
0149    */
0150    bool Init(const TUnuranMultiContDist & distr, const std::string & method = "vnrou");
0151 
0152 
0153    /**
0154       Initialize method for continuous one-dimensional discrete distribution.
0155       User must provide a distribution object (which is copied inside) and a string for a method.
0156       For the list of available method for 1D discrete distribution see the
0157       <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fDISCR">UnuRan doc</A>
0158       A re-initialization is needed whenever distribution parameters have been changed.
0159 
0160    */
0161    bool Init(const TUnuranDiscrDist & distr, const std::string & method = "auto");
0162 
0163 
0164    /**
0165       Initialize method for continuous empirical distribution.
0166       User must provide a distribution object (which is copied inside) and a string for a method.
0167       The distribution object can represent binned (only 1D) or unbinned (1D or multi-dim) data
0168       The method for the unbinned empirical distribution are based on the kernel smoothing, see
0169       <A href="http://statmath.wu-wien.ac.at/software/unuran/doc/unuran.html#EMPK">UnuRan doc</A>
0170       A re-initialization is needed whenever distribution parameters have been changed.
0171 
0172    */
0173    bool Init(const TUnuranEmpDist & distr, const std::string & method = "empk");
0174 
0175 
0176    /**
0177       Initialize method for the Poisson distribution.
0178       Used to generate poisson numbers for a constant parameter mu of the Poisson distribution.
0179       Use after the method TUnuran::SampleDiscr to generate the numbers.
0180       The flag reinit perform a fast re-initialization when only the distribution parameters
0181       are changed in the subsequent calls.
0182       If the same TUnuran object is used to generate with other distributions it cannot be used.
0183    */
0184    bool InitPoisson(double mu, const std::string & method = "dstd");
0185 
0186    /**
0187       Initialize method for the Binomial distribution.
0188       Used to generate poisson numbers for a constant parameters (n,p) of the Binomial distribution.
0189       Use after the method TUnuran::SampleDiscr to generate the numbers.
0190       The flag reinit perform a fast re-initialization when only the distribution parameters
0191       are changed in the subsequent calls.
0192       If the same TUnuran object is used to generate with other distributions it cannot be used.
0193    */
0194    bool InitBinomial(unsigned int ntot, double prob, const std::string & method = "dstd");
0195 
0196    /**
0197       Reinitialize UNURAN by changing the distribution parameters but maintaining same distribution and method.
0198       It is implemented now only for predefined discrete distributions like the poisson or the binomial
0199    */
0200    bool ReInitDiscrDist(unsigned int npar, double * params);
0201 
0202    /**
0203       Sample 1D distribution.
0204       User is responsible for having previously correctly initialized with TUnuran::Init
0205    */
0206    double Sample();
0207 
0208    /**
0209       Sample multidimensional distributions.
0210       User is responsible for having previously correctly initialized with TUnuran::Init
0211    */
0212    bool SampleMulti(double * x);
0213 
0214    /**
0215       Sample discrete distributions.
0216       User is responsible for having previously correctly initialized with TUnuran::Init
0217    */
0218    int SampleDiscr();
0219 
0220    /**
0221       Set the random engine.
0222       Must be called before init to have effect
0223     */
0224    void SetRandom(TRandom * r) {
0225       fRng = r;
0226    }
0227 
0228    /**
0229       Return instance of the random engine used.
0230     */
0231    TRandom * GetRandom() {
0232       return fRng;
0233    }
0234 
0235    /**
0236       Return an information string about the used Unuran generator method.
0237       @param extended : if true return some helper information about the existing options of the method.
0238    */
0239    std::string GetInfo(bool extended = false);
0240 
0241    /**
0242       Return an ID string about the unuran generator method.
0243    */
0244    std::string GetGenId() const;
0245 
0246    /**
0247       Return the dimension of unuran generator method.
0248       For 1D method returns 1 and for the multi-dimensional case
0249       must be equal to the distribution dimension.
0250    */
0251    int GetDimension() const;
0252 
0253    /**
0254       Return the type of the distribution.
0255       See documentation of `unuran_distr_get_type` for the possible
0256       types of distributions.
0257    */
0258    int GetDistType() const;
0259 
0260    /// Return true for a univariate continuous distribution.
0261    bool IsDistCont() const;
0262    /// Return true for a multivariate continuous distribution.
0263    bool IsDistMultiCont() const;
0264     /// Return true for a discrete distribution.
0265    bool IsDistDiscrete() const;
0266     /// Return true for an empirical distribution.
0267    bool IsDistEmpirical() const;
0268 
0269 
0270 
0271    /**
0272       set the seed for the random number generator
0273     */
0274    void SetSeed(unsigned int seed);
0275 
0276    /**
0277       set log level
0278    */
0279    bool SetLogLevel(unsigned int iflag = 1);
0280 
0281    /**
0282       set stream for log and error (not yet implemented)
0283    */
0284    bool SetLogStream() { return false;}
0285 
0286    /**
0287       used Unuran method
0288     */
0289    const std::string & MethodName() const { return fMethod; }
0290 
0291 protected:
0292 
0293 
0294    bool SetRandomGenerator();
0295 
0296    bool SetContDistribution(const TUnuranContDist & dist );
0297 
0298    bool SetMultiDistribution(const TUnuranMultiContDist & dist );
0299 
0300    bool SetDiscreteDistribution(const TUnuranDiscrDist & dist );
0301 
0302    bool SetEmpiricalDistribution(const TUnuranEmpDist & dist );
0303 
0304    /**
0305       change the method and initialize Unuran with the previously given distribution
0306     */
0307    bool SetMethodAndInit();
0308 
0309 
0310 
0311 // private:
0312 
0313    UNUR_GEN * fGen;                      //pointer to the UnuRan C generator struct
0314    UNUR_DISTR * fUdistr;                 //pointer to the UnuRan C distribution struct
0315    UNUR_URNG  * fUrng;                   // pointer to Unuran C random generator struct
0316    std::unique_ptr<TUnuranBaseDist> fDist; // pointer for distribution wrapper
0317    TRandom * fRng;                       //pointer to ROOT random number generator
0318    std::string fMethod;                  //string representing the method
0319 
0320 };
0321 
0322 
0323 #endif /* ROOT_Math_TUnuran */