ROOT  6.06/09
Reference Guide
RandomFunctions.h
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Authors: L. Moneta 8/2015
3 
4 /**********************************************************************
5  * *
6  * Copyright (c) 2015 , ROOT MathLib Team *
7  * *
8  * *
9  **********************************************************************/
10 
11 // Header file for random class
12 //
13 //
14 // Created by: Lorenzo Moneta : Tue 4 Aug 2015
15 //
16 //
17 #ifndef ROOT_Math_RandomFunctions
18 #define ROOT_Math_RandomFunctions
19 
20 
21 #include <type_traits>
22 #include <cmath>
23 #include "Rtypes.h"
24 #include "TMath.h"
25 #include <cassert>
26 
27 #include "TRandomEngine.h"
28 
29 
30 namespace ROOT {
31 namespace Math {
32 
33 
34 //___________________________________________________________________________________
35 
36 
37  // class DefaultEngineType {};
38 
39 
40  /**
41  Documentation for the RandomFunction class
42 
43  @ingroup Random
44  */
45 
46 
48  //class DefaultEngineType {}; // for generic types
49 
50 
51 
52  /**
53  Definition of the generic impelmentation class for the RandomFunctions.
54  Needs to have specialized implementations on the different type of engines
55  */
56  template <class EngineBaseType>
58  public:
59  void SetEngine(void *) {}
60  };
61 
62  /**
63  Implementation class for the RandomFunction for all the engined that derives from
64  TRandomEngine class, which defines an interface which has TRandomEngine::Rndm()
65  In this way we can have a common implementation for the RandomFunctions
66  */
67 
68  template<>
70 
71  public:
72 
73  /// class constructor
75 
76  void SetEngine(void *r) {
77  fBaseEngine = static_cast<TRandomEngine*>(r);
78  assert(fBaseEngine); // to be sure the static cast works
79  }
80 
81 
82  ///Generate binomial numbers
83  int Binomial(int ntot, double prob);
84 
85  /// Return a number distributed following a BreitWigner function with mean and gamma.
86  double BreitWigner(double mean, double gamma);
87 
88  /// Generates random vectors, uniformly distributed over a circle of given radius.
89  /// Input : r = circle radius
90  /// Output: x,y a random 2-d vector of length r
91  void Circle(double &x, double &y, double r);
92 
93  /// Returns an exponential deviate.
94  /// exp( -t/tau )
95  double Exp(double tau);
96 
97  /// generate Gaussian number using Box-Muller method
98  double GausBM( double mean, double sigma);
99 
100  /// generate random numbers according to the Accemptance-Complemet-Ratio method
101  double GausACR( double mean, double sigma);
102 
103  /// Generate a random number following a Landau distribution
104  /// with location parameter mu and scale parameter sigma:
105  /// Landau( (x-mu)/sigma )
106  double Landau(double mu, double sigma);
107 
108  /// Generates a random integer N according to a Poisson law.
109  /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
110  int Poisson(double mean);
111  double PoissonD(double mean);
112 
113  /// Generate numbers distributed following a gaussian with mean=0 and sigma=1.
114  /// Using the Box-Muller method
115  void Rannor(double &a, double &b);
116 
117  /// Generates random vectors, uniformly distributed over the surface
118  /// of a sphere of given radius.
119  void Sphere(double &x, double &y, double &z, double r);
120 
121  /// generate random numbers following a Uniform distribution in the [a,b] interval
122  double Uniform(double a, double b);
123  double Uniform(double a);
124 
125  protected:
127 
128  private:
129  // Internal method used by the functions
130  double Rndm() { return fBaseEngine->Rndm(); }
131  // for internal usage
132  double Gaus(double mean, double sigma) { return GausACR(mean,sigma); }
133 
134 
135  };
136 
137 
138  template < class Engine, class EngineBaseType>
139  class RandomFunctions { //: public RandomFunctionsImpl<EngineBaseType> {
140 
141 
142  public:
143 
144  //RandomFunctions() {}
145 
146  RandomFunctions(Engine & rng) : fEngine(&rng) {
147  fImpl.SetEngine(&rng);
148  }
149 
150  /// destructor (no op) we do not mantain the engine)
152 
153 
154  /// non-virtual method
155  inline double operator() () { return (*fEngine)(); }
156 
157 
158  ///Generate binomial numbers
159  int Binomial(int ntot, double prob) {
160  return fImpl.Binomial(ntot,prob);
161  }
162 
163  /// Return a number distributed following a BreitWigner function with mean and gamma.
164  double BreitWigner(double mean, double gamma) {
165  return fImpl.BreitWigner(mean,gamma);
166  }
167 
168  /// Generates random vectors, uniformly distributed over a circle of given radius.
169  /// Input : r = circle radius
170  /// Output: x,y a random 2-d vector of length r
171  void Circle(double &x, double &y, double r) {
172  return fImpl.Circle(x,y,r);
173  }
174 
175  /// Returns an exponential deviate.
176  /// exp( -t/tau )
177  double Exp(double tau) {
178  return fImpl.Exp(tau);
179  }
180 
181  /// generate Gaussian number using Box-Muller method
182  double GausBM( double mean, double sigma) {
183  return fImpl.GausBM(mean,sigma);
184  }
185 
186  /// generate random numbers according to the Accemptance-Complemet-Ratio method
187  double GausACR( double mean, double sigma) {
188  return fImpl.GausACR(mean, sigma);
189  }
190 
191  /// Generate a random number following a Landau distribution
192  /// with location parameter mu and scale parameter sigma:
193  /// Landau( (x-mu)/sigma )
194  double Landau(double mu, double sigma) {
195  return fImpl.Landau(mu,sigma);
196  }
197 
198  /// Generates a random integer N according to a Poisson law.
199  /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
200  int Poisson(double mean) { return fImpl.Poisson(mean); }
201  double PoissonD(double mean) { return fImpl.PoissonD(mean); }
202 
203  /// Generate numbers distributed following a gaussian with mean=0 and sigma=1.
204  /// Using the Box-Muller method
205  void Rannor(double &a, double &b) {
206  return fImpl.Rannor(a,b);
207  }
208 
209  /// Generates random vectors, uniformly distributed over the surface
210  /// of a sphere of given radius.
211  void Sphere(double &x, double &y, double &z, double r) {
212  return fImpl.Sphere(x,y,z,r);
213  }
214 
215  /// generate random numbers following a Uniform distribution in the [a,b] interval
216  double Uniform(double a, double b) {
217  return (b-a) * Rndm_impl() + a;
218  }
219 
220  /// generate random numbers following a Uniform distribution in the [0,a] interval
221  double Uniform(double a) {
222  return a * Rndm_impl() ;
223  }
224 
225 
226  /// generate Gaussian number using defqault method
227  inline double Gaus( double mean, double sigma) {
228  return fImpl.GausACR(mean,sigma);
229  }
230 
231 
232  // /// re-implement Gaussian
233  // double GausBM2(double mean, double sigma) {
234  // double y = Rndm_impl();
235  // double z = Rndm_impl();
236  // double x = z * 6.28318530717958623;
237  // double radius = std::sqrt(-2*std::log(y));
238  // double g = radius * std::sin(x);
239  // return mean + g * sigma;
240  // }
241 
242 
243  /// methods which are only for GSL random generators
244 
245 
246  /// Gamma functions (not implemented here, requires a GSL random engine)
247  double Gamma( double , double ) {
248  //r.Error("Error: Gamma() requires a GSL Engine type");
249  static_assert(std::is_fundamental<Engine>::value,"Error: Gamma() requires a GSL Engine type");
250  return 0;
251  }
252  double LogNormal(double, double) {
253  static_assert(std::is_fundamental<Engine>::value,"Error: LogNormal() requires a GSL Engine type");
254  return 0;
255  }
256  double ChiSquare(double) {
257  static_assert(std::is_fundamental<Engine>::value,"Error: ChiSquare() requires a GSL Engine type");
258  return 0;
259  }
260  double FDist(double, double) {
261  static_assert(std::is_fundamental<Engine>::value,"Error: FDist() requires a GSL Engine type");
262  return 0;
263  }
264  double tDist(double) {
265  static_assert(std::is_fundamental<Engine>::value,"Error: tDist() requires a GSL Engine type");
266  return 0;
267  }
268  unsigned int NegativeBinomial(double , double ) {
269  static_assert(std::is_fundamental<Engine>::value,"Error: NegativeBinomial() requires a GSL Engine type");
270  return 0;
271  }
272  std::vector<unsigned int> MultiNomial(unsigned int, const std::vector<double> &){
273  static_assert(std::is_fundamental<Engine>::value,"Error: MultiNomial() requires a GSL Engine type");
274  return std::vector<unsigned int>();
275  }
276 
277 
278  protected:
279 
280  Engine & Rng() { assert(fEngine); return *fEngine; }
281 
282  /// Internal impelmentation to return random number
283  /// Since this one is not a virtual function is faster than Rndm
284  inline double Rndm_impl() { return (*fEngine)(); }
285 
286 
287  private:
288 
289  Engine * fEngine; //! random number generator engine
290  RandomFunctionsImpl<EngineBaseType> fImpl; //! instance of the class implementing the functions
291 
292 
293  };
294 
295 
296 
297 
298 } // namespace Math
299 } // namespace ROOT
300 
301 #endif /* ROOT_Math_RandomFunctions */
int Poisson(double mean)
Generates a random integer N according to a Poisson law.
Double_t Landau(Double_t x, Double_t mpv=0, Double_t sigma=1, Bool_t norm=kFALSE)
The LANDAU function.
Definition: TMath.cxx:473
Double_t BreitWigner(Double_t x, Double_t mean=0, Double_t gamma=1)
Calculate a Breit Wigner function with mean and gamma.
Definition: TMath.cxx:442
double LogNormal(double, double)
Namespace for new ROOT classes and functions.
Definition: ROOT.py:1
RandomFunctionsImpl< EngineBaseType > fImpl
random number generator engine
double Exp(double tau)
Returns an exponential deviate.
#define assert(cond)
Definition: unittest.h:542
double Gamma(double, double)
methods which are only for GSL random generators
TArc * a
Definition: textangle.C:12
void Circle(double &x, double &y, double r)
Generates random vectors, uniformly distributed over a circle of given radius.
double Landau(double mu, double sigma)
Generate a random number following a Landau distribution with location parameter mu and scale paramet...
Double_t x[n]
Definition: legend1.C:17
void Sphere(double &x, double &y, double &z, double r)
Generates random vectors, uniformly distributed over the surface of a sphere of given radius...
double Uniform(double a, double b)
generate random numbers following a Uniform distribution in the [a,b] interval
double FDist(double, double)
double gamma(double x)
~RandomFunctions()
destructor (no op) we do not mantain the engine)
ROOT::R::TRInterface & r
Definition: Object.C:4
double Uniform(double a)
generate random numbers following a Uniform distribution in the [0,a] interval
void Rannor(double &a, double &b)
Generate numbers distributed following a gaussian with mean=0 and sigma=1.
double operator()()
non-virtual method
Double_t Binomial(Int_t n, Int_t k)
Calculate the binomial coefficient n over k.
Definition: TMath.cxx:2072
double Rndm_impl()
Internal impelmentation to return random number Since this one is not a virtual function is faster th...
double Gaus(double mean, double sigma)
TRandomEngine DefaultEngineType
Documentation for the RandomFunction class.
Double_t Exp(Double_t x)
Definition: TMath.h:495
Double_t y[n]
Definition: legend1.C:17
Namespace for new Math classes and functions.
double Gaus(double mean, double sigma)
generate Gaussian number using defqault method
int Binomial(int ntot, double prob)
Generate binomial numbers.
Definition of the generic impelmentation class for the RandomFunctions.
unsigned int NegativeBinomial(double, double)
double GausBM(double mean, double sigma)
generate Gaussian number using Box-Muller method
double PoissonD(double mean)
float value
Definition: math.cpp:443
double BreitWigner(double mean, double gamma)
Return a number distributed following a BreitWigner function with mean and gamma. ...
std::vector< unsigned int > MultiNomial(unsigned int, const std::vector< double > &)
virtual double Rndm()=0
double GausACR(double mean, double sigma)
generate random numbers according to the Accemptance-Complemet-Ratio method