Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-30 10:22:08

0001 // @(#)root/mathcore:$Id$
0002 // Authors: L. Moneta    8/2015
0003 
0004 /**********************************************************************
0005  *                                                                    *
0006  * Copyright (c) 2015 , ROOT MathLib Team                             *
0007  *                                                                    *
0008  *                                                                    *
0009  **********************************************************************/
0010 
0011 // Header file for random class
0012 //
0013 //
0014 // Created by: Lorenzo Moneta  : Tue 4 Aug 2015
0015 //
0016 //
0017 #ifndef ROOT_Math_RandomFunctions
0018 #define ROOT_Math_RandomFunctions
0019 
0020 
0021 #include <type_traits>
0022 #include <cmath>
0023 #include "RtypesCore.h"
0024 #include "TMath.h"
0025 #include <cassert>
0026 #include <vector>
0027 
0028 #include "TRandomEngine.h"
0029 
0030 
0031 namespace ROOT {
0032 namespace Math {
0033 
0034 
0035 //___________________________________________________________________________________
0036 
0037 
0038    // class DefaultEngineType {};
0039 
0040 
0041    /**
0042        Documentation for the RandomFunction class
0043 
0044        @ingroup  Random
0045    */
0046 
0047 
0048    typedef TRandomEngine DefaultEngineType;
0049    //class DefaultEngineType {};  // for generic types
0050 
0051 
0052 
0053    /**
0054       Definition of the generic implementation class for the RandomFunctions.
0055       Needs to have specialized implementations on the different type of engines
0056     */
0057    template <class EngineBaseType>
0058    class  RandomFunctionsImpl {
0059    public:
0060       void SetEngine(void *) {}
0061    };
0062 
0063    /**
0064       Implementation class for the RandomFunction for all the engined that derives from
0065       TRandomEngine class, which defines an interface which has TRandomEngine::Rndm()
0066       In this way we can have a common implementation for the RandomFunctions
0067     */
0068 
0069    template<>
0070    class RandomFunctionsImpl<TRandomEngine> {
0071 
0072    public:
0073 
0074       /// class constructor
0075       RandomFunctionsImpl() : fBaseEngine(nullptr) {}
0076 
0077       void SetEngine(void *r) {
0078          fBaseEngine = static_cast<TRandomEngine*>(r);
0079          assert(fBaseEngine);  // to be sure the static cast works
0080       }
0081 
0082 
0083       ///Generate binomial numbers
0084       int Binomial(int ntot, double prob);
0085 
0086       /// Return a number distributed following a BreitWigner function with mean and gamma.
0087       double BreitWigner(double mean, double gamma);
0088 
0089       /// Generates random vectors, uniformly distributed over a circle of given radius.
0090       ///   Input : r = circle radius
0091       ///   Output: x,y a random 2-d vector of length r
0092       void Circle(double &x, double &y, double r);
0093 
0094       /// Returns an exponential deviate.
0095       ///    exp( -t/tau )
0096       double  Exp(double tau);
0097 
0098       /// generate Gaussian number using Box-Muller method
0099       double GausBM( double mean, double sigma);
0100 
0101       /// generate random numbers according to the Acceptance-Complement-Ratio method
0102       double GausACR( double mean, double sigma);
0103 
0104       /// Generate a random number following a Landau distribution
0105       /// with location parameter mu and scale parameter sigma:
0106       ///      Landau( (x-mu)/sigma )
0107       double Landau(double mu, double sigma);
0108 
0109       /// Generates a random integer N according to a Poisson law.
0110       /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
0111       int Poisson(double mean);
0112       double PoissonD(double mean);
0113 
0114       /// Generate numbers distributed following a gaussian with mean=0 and sigma=1.
0115       /// Using the Box-Muller method
0116       void Rannor(double &a, double  &b);
0117 
0118       /// Generates random vectors, uniformly distributed over the surface
0119       /// of a sphere of given radius.
0120       void Sphere(double &x, double &y, double &z, double r);
0121 
0122       /// generate random numbers following a Uniform distribution in the [a,b] interval
0123       double Uniform(double a, double b);
0124       double Uniform(double a);
0125 
0126    protected:
0127       TRandomEngine* fBaseEngine;
0128 
0129    private:
0130       // Internal method used by the functions
0131       double Rndm() { return fBaseEngine->Rndm(); }
0132       // for internal usage
0133       double Gaus(double mean, double sigma) { return GausACR(mean,sigma); }
0134 
0135 
0136    };
0137 
0138 
0139    template < class Engine, class EngineBaseType>
0140    class RandomFunctions { //: public RandomFunctionsImpl<EngineBaseType> {
0141 
0142 
0143    public:
0144 
0145       //RandomFunctions() {}
0146 
0147       RandomFunctions(Engine & rng) : fEngine(&rng) {
0148          fImpl.SetEngine(&rng);
0149       }
0150 
0151       /// destructor (no op) we do not maintain the engine)
0152       ~RandomFunctions() {}
0153 
0154 
0155       /// non-virtual method
0156       inline double operator() () { return (*fEngine)(); }
0157 
0158 
0159       ///Generate binomial numbers
0160       int Binomial(int ntot, double prob) {
0161          return fImpl.Binomial(ntot,prob);
0162       }
0163 
0164       /// Return a number distributed following a BreitWigner function with mean and gamma.
0165       double BreitWigner(double mean, double gamma) {
0166          return fImpl.BreitWigner(mean,gamma);
0167       }
0168 
0169       /// Generates random vectors, uniformly distributed over a circle of given radius.
0170       ///   Input : r = circle radius
0171       ///   Output: x,y a random 2-d vector of length r
0172       void Circle(double &x, double &y, double r) {
0173          return fImpl.Circle(x,y,r);
0174       }
0175 
0176       /// Returns an exponential deviate.
0177       ///    exp( -t/tau )
0178       double  Exp(double tau) {
0179          return fImpl.Exp(tau);
0180       }
0181 
0182       /// generate Gaussian number using Box-Muller method
0183       double GausBM( double mean, double sigma) {
0184          return fImpl.GausBM(mean,sigma);
0185       }
0186 
0187       /// generate random numbers according to the Acceptance-Complement-Ratio method
0188       double GausACR( double mean, double sigma) {
0189          return fImpl.GausACR(mean, sigma);
0190       }
0191 
0192       /// Generate a random number following a Landau distribution
0193       /// with location parameter mu and scale parameter sigma:
0194       ///      Landau( (x-mu)/sigma )
0195       double Landau(double mu, double sigma) {
0196          return fImpl.Landau(mu,sigma);
0197       }
0198 
0199       /// Generates a random integer N according to a Poisson law.
0200       /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
0201       int Poisson(double mean) { return fImpl.Poisson(mean); }
0202       double PoissonD(double mean) { return fImpl.PoissonD(mean); }
0203 
0204       /// Generate numbers distributed following a gaussian with mean=0 and sigma=1.
0205       /// Using the Box-Muller method
0206       void Rannor(double &a, double  &b) {
0207          return fImpl.Rannor(a,b);
0208       }
0209 
0210       /// Generates random vectors, uniformly distributed over the surface
0211       /// of a sphere of given radius.
0212       void Sphere(double &x, double &y, double &z, double r) {
0213          return fImpl.Sphere(x,y,z,r);
0214       }
0215 
0216       /// generate random numbers following a Uniform distribution in the [a,b] interval
0217       double Uniform(double a, double b) {
0218          return (b-a) * Rndm_impl() + a;
0219       }
0220 
0221       /// generate random numbers following a Uniform distribution in the [0,a] interval
0222       double Uniform(double a) {
0223          return a * Rndm_impl() ;
0224       }
0225 
0226 
0227       /// generate Gaussian number using default method
0228       inline double Gaus( double mean, double sigma) {
0229          return fImpl.GausACR(mean,sigma);
0230       }
0231 
0232 
0233       // /// re-implement Gaussian
0234       // double GausBM2(double mean, double sigma) {
0235       //    double y =  Rndm_impl();
0236       //    double z =  Rndm_impl();
0237       //    double x = z * 6.28318530717958623;
0238       //    double radius = std::sqrt(-2*std::log(y));
0239       //    double g = radius * std::sin(x);
0240       //    return mean + g * sigma;
0241       // }
0242 
0243 
0244       /// methods which are only for GSL random generators
0245 
0246 
0247       /// Gamma functions (not implemented here, requires a GSL random engine)
0248       double Gamma( double , double ) {
0249          //r.Error("Error: Gamma() requires a GSL Engine type");
0250          static_assert(std::is_fundamental<Engine>::value,"Error: Gamma() requires a GSL Engine type");
0251          return 0;
0252       }
0253       double Beta( double , double ) {
0254          static_assert(std::is_fundamental<Engine>::value,"Error: Beta() requires a GSL Engine type");
0255          return 0;
0256       }
0257       double LogNormal(double, double) {
0258          static_assert(std::is_fundamental<Engine>::value,"Error: LogNormal() requires a GSL Engine type");
0259          return 0;
0260       }
0261       double ChiSquare(double) {
0262          static_assert(std::is_fundamental<Engine>::value,"Error: ChiSquare() requires a GSL Engine type");
0263          return 0;
0264       }
0265       double Rayleigh( double ) {
0266          static_assert(std::is_fundamental<Engine>::value,"Error: Rayleigh() requires a GSL Engine type");
0267          return 0;
0268       }
0269       double Logistic( double ) {
0270          static_assert(std::is_fundamental<Engine>::value,"Error: Logistic() requires a GSL Engine type");
0271          return 0;
0272       }
0273       double Pareto( double , double ) {
0274          static_assert(std::is_fundamental<Engine>::value,"Error: Pareto() requires a GSL Engine type");
0275          return 0;
0276       }
0277       double FDist(double, double) {
0278          static_assert(std::is_fundamental<Engine>::value,"Error: FDist() requires a GSL Engine type");
0279          return 0;
0280       }
0281       double tDist(double) {
0282          static_assert(std::is_fundamental<Engine>::value,"Error: tDist() requires a GSL Engine type");
0283          return 0;
0284       }
0285       unsigned int NegativeBinomial(double , double ) {
0286          static_assert(std::is_fundamental<Engine>::value,"Error: NegativeBinomial() requires a GSL Engine type");
0287          return 0;
0288       }
0289       std::vector<unsigned int> MultiNomial(unsigned int, const std::vector<double> &){
0290          static_assert(std::is_fundamental<Engine>::value,"Error: MultiNomial() requires a GSL Engine type");
0291          return std::vector<unsigned int>();
0292       }
0293 
0294 
0295    protected:
0296 
0297       Engine & Rng() { assert(fEngine); return *fEngine; }
0298 
0299       /// Internal implementation to return random number
0300       /// Since this one is not a virtual function is faster than Rndm
0301       inline double Rndm_impl() { return (*fEngine)(); }
0302 
0303 
0304    private:
0305 
0306       Engine * fEngine;   //! random number generator engine
0307       RandomFunctionsImpl<EngineBaseType> fImpl;   //! instance of the class implementing the functions
0308 
0309 
0310   };
0311 
0312 
0313 
0314 
0315 } // namespace Math
0316 } // namespace ROOT
0317 
0318 #endif /* ROOT_Math_RandomFunctions */