// @(#)root/mathcore:$Id$
// Authors: L. Moneta    8/2015

/**********************************************************************
 *                                                                    *
 * Copyright (c) 2015 , ROOT MathLib Team                             *
 *                                                                    *
 *                                                                    *
 **********************************************************************/

// Header file for random class
//
//
// Created by: Lorenzo Moneta  : Tue 4 Aug 2015
//
//
#ifndef ROOT_Math_Random
#define ROOT_Math_Random

/**
@defgroup Random Interface class for Random number generation
*/

#include "Math/RandomFunctions.h"


namespace ROOT {
namespace Math {


//___________________________________________________________________________________
   /**
       Documentation for the Random class

       @ingroup  Random
   */

   template < class Engine>
   class Random {

   public:

      typedef typename Engine::BaseType EngineBaseType;
      typedef RandomFunctions<Engine, EngineBaseType> RndmFunctions;

      Random() :
         fEngine(),
         fFunctions(fEngine)
      {}

      explicit Random(unsigned int seed) :
         fEngine(),
         fFunctions(fEngine)
      {
         fEngine.SetSeed(seed);
      }

      double Rndm() {
         return fEngine();
      }

      /**
         Generate an array of random numbers between ]0,1]
         0 is excluded and 1 is included
         Function to preserve ROOT Trandom compatibility
      */
      void RndmArray(int n, double * array) {
         fEngine.RandomArray(array, array+n);
      }

      /**
         Return the type (name) of the used generator
      */
      std::string Type() const {
         return fEngine.Name();
      }

      /**
       Return the size of the generator state
     */
      unsigned int EngineSize() const {
         return fEngine.Size();
      }


      double operator() (){
         return fEngine();
      }

      uint64_t Integer() {
         return fEngine.IntRndm();
      }

      static uint64_t MaxInt()  {
         return Engine::Max();
      }

      Engine & Rng() {
         return fEngine;
      }

      /// Exponential distribution
      double Exp(double tau) {
         return fFunctions.Exp(tau);
      }

      double Gaus(double mean = 0, double sigma = 1) {
         return fFunctions.Gaus(mean,sigma);
      }

      /// Gamma distribution
      double Gamma(double a, double b) {
         return fFunctions.Gamma(a,b);
      }

      /// Beta distribution
      double Beta(double a, double b) {
         return fFunctions.Beta(a,b);
      }

      ///Log-normal distribution
      double LogNormal(double zeta, double sigma) {
         return fFunctions.LogNormal(zeta,sigma);
      }

      /// chi-square
      double  ChiSquare(double nu) {
         return fFunctions.ChiSquare(nu);
      }

      /// Rayleigh distribution
      double  Rayleigh(double sigma) {
         return fFunctions.Rayleigh(sigma);
      }

      /// Logistic distribution
      double  Logistic(double a) {
         return fFunctions.Logistic(a);
      }

      /// Pareto distribution
      double  Pareto(double a, double b) {
         return fFunctions.Pareto(a, b);
      }

      ///F-distribution
      double FDist(double nu1, double nu2) {
         return fFunctions.FDist(nu1,nu2);
      }

      ///  t student distribution
      double tDist(double nu) {
         return fFunctions.tDist(nu);
      }

      /// Landau distribution
      double Landau(double m = 0, double s = 1) {
         return fFunctions.Landau(m,s);
      }
     ///  Breit Wigner distribution
      double BreitWigner(double mean = 0., double gamma = 1) {
         return fFunctions.BreitWigner(mean,gamma);
      }

     ///  generate random numbers in a 2D circle of radious 1
      void Circle(double &x, double &y, double r = 1) {
         fFunctions.Circle(x,y,r);
      }

      ///  generate random numbers in a 3D sphere of radious 1
      void Sphere(double &x, double &y, double &z,double r = 1) {
         fFunctions.Sphere(x,y,z,r);
      }


      ///discrete distributions

      /// Binomial distribution
      unsigned int Binomial(unsigned int ntot, double prob) {
         return fFunctions.Binomial(prob,ntot);
      }


      ///   Poisson distribution
      unsigned int Poisson(double mu)  {
         return fFunctions.Poisson(mu);
      }

      /// Negative Binomial distribution
      ///  First parameter is n, second is probability
      ///  To be consistent with Random::Binomial
     unsigned int NegativeBinomial(double n, double prob) {
      return fFunctions.NegativeBinomial(prob,n);
     }

      ///     Multinomial distribution
      std::vector<unsigned int> Multinomial( unsigned int ntot, const std::vector<double> & p ) {
         return fFunctions.Multinomial(ntot,p);
      }



      double Uniform(double a, double b) {
         return fFunctions.Uniform(a,b);
      }
      double Uniform(double a = 1.0) {
         return fFunctions.Uniform(a);
      }
      double Uniform2(double a, double b) {
         return fFunctions.UniformBase(a,b);
      }


      RandomFunctions<Engine,EngineBaseType> & Functions() {
         return fFunctions;
      }

      void SetSeed(int seed) { fEngine.SetSeed(seed);}

   private:

      Engine fEngine;             //  random generator engine
      RndmFunctions fFunctions;   //! random functions object


  };




} // namespace Math
} // namespace ROOT

#include "Math/MixMaxEngine.h"
#include "Math/MersenneTwisterEngine.h"
#include "Math/StdEngine.h"

namespace ROOT {
namespace Math {

   /// Useful typedef definitions

