Logo ROOT   6.10/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
74  RandomFunctionsImpl() : fBaseEngine(0) {}
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 Beta( double , double ) {
253  static_assert(std::is_fundamental<Engine>::value,"Error: Beta() requires a GSL Engine type");
254  return 0;
255  }
256  double LogNormal(double, double) {
257  static_assert(std::is_fundamental<Engine>::value,"Error: LogNormal() requires a GSL Engine type");
258  return 0;
259  }
260  double ChiSquare(double) {
261  static_assert(std::is_fundamental<Engine>::value,"Error: ChiSquare() requires a GSL Engine type");
262  return 0;
263  }
264  double Rayleigh( double ) {
265  static_assert(std::is_fundamental<Engine>::value,"Error: Rayleigh() requires a GSL Engine type");
266  return 0;
267  }
268  double Logistic( double ) {
269  static_assert(std::is_fundamental<Engine>::value,"Error: Logistic() requires a GSL Engine type");
270  return 0;
271  }
272  double Pareto( double , double ) {
273  static_assert(std::is_fundamental<Engine>::value,"Error: Pareto() requires a GSL Engine type");
274  return 0;
275  }
276  double FDist(double, double) {
277  static_assert(std::is_fundamental<Engine>::value,"Error: FDist() requires a GSL Engine type");
278  return 0;
279  }
280  double tDist(double) {
281  static_assert(std::is_fundamental<Engine>::value,"Error: tDist() requires a GSL Engine type");
282  return 0;
283  }
284  unsigned int NegativeBinomial(double , double ) {
285  static_assert(std::is_fundamental<Engine>::value,"Error: NegativeBinomial() requires a GSL Engine type");
286  return 0;
287  }
288  std::vector<unsigned int> MultiNomial(unsigned int, const std::vector<double> &){
289  static_assert(std::is_fundamental<Engine>::value,"Error: MultiNomial() requires a GSL Engine type");
290  return std::vector<unsigned int>();
291  }
292 
293 
294  protected:
295 
296  Engine & Rng() { assert(fEngine); return *fEngine; }
297 
298  /// Internal impelmentation to return random number
299  /// Since this one is not a virtual function is faster than Rndm
300  inline double Rndm_impl() { return (*fEngine)(); }
301 
302 
303  private:
304 
305  Engine * fEngine; //! random number generator engine
306  RandomFunctionsImpl<EngineBaseType> fImpl; //! instance of the class implementing the functions
307 
308 
309  };
310 
311 
312 
313 
314 } // namespace Math
315 } // namespace ROOT
316 
317 #endif /* ROOT_Math_RandomFunctions */
int Poisson(double mean)
Generates a random integer N according to a Poisson law.
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:441
double LogNormal(double, double)
Namespace for new ROOT classes and functions.
Definition: StringConv.hxx:21
RandomFunctionsImpl< EngineBaseType > fImpl
random number generator engine
double Exp(double tau)
Returns an exponential deviate.
Double_t Landau(Double_t x, Double_t mean, Double_t sigma)
double Gamma(double, double)
methods which are only for GSL random generators
TArc * a
Definition: textangle.C:12
TRObject operator()(const T1 &t1) const
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
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t tau
Definition: TRolke.cxx:630
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
const Double_t sigma
double FDist(double, double)
double gamma(double x)
~RandomFunctions()
destructor (no op) we do not mantain the engine)
TRandom2 r(17)
virtual double Rndm()=0
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_t Binomial(Int_t n, Int_t k)
Calculate the binomial coefficient n over k.
Definition: TMath.cxx:2078
double Beta(double, double)
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:622
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
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
int Binomial(int ntot, double prob)
Generate binomial numbers.
Definition of the generic impelmentation class for the RandomFunctions.
unsigned int NegativeBinomial(double, double)
you should not use this method at all Int_t Int_t Double_t Double_t Double_t Int_t Double_t Double_t Double_t Double_t b
Definition: TRolke.cxx:630
double Pareto(double, double)
double GausBM(double mean, double sigma)
generate Gaussian number using Box-Muller method
double PoissonD(double mean)
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 > &)
double GausACR(double mean, double sigma)
generate random numbers according to the Accemptance-Complemet-Ratio method