Logo ROOT   6.08/07
Reference Guide
GSLRndmEngines.cxx
Go to the documentation of this file.
1 // @(#)root/mathmore:$Id$
2 // Authors: L. Moneta, A. Zsenei 08/2005
3 
4  /**********************************************************************
5  * *
6  * Copyright (c) 2004 ROOT Foundation, CERN/PH-SFT *
7  * *
8  * This library is free software; you can redistribute it and/or *
9  * modify it under the terms of the GNU General Public License *
10  * as published by the Free Software Foundation; either version 2 *
11  * of the License, or (at your option) any later version. *
12  * *
13  * This library is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
16  * General Public License for more details. *
17  * *
18  * You should have received a copy of the GNU General Public License *
19  * along with this library (see file COPYING); if not, write *
20  * to the Free Software Foundation, Inc., 59 Temple Place, Suite *
21  * 330, Boston, MA 02111-1307 USA, or contact the author. *
22  * *
23  **********************************************************************/
24 
25 // Header file for class GSLRandom
26 //
27 // Created by: moneta at Sun Nov 21 16:26:03 2004
28 //
29 // Last update: Sun Nov 21 16:26:03 2004
30 //
31 
32 
33 
34 // need to be included later
35 #include <time.h>
36 #include <stdlib.h>
37 #include <cassert>
38 
39 #include "gsl/gsl_rng.h"
40 #include "gsl/gsl_randist.h"
41 
42 
43 #include "Math/GSLRndmEngines.h"
44 #include "GSLRngWrapper.h"
45 // for wrapping in GSL ROOT engines
46 #include "GSLRngROOTWrapper.h"
47 
48 extern double gsl_ran_gaussian_acr( const gsl_rng * r, const double sigma);
49 
50 //#include <iostream>
51 
52 namespace ROOT {
53 namespace Math {
54 
55 
56 
57 
58 
59  // default constructor (need to call set type later)
61  fRng(nullptr),
62  fCurTime(0)
63  { }
64 
65  // constructor from external rng
66  // internal generator will be managed or not depending on
67  // how the GSLRngWrapper is created
69  fRng(new GSLRngWrapper(*rng) ),
70  fCurTime(0)
71  {}
72 
73  // copy constructor
75  fRng(new GSLRngWrapper(*eng.fRng) ),
76  fCurTime(0)
77  {}
78 
80  // destructor : call terminate if not yet called
81  if (fRng) Terminate();
82  }
83 
84  // assignment operator
86  if (this == &eng) return *this;
87  if (fRng)
88  *fRng = *eng.fRng;
89  else
90  fRng = new GSLRngWrapper(*eng.fRng);
91  fCurTime = eng.fCurTime;
92  return *this;
93  }
94 
95 
97  // initialize the generator by allocating the GSL object
98  // if type was not passed create with default generator
99  if (!fRng) fRng = new GSLRngWrapper();
100  fRng->Allocate();
101  }
102 
104  // terminate the generator by freeing the GSL object
105  if (!fRng) return;
106  fRng->Free();
107  delete fRng;
108  fRng = 0;
109  }
110 
111 
113  // generate random between 0 and 1.
114  // 0 is excluded
115  return gsl_rng_uniform_pos(fRng->Rng() );
116  }
117 
118 
119  unsigned long GSLRandomEngine::RndmInt(unsigned long max) const {
120  // generate a random integer number between 0 and MAX
121  return gsl_rng_uniform_int( fRng->Rng(), max );
122  }
123 
124  unsigned long GSLRandomEngine::MinInt() const {
125  // return minimum integer value used in RndmInt
126  return gsl_rng_min( fRng->Rng() );
127  }
128 
129  unsigned long GSLRandomEngine::MaxInt() const {
130  // return maximum integr value used in RndmInt
131  return gsl_rng_max( fRng->Rng() );
132  }
133 
134  void GSLRandomEngine::RandomArray(double * begin, double * end ) const {
135  // generate array of randoms betweeen 0 and 1. 0 is excluded
136  // specialization for double * (to be faster)
137  for ( double * itr = begin; itr != end; ++itr ) {
138  *itr = gsl_rng_uniform_pos(fRng->Rng() );
139  }
140  }
141 
142  void GSLRandomEngine::SetSeed(unsigned int seed) const {
143  // set the seed, if = 0then the seed is set randomly using an std::rand()
144  // seeded with the current time. Be carefuk in case the current time is
145  // the same in consecutive calls
146  if (seed == 0) {
147  // use like in root (use time)
148  time_t curtime;
149  time(&curtime);
150  unsigned int ct = static_cast<unsigned int>(curtime);
151  if (ct != fCurTime) {
152  fCurTime = ct;
153  // set the seed for rand
154  srand(ct);
155  }
156  seed = rand();
157  }
158 
159  assert(fRng);
160  gsl_rng_set(fRng->Rng(), seed );
161  }
162 
163  std::string GSLRandomEngine::Name() const {
164  //////////////////////////////////////////////////////////////////////////
165 
166  assert ( fRng != 0);
167  assert ( fRng->Rng() != 0 );
168  return std::string( gsl_rng_name( fRng->Rng() ) );
169  }
170 
171  unsigned int GSLRandomEngine::Size() const {
172  //////////////////////////////////////////////////////////////////////////
173 
174  assert (fRng != 0);
175  return gsl_rng_size( fRng->Rng() );
176  }
177 
178 
179  // Random distributions
180 
181  double GSLRandomEngine::GaussianZig(double sigma) const
182  {
183  // Gaussian distribution. Use fast ziggurat algorithm implemented since GSL 1.8
184  return gsl_ran_gaussian_ziggurat( fRng->Rng(), sigma);
185  }
186 
187  double GSLRandomEngine::Gaussian(double sigma) const
188  {
189  // Gaussian distribution. Use default Box-Muller method
190  return gsl_ran_gaussian( fRng->Rng(), sigma);
191  }
192 
194  {
195  // Gaussian distribution. Use ratio method
196  return gsl_ran_gaussian_ratio_method( fRng->Rng(), sigma);
197  }
198 
199 
200  double GSLRandomEngine::GaussianTail(double a , double sigma) const
201  {
202  // Gaussian Tail distribution: eeturn values larger than a distributed
203  // according to the gaussian
204  return gsl_ran_gaussian_tail( fRng->Rng(), a, sigma);
205  }
206 
207  void GSLRandomEngine::Gaussian2D(double sigmaX, double sigmaY, double rho, double &x, double &y) const
208  {
209  // Gaussian Bivariate distribution, with correlation coefficient rho
210  gsl_ran_bivariate_gaussian( fRng->Rng(), sigmaX, sigmaY, rho, &x, &y);
211  }
212 
213  double GSLRandomEngine::Exponential(double mu) const
214  {
215  // Exponential distribution
216  return gsl_ran_exponential( fRng->Rng(), mu);
217  }
218 
219  double GSLRandomEngine::Cauchy(double a) const
220  {
221  // Cauchy distribution
222  return gsl_ran_cauchy( fRng->Rng(), a);
223  }
224 
225  double GSLRandomEngine::Landau() const
226  {
227  // Landau distribution
228  return gsl_ran_landau( fRng->Rng());
229  }
230 
231  double GSLRandomEngine::Beta(double a, double b) const
232  {
233  // Beta distribution
234  return gsl_ran_beta( fRng->Rng(), a, b);
235  }
236 
237  double GSLRandomEngine::Gamma(double a, double b) const
238  {
239  // Gamma distribution
240  return gsl_ran_gamma( fRng->Rng(), a, b);
241  }
242 
243  double GSLRandomEngine::LogNormal(double zeta, double sigma) const
244  {
245  // Log normal distribution
246  return gsl_ran_lognormal( fRng->Rng(), zeta, sigma);
247  }
248 
249  double GSLRandomEngine::ChiSquare(double nu) const
250  {
251  // Chi square distribution
252  return gsl_ran_chisq( fRng->Rng(), nu);
253  }
254 
255 
256  double GSLRandomEngine::FDist(double nu1, double nu2) const
257  {
258  // F distribution
259  return gsl_ran_fdist( fRng->Rng(), nu1, nu2);
260  }
261 
262  double GSLRandomEngine::tDist(double nu) const
263  {
264  // t distribution
265  return gsl_ran_tdist( fRng->Rng(), nu);
266  }
267 
268  double GSLRandomEngine::Rayleigh(double sigma) const
269  {
270  // Rayleigh distribution
271  return gsl_ran_rayleigh( fRng->Rng(), sigma);
272  }
273 
274  double GSLRandomEngine::Logistic(double a) const
275  {
276  // Logistic distribution
277  return gsl_ran_logistic( fRng->Rng(), a);
278  }
279 
280  double GSLRandomEngine::Pareto(double a, double b) const
281  {
282  // Pareto distribution
283  return gsl_ran_pareto( fRng->Rng(), a, b);
284  }
285 
286  void GSLRandomEngine::Dir2D(double &x, double &y) const
287  {
288  // generate random numbers in a 2D circle of radious 1
289  gsl_ran_dir_2d( fRng->Rng(), &x, &y);
290  }
291 
292  void GSLRandomEngine::Dir3D(double &x, double &y, double &z) const
293  {
294  // generate random numbers in a 3D sphere of radious 1
295  gsl_ran_dir_3d( fRng->Rng(), &x, &y, &z);
296  }
297 
298  unsigned int GSLRandomEngine::Poisson(double mu) const
299  {
300  // Poisson distribution
301  return gsl_ran_poisson( fRng->Rng(), mu);
302  }
303 
304  unsigned int GSLRandomEngine::Binomial(double p, unsigned int n) const
305  {
306  // Binomial distribution
307  return gsl_ran_binomial( fRng->Rng(), p, n);
308  }
309 
310  unsigned int GSLRandomEngine::NegativeBinomial(double p, double n) const
311  {
312  // Negative Binomial distribution
313  return gsl_ran_negative_binomial( fRng->Rng(), p, n);
314  }
315 
316 
317  std::vector<unsigned int> GSLRandomEngine::Multinomial( unsigned int ntot, const std::vector<double> & p ) const
318  {
319  // Multinomial distribution return vector of integers which sum is ntot
320  std::vector<unsigned int> ival( p.size());
321  gsl_ran_multinomial( fRng->Rng(), p.size(), ntot, &p.front(), &ival[0]);
322  return ival;
323  }
324 
325 
326 
327  //----------------------------------------------------
328  // generators
329  //----------------------------------------------------
330 
331  /////////////////////////////////////////////////////////////////////////////
332 
334  {
335  SetType(new GSLRngWrapper(gsl_rng_mt19937));
336  Initialize();
337  }
338 
339 
340  // old ranlux - equivalent to TRandom1
342  {
343  SetType(new GSLRngWrapper(gsl_rng_ranlux) );
344  Initialize();
345  }
346 
347  // second generation of Ranlux (single precision version - luxury 1)
349  {
350  SetType(new GSLRngWrapper(gsl_rng_ranlxs1) );
351  Initialize();
352  }
353 
354  // second generation of Ranlux (single precision version - luxury 2)
356  {
357  SetType(new GSLRngWrapper(gsl_rng_ranlxs2) );
358  Initialize();
359  }
360 
361  // double precision version - luxury 1
363  {
364  SetType(new GSLRngWrapper(gsl_rng_ranlxd1) );
365  Initialize();
366  }
367 
368  // double precision version - luxury 2
370  {
371  SetType(new GSLRngWrapper(gsl_rng_ranlxd2) );
372  Initialize();
373  }
374 
375  /////////////////////////////////////////////////////////////////////////////
376 
378  {
379  SetType(new GSLRngWrapper(gsl_rng_taus2) );
380  Initialize();
381  }
382 
383  /////////////////////////////////////////////////////////////////////////////
384 
386  {
387  SetType(new GSLRngWrapper(gsl_rng_gfsr4) );
388  Initialize();
389  }
390 
391  /////////////////////////////////////////////////////////////////////////////
392 
394  {
395  SetType(new GSLRngWrapper(gsl_rng_cmrg) );
396  Initialize();
397  }
398 
399  /////////////////////////////////////////////////////////////////////////////
400 
402  {
403  SetType(new GSLRngWrapper(gsl_rng_mrg) );
404  Initialize();
405  }
406 
407 
408  /////////////////////////////////////////////////////////////////////////////
409 
411  {
412  SetType(new GSLRngWrapper(gsl_rng_rand) );
413  Initialize();
414  }
415 
416  /////////////////////////////////////////////////////////////////////////////
417 
419  {
420  SetType(new GSLRngWrapper(gsl_rng_ranmar) );
421  Initialize();
422  }
423 
424  /////////////////////////////////////////////////////////////////////////////
425 
427  {
428  SetType(new GSLRngWrapper(gsl_rng_minstd) );
429  Initialize();
430  }
431 
432 
433  // for extra engines based on ROOT
435  {
437  Initialize();
438  }
440  // we need to explicitly delete the ROOT wrapper class
441  GSLMixMaxWrapper::Free(Engine()->Rng()->state);
442  }
443 
444 } // namespace Math
445 } // namespace ROOT
446 
447 
448 
double Beta(double a, double b) const
Beta distribution.
double Rayleigh(double sigma) const
Rayleigh distribution.
GSLRandomEngine & operator=(const GSLRandomEngine &eng)
Assignment operator : make a deep copy of the contained GSL generator.
This namespace contains pre-defined functions to be used in conjuction with TExecutor::Map and TExecu...
Definition: StringConv.hxx:21
double Gamma(double a, double b) const
Gamma distribution.
double Logistic(double a) const
Logistic distribution.
void SetType(GSLRngWrapper *r)
internal method used by the derived class to set the type of generators
double tDist(double nu) const
t student distribution
TArc * a
Definition: textangle.C:12
void RandomArray(Iterator begin, Iterator end) const
Generate an array of random numbers.
double FDist(double nu1, double nu2) const
F distrbution.
unsigned int Poisson(double mu) const
Poisson distribution.
double Pareto(double a, double b) const
Pareto distribution.
Double_t x[n]
Definition: legend1.C:17
unsigned int NegativeBinomial(double p, double n) const
Negative Binomial distribution.
void Dir3D(double &x, double &y, double &z) const
generate random numbers in a 3D sphere of radious 1
void Terminate()
delete pointer to contained rng
double ChiSquare(double nu) const
Chi square distribution.
GSLRandomEngine Base class for all GSL random engines, normally user instantiate the derived classes ...
GSLRngWrapper class to wrap gsl_rng structure.
Definition: GSLRngWrapper.h:25
unsigned int Size() const
return the state size of generator
double GaussianZig(double sigma) const
Gaussian distribution - Ziggurat method.
const Double_t sigma
double Landau() const
Landau distribution.
double Exponential(double mu) const
Exponential distribution.
std::vector< unsigned int > Multinomial(unsigned int ntot, const std::vector< double > &p) const
Multinomial distribution.
unsigned long MinInt() const
return the minimum integer a generator can handle typically this value is 0
virtual ~GSLRandomEngine()
call Terminate()
TRandom2 r(17)
double LogNormal(double zeta, double sigma) const
Log Normal distribution.
unsigned long RndmInt(unsigned long max) const
Generate an integer number between [0,max-1] (including 0 and max-1) if max is larger than available ...
GSLRngWrapper * Engine()
internal method to return the engine Used by class like GSLMCIntegrator to set the engine ...
void Gaussian2D(double sigmaX, double sigmaY, double rho, double &x, double &y) const
Bivariate Gaussian distribution with correlation.
unsigned int Binomial(double p, unsigned int n) const
Binomial distribution.
double GaussianTail(double a, double sigma) const
Gaussian Tail distribution.
double operator()() const
Generate a random number between ]0,1] 0 is excluded and 1 is included.
void SetSeed(unsigned int seed) const
set the random generator seed
Double_t y[n]
Definition: legend1.C:17
Namespace for new Math classes and functions.
you should not use this method at all Int_t Int_t z
Definition: TRolke.cxx:630
std::string Name() const
return name of generator
double Cauchy(double a) const
Cauchy distribution.
unsigned long MaxInt() const
return the maximum integer +1 a generator can handle
#define nullptr
Definition: Rtypes.h:87
double GaussianRatio(double sigma) const
Gaussian distribution - Ratio method.
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
void Initialize()
initialize the generator If no rng is present the default one based on Mersenne and Twister is create...
double Gaussian(double sigma) const
Gaussian distribution - default method is Box-Muller (polar method)
const Int_t n
Definition: legend1.C:16
const gsl_rng_type * gsl_rng_mixmax
GSLRandomEngine()
default constructor.
double gsl_ran_gaussian_acr(const gsl_rng *r, const double sigma)
void Dir2D(double &x, double &y) const
generate random numbers in a 2D circle of radious 1