File: RandomFunctions.h

package info (click to toggle)
bornagain 23.0-6
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 103,956 kB
  • sloc: cpp: 423,131; python: 40,997; javascript: 11,167; awk: 630; sh: 356; ruby: 173; xml: 130; makefile: 45; ansic: 24
file content (317 lines) | stat: -rw-r--r-- 10,154 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
// @(#)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_RandomFunctions
#define ROOT_Math_RandomFunctions


#include <type_traits>
#include <cmath>
#include "Rtypes.h"
#include "TMath.h"
#include <cassert>

#include "TRandomEngine.h"


namespace ROOT {
namespace Math {


//___________________________________________________________________________________


   // class DefaultEngineType {};

   
   /**
       Documentation for the RandomFunction class 

       @ingroup  Random
   */


   typedef TRandomEngine DefaultEngineType;
   //class DefaultEngineType {};  // for generic types



      /**
      Definition of the generic impelmentation class for the RandomFunctions.
      Needs to have specialized implementations on the different type of engines      
    */
   template <class EngineBaseType> 
   class  RandomFunctionsImpl {
   public:
      void SetEngine(void *) {}
   };

   /**
      Implementation class for the RandomFunction for all the engined that derives from 
      TRandomEngine class, which defines an interface which has TRandomEngine::Rndm()
      In this way we can have a common implementation for the RandomFunctions
    */

   template<>
   class RandomFunctionsImpl<TRandomEngine> { 

   public: 

      /// class constructor 
      RandomFunctionsImpl() : fBaseEngine(0) {}

      void SetEngine(void *r) {
         fBaseEngine = static_cast<TRandomEngine*>(r);
         assert(fBaseEngine);  // to be sure the static cast works 
      }
      

      ///Generate binomial numbers
      int Binomial(int ntot, double prob);

      /// Return a number distributed following a BreitWigner function with mean and gamma.
      double BreitWigner(double mean, double gamma);

      /// Generates random vectors, uniformly distributed over a circle of given radius.
      ///   Input : r = circle radius
      ///   Output: x,y a random 2-d vector of length r
      void Circle(double &x, double &y, double r);

      /// Returns an exponential deviate.
      ///    exp( -t/tau )
      double  Exp(double tau);
      
      /// generate Gaussian number using Box-Muller method
      double GausBM( double mean, double sigma);

      /// generate random numbers according to the Accemptance-Complemet-Ratio method
      double GausACR( double mean, double sigma);

      /// Generate a random number following a Landau distribution
      /// with location parameter mu and scale parameter sigma:
      ///      Landau( (x-mu)/sigma )
//      double Landau(double mu, double sigma);

      /// Generates a random integer N according to a Poisson law.
      /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
      int Poisson(double mean);
      double PoissonD(double mean);

      /// Generate numbers distributed following a gaussian with mean=0 and sigma=1.
      /// Using the Box-Muller method 
      void Rannor(double &a, double  &b);

      /// Generates random vectors, uniformly distributed over the surface
      /// of a sphere of given radius.
      void Sphere(double &x, double &y, double &z, double r);

      /// generate random numbers following a Uniform distribution in the [a,b] interval
      double Uniform(double a, double b);
      double Uniform(double a);

   protected:
      TRandomEngine* fBaseEngine;

   private:
      // Internal method used by the functions 
      double Rndm() { return fBaseEngine->Rndm(); }
      // for internal usage
      double Gaus(double mean, double sigma) { return GausACR(mean,sigma); }


   };


   template < class Engine, class EngineBaseType>
   class RandomFunctions { //: public RandomFunctionsImpl<EngineBaseType> {


   public:

      //RandomFunctions() {} 

      RandomFunctions(Engine & rng) : fEngine(&rng) {
         fImpl.SetEngine(&rng);
      }

      /// destructor (no op) we do not mantain the engine)
      ~RandomFunctions() {}


      /// non-virtual method
      inline double operator() () { return (*fEngine)(); }


      ///Generate binomial numbers
      int Binomial(int ntot, double prob) {
         return fImpl.Binomial(ntot,prob); 
      }

      /// Return a number distributed following a BreitWigner function with mean and gamma.
      double BreitWigner(double mean, double gamma) {
         return fImpl.BreitWigner(mean,gamma);
      }

      /// Generates random vectors, uniformly distributed over a circle of given radius.
      ///   Input : r = circle radius
      ///   Output: x,y a random 2-d vector of length r
      void Circle(double &x, double &y, double r) {
         return fImpl.Circle(x,y,r);
      }

      /// Returns an exponential deviate.
      ///    exp( -t/tau )
      double  Exp(double tau) {
         return fImpl.Exp(tau); 
      }
      
