Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-09-13 09:11:52

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    // usually copying is non trivial, so we delete this
0095    TUnuran(const TUnuran &) = delete;
0096    TUnuran & operator = (const TUnuran & rhs) = delete;
0097    TUnuran(TUnuran &&) = delete;
0098    TUnuran & operator = (TUnuran && rhs) = delete;
0099 
0100    /**
0101       Initialize with Unuran string API interface.
0102       See  https://statmath.wu.ac.at/unuran/doc/unuran.html#StringAPI
0103 
0104       @param distr   : UNU.RAN distribution string
0105       @param  method : UNU.RAN  method string
0106 
0107       Here is an example using the string API:
0108       ```
0109       Tunuran unr;
0110       unr.Init("normal(3.,0.75); domain = (0,inf)", "method = tdr; c = 0");
0111       ```
0112    */
0113    bool Init(const std::string & distr, const std::string  & method);
0114 
0115 
0116    /**
0117       Initialize method for continuous one-dimensional distribution.
0118       User must provide a distribution object (which is copied inside) and a string for a method.
0119       For the list of available method for 1D cont. distribution see the
0120       <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCONT">UnuRan doc</A>.
0121       A re-initialization is needed whenever distribution parameters have been changed.
0122       Note that the method string can contain in addition to the method name all the specific method
0123       parameters specified using the UNURAN method string API.
0124       For example a valid string can be `"method=arou; max_segments=1000; max_sqhratio = 0.9"`
0125    */
0126    bool Init(const TUnuranContDist & distr, const std::string & method = "auto");
0127 
0128    /**
0129       Initialize method for continuous multi-dimensional distribution.
0130       User must provide a distribution object (which is copied inside) and a string for a method.
0131       For the list of available method for multivariate cont. distribution see the
0132       <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fCVEC">UnuRan doc</A>
0133       A re-initialization is needed whenever distribution parameters have been changed.
0134 
0135       The default method used for multi-dimensional distributions is "vnrou"
0136       Note that some of the multi-dimensional continuous distribution methods like "hitro" are based on Markov-CHain sampler and
0137       they are much faster for sampling but require more time to converge. Furthermore, since they are Markov-Chain methods their
0138       generated sample values are correlated and cannot be used as i.i.d., one can instead use the obtained sample distribution.
0139       (see also the ROOT issue: #10222 ).
0140 
0141    */
0142    bool Init(const TUnuranMultiContDist & distr, const std::string & method = "vnrou");
0143 
0144 
0145    /**
0146       Initialize method for continuous one-dimensional discrete distribution.
0147       User must provide a distribution object (which is copied inside) and a string for a method.
0148       For the list of available method for 1D discrete distribution see the
0149       <A href="http://statmath.wu-wien.ac.at/unuran/doc/unuran.html#Methods_005ffor_005fDISCR">UnuRan doc</A>
0150       A re-initialization is needed whenever distribution parameters have been changed.
0151 
0152    */
0153    bool Init(const TUnuranDiscrDist & distr, const std::string & method = "auto");
0154 
0155 
0156    /**
0157       Initialize method for continuous empirical distribution.
0158       User must provide a distribution object (which is copied inside) and a string for a method.
0159       The distribution object can represent binned (only 1D) or unbinned (1D or multi-dim) data
0160       The method for the unbinned empirical distribution are based on the kernel smoothing, see
0161       <A href="http://statmath.wu-wien.ac.at/software/unuran/doc/unuran.html#EMPK">UnuRan doc</A>
0162       A re-initialization is needed whenever distribution parameters have been changed.
0163 
0164    */
0165    bool Init(const TUnuranEmpDist & distr, const std::string & method = "empk");
0166 
0167 
0168    /**
0169       Initialize method for the Poisson distribution.
0170       Used to generate poisson numbers for a constant parameter mu of the Poisson distribution.
0171       Use after the method TUnuran::SampleDiscr to generate the numbers.
0172       The flag reinit perform a fast re-initialization when only the distribution parameters
0173       are changed in the subsequent calls.
0174       If the same TUnuran object is used to generate with other distributions it cannot be used.
0175    */
0176    bool InitPoisson(double mu, const std::string & method = "dstd");
0177 
0178    /**
0179       Initialize method for the Binomial distribution.
0180       Used to generate poisson numbers for a constant parameters (n,p) of the Binomial distribution.
0181       Use after the method TUnuran::SampleDiscr to generate the numbers.
0182       The flag reinit perform a fast re-initialization when only the distribution parameters
0183       are changed in the subsequent calls.
0184       If the same TUnuran object is used to generate with other distributions it cannot be used.
0185    */
0186    bool InitBinomial(unsigned int ntot, double prob, const std::string & method = "dstd");
0187 
0188    /**
0189       Reinitialize UNURAN by changing the distribution parameters but maintaining same distribution and method.
0190       It is implemented now only for predefined discrete distributions like the poisson or the binomial
0191    */
0192    bool ReInitDiscrDist(unsigned int npar, double * params);
0193 
0194    /**
0195       Sample 1D distribution.
0196       User is responsible for having previously correctly initialized with TUnuran::Init
0197    */
0198    double Sample();
0199 
0200    /**
0201       Sample multidimensional distributions.
0202       User is responsible for having previously correctly initialized with TUnuran::Init
0203    */
0204    bool SampleMulti(double * x);
0205 
0206    /**
0207       Sample discrete distributions.
0208       User is responsible for having previously correctly initialized with TUnuran::Init
0209    */
0210    int SampleDiscr();
0211 
0212    /**
0213       Set the random engine.
0214       Must be called before init to have effect
0215     */
0216    void SetRandom(TRandom * r) {
0217       fRng = r;
0218    }
0219 
0220    /**
0221       Return instance of the random engine used.
0222     */
0223    TRandom * GetRandom() {
0224       return fRng;
0225    }
0226 
0227    /**
0228       Return an information string about the used Unuran generator method.
0229       @param extended : if true return some helper information about the existing options of the method.
0230    */
0231    std::string GetInfo(bool extended = false);
0232 
0233    /**
0234       Return an ID string about the unuran generator method.
0235    */
0236    std::string GetGenId() const;
0237 
0238    /**
0239       Return the dimension of unuran generator method.
0240       For 1D method returns 1 and for the multi-dimensional case
0241       must be equal to the distribution dimension.
0242    */
0243    int GetDimension() const;
0244 
0245    /**
0246       Return the type of the distribution.
0247       See documentation of `unuran_distr_get_type` for the possible
0248       types of distributions.
0249    */
0250    int GetDistType() const;
0251 
0252    /// Return true for a univariate continuous distribution.
0253    bool IsDistCont() const;
0254    /// Return true for a multivariate continuous distribution.
0255    bool IsDistMultiCont() const;
0256     /// Return true for a discrete distribution.
0257    bool IsDistDiscrete() const;
0258     /// Return true for an empirical distribution.
0259    bool IsDistEmpirical() const;
0260 
0261 
0262 
0263    /**
0264       set the seed for the random number generator
0265     */
0266    void SetSeed(unsigned int seed);
0267 
0268    /**
0269       set log level
0270    */
0271    bool SetLogLevel(unsigned int iflag = 1);
0272 
0273    /**
0274       set stream for log and error (not yet implemented)
0275    */
0276    bool SetLogStream() { return false;}
0277 
0278    /**
0279       used Unuran method
0280     */
0281    const std::string & MethodName() const { return fMethod; }
0282 
0283 protected:
0284 
0285 
0286    bool SetRandomGenerator();
0287 
0288    bool SetContDistribution(const TUnuranContDist & dist );
0289 
0290    bool SetMultiDistribution(const TUnuranMultiContDist & dist );
0291 
0292    bool SetDiscreteDistribution(const TUnuranDiscrDist & dist );
0293 
0294    bool SetEmpiricalDistribution(const TUnuranEmpDist & dist );
0295 
0296    /**
0297       change the method and initialize Unuran with the previously given distribution
0298     */
0299    bool SetMethodAndInit();
0300 
0301 
0302 
0303 // private:
0304 
0305    UNUR_GEN * fGen;                      //pointer to the UnuRan C generator struct
0306    UNUR_DISTR * fUdistr;                 //pointer to the UnuRan C distribution struct
0307    UNUR_URNG  * fUrng;                   // pointer to Unuran C random generator struct
0308    std::unique_ptr<TUnuranBaseDist> fDist; // pointer for distribution wrapper
0309    TRandom * fRng;                       //pointer to ROOT random number generator
0310    std::string fMethod;                  //string representing the method
0311 
0312 };
0313 
0314 
0315 #endif /* ROOT_Math_TUnuran */