   typedef   Random<ROOT::Math::MixMaxEngine<240,0>>            RandomMixMax;
   typedef   Random<ROOT::Math::MersenneTwisterEngine>   RandomMT19937;
   typedef   Random<ROOT::Math::StdEngine<std::mt19937_64>> RandomMT64;
   typedef   Random<ROOT::Math::StdEngine<std::ranlux48>> RandomRanlux48;

} // namespace Math
} // namespace ROOT


#endif /* ROOT_Math_Random */
 Random.h:1
 Random.h:2
 Random.h:3
 Random.h:4
 Random.h:5
 Random.h:6
 Random.h:7
 Random.h:8
 Random.h:9
 Random.h:10
 Random.h:11
 Random.h:12
 Random.h:13
 Random.h:14
 Random.h:15
 Random.h:16
 Random.h:17
 Random.h:18
 Random.h:19
 Random.h:20
 Random.h:21
 Random.h:22
 Random.h:23
 Random.h:24
 Random.h:25
 Random.h:26
 Random.h:27
 Random.h:28
 Random.h:29
 Random.h:30
 Random.h:31
 Random.h:32
 Random.h:33
 Random.h:34
 Random.h:35
 Random.h:36
 Random.h:37
 Random.h:38
 Random.h:39
 Random.h:40
 Random.h:41
 Random.h:42
 Random.h:43
 Random.h:44
 Random.h:45
 Random.h:46
 Random.h:47
 Random.h:48
 Random.h:49
 Random.h:50
 Random.h:51
 Random.h:52
 Random.h:53
 Random.h:54
 Random.h:55
 Random.h:56
 Random.h:57
 Random.h:58
 Random.h:59
 Random.h:60
 Random.h:61
 Random.h:62
 Random.h:63
 Random.h:64
 Random.h:65
 Random.h:66
 Random.h:67
 Random.h:68
 Random.h:69
 Random.h:70
 Random.h:71
 Random.h:72
 Random.h:73
 Random.h:74
 Random.h:75
 Random.h:76
 Random.h:77
 Random.h:78
 Random.h:79
 Random.h:80
 Random.h:81
 Random.h:82
 Random.h:83
 Random.h:84
 Random.h:85
 Random.h:86
 Random.h:87
 Random.h:88
 Random.h:89
 Random.h:90
 Random.h:91
 Random.h:92
 Random.h:93
 Random.h:94
 Random.h:95
 Random.h:96
 Random.h:97
 Random.h:98
 Random.h:99
 Random.h:100
 Random.h:101
 Random.h:102
 Random.h:103
 Random.h:104
 Random.h:105
 Random.h:106
 Random.h:107
 Random.h:108
 Random.h:109
 Random.h:110
 Random.h:111
 Random.h:112
 Random.h:113
 Random.h:114
 Random.h:115
 Random.h:116
 Random.h:117
 Random.h:118
 Random.h:119
 Random.h:120
 Random.h:121
 Random.h:122
 Random.h:123
 Random.h:124
 Random.h:125
 Random.h:126
 Random.h:127
 Random.h:128
 Random.h:129
 Random.h:130
 Random.h:131
 Random.h:132
 Random.h:133
 Random.h:134
 Random.h:135
 Random.h:136
 Random.h:137
 Random.h:138
 Random.h:139
 Random.h:140
 Random.h:141
 Random.h:142
 Random.h:143
 Random.h:144
 Random.h:145
 Random.h:146
 Random.h:147
 Random.h:148
 Random.h:149
 Random.h:150
 Random.h:151
 Random.h:152
 Random.h:153
 Random.h:154
 Random.h:155
 Random.h:156
 Random.h:157
 Random.h:158
 Random.h:159
 Random.h:160
 Random.h:161
 Random.h:162
 Random.h:163
 Random.h:164
 Random.h:165
 Random.h:166
 Random.h:167
 Random.h:168
 Random.h:169
 Random.h:170
 Random.h:171
 Random.h:172
 Random.h:173
 Random.h:174
 Random.h:175
 Random.h:176
 Random.h:177
 Random.h:178
 Random.h:179
 Random.h:180
 Random.h:181
 Random.h:182
 Random.h:183
 Random.h:184
 Random.h:185
 Random.h:186
 Random.h:187
 Random.h:188
 Random.h:189
 Random.h:190
 Random.h:191
 Random.h:192
 Random.h:193
 Random.h:194
 Random.h:195
 Random.h:196
 Random.h:197
 Random.h:198
 Random.h:199
 Random.h:200
 Random.h:201
 Random.h:202
 Random.h:203
 Random.h:204
 Random.h:205
 Random.h:206
 Random.h:207
 Random.h:208
 Random.h:209
 Random.h:210
 Random.h:211
 Random.h:212
 Random.h:213
 Random.h:214
 Random.h:215
 Random.h:216
 Random.h:217
 Random.h:218
 Random.h:219
 Random.h:220
 Random.h:221
 Random.h:222
 Random.h:223
 Random.h:224
 Random.h:225
 Random.h:226
 Random.h:227
 Random.h:228
 Random.h:229
 Random.h:230
 Random.h:231
 Random.h:232
 Random.h:233
 Random.h:234
 Random.h:235
 Random.h:236
 Random.h:237
 Random.h:238
 Random.h:239
 Random.h:240
 Random.h:241
 Random.h:242
 Random.h:243
 Random.h:244
 Random.h:245
 Random.h:246
 Random.h:247
 Random.h:248
 Random.h:249
 Random.h:250
 Random.h:251
 Random.h:252