      /// generate Gaussian number using Box-Muller method
      double GausBM( double mean, double sigma) {
         return fImpl.GausBM(mean,sigma);
      }

      /// generate random numbers according to the Accemptance-Complemet-Ratio method
      double GausACR( double mean, double sigma) {
         return fImpl.GausACR(mean, sigma); 
      }

      /// Generate a random number following a Landau distribution
      /// with location parameter mu and scale parameter sigma:
      ///      Landau( (x-mu)/sigma )
      double Landau(double mu, double sigma) {
         return fImpl.Landau(mu,sigma); 
      }

      /// Generates a random integer N according to a Poisson law.
      /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
      int Poisson(double mean) { return fImpl.Poisson(mean); }
      double PoissonD(double mean) { return fImpl.PoissonD(mean); }

      /// Generate numbers distributed following a gaussian with mean=0 and sigma=1.
      /// Using the Box-Muller method 
      void Rannor(double &a, double  &b) {
         return fImpl.Rannor(a,b);
      }

      /// Generates random vectors, uniformly distributed over the surface
      /// of a sphere of given radius.
      void Sphere(double &x, double &y, double &z, double r) {
         return fImpl.Sphere(x,y,z,r);
      }

      /// generate random numbers following a Uniform distribution in the [a,b] interval
      double Uniform(double a, double b) {
         return (b-a) * Rndm_impl() + a; 
      }
     
      /// generate random numbers following a Uniform distribution in the [0,a] interval
      double Uniform(double a) {
         return a * Rndm_impl() ; 
      }


      /// generate Gaussian number using defqault method
      inline double Gaus( double mean, double sigma) {
         return fImpl.GausACR(mean,sigma);
      }


      // /// re-implement Gaussian 
      // double GausBM2(double mean, double sigma) {
      //    double y =  Rndm_impl();
      //    double z =  Rndm_impl();
      //    double x = z * 6.28318530717958623;
      //    double radius = std::sqrt(-2*std::log(y));
      //    double g = radius * std::sin(x);
      //    return mean + g * sigma; 
      // }


      /// methods which are only for GSL random generators 
      

      /// Gamma functions (not implemented here, requires a GSL random engine)
      double Gamma( double , double ) {
         //r.Error("Error: Gamma() requires a GSL Engine type"); 
         static_assert(std::is_fundamental<Engine>::value,"Error: Gamma() requires a GSL Engine type");
         return 0;
      }
      double Beta( double , double ) {
         static_assert(std::is_fundamental<Engine>::value,"Error: Beta() requires a GSL Engine type");
         return 0;
      }
      double LogNormal(double, double) {
         static_assert(std::is_fundamental<Engine>::value,"Error: LogNormal() requires a GSL Engine type");
         return 0;
      }
      double ChiSquare(double) {
         static_assert(std::is_fundamental<Engine>::value,"Error: ChiSquare() requires a GSL Engine type");
         return 0;
      }
      double Rayleigh( double ) {
         static_assert(std::is_fundamental<Engine>::value,"Error: Rayleigh() requires a GSL Engine type");
         return 0;
      }
      double Logistic( double ) {
         static_assert(std::is_fundamental<Engine>::value,"Error: Logistic() requires a GSL Engine type");
         return 0;
      }
      double Pareto( double , double ) {
         static_assert(std::is_fundamental<Engine>::value,"Error: Pareto() requires a GSL Engine type");
         return 0;
      }
      double FDist(double, double) {
         static_assert(std::is_fundamental<Engine>::value,"Error: FDist() requires a GSL Engine type");
         return 0;
      }
      double tDist(double) {
         static_assert(std::is_fundamental<Engine>::value,"Error: tDist() requires a GSL Engine type");
         return 0;
      }
      unsigned int NegativeBinomial(double , double ) {
         static_assert(std::is_fundamental<Engine>::value,"Error: NegativeBinomial() requires a GSL Engine type");
         return 0;
      }
      std::vector<unsigned int> MultiNomial(unsigned int, const std::vector<double> &){
         static_assert(std::is_fundamental<Engine>::value,"Error: MultiNomial() requires a GSL Engine type");
         return std::vector<unsigned int>();
      }


   protected:

      Engine & Rng() { assert(fEngine); return *fEngine; }

      /// Internal impelmentation to return random number
      /// Since this one is not a virtual function is faster than Rndm
      inline double Rndm_impl() { return (*fEngine)(); }


   private:    

      Engine * fEngine;   //! random number generator engine
      RandomFunctionsImpl<EngineBaseType> fImpl;   //! instance of the class implementing the functions
      

  };




} // namespace Math
} // namespace ROOT

#endif /* ROOT_Math_RandomFunctions */