Logo ROOT  
Reference Guide
TRandom.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: Rene Brun, Lorenzo Moneta 15/12/95
3 
4 /*************************************************************************
5  * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers. *
6  * All rights reserved. *
7  * *
8  * For the licensing terms see $ROOTSYS/LICENSE. *
9  * For the list of contributors see $ROOTSYS/README/CREDITS. *
10  *************************************************************************/
11 
12 /**
13 
14 \class TRandom
15 
16 @ingroup Random
17 
18 This is the base class for the ROOT Random number generators.
19 This class defines the ROOT Random number interface and it should not be instantiated directly but used via its derived
20 classes. The generator provided in TRandom itself is a LCG (Linear Congruential Generator), the <a
21 href="https://www.gnu.org/software/gsl/manual/html_node/Unix-random-number-generators.html">BSD `rand` generator</a>,
22 that it should not be used because its period is only 2**31, i.e. approximatly 2 billion events, that can be generated
23 in just few seconds.
24 
25 To generate random numbers, one should use the derived class, which are :
26 - TRandom3: it is based on the "Mersenne Twister generator",
27 it is fast and a very long period of about \f$10^{6000}\f$. However it fails some of the most stringent tests of the
28 <a href="http://simul.iro.umontreal.ca/testu01/tu01.html">TestU01 suite</a>.
29 In addition this generator provide only numbers with 32 random bits, which might be not sufficient for some application
30 based on double or extended precision. This generator is however used in ROOT used to instantiate the global pointer to
31 the ROOT generator, *gRandom*.
32 - ::TRandomRanluxpp : New implementation of the Ranlux generator algorithm based on a fast modular multiplication of
33 576 bits. This new implementation is built on the idea and the original code of Alexei Sibidanov, described in his
34 <a href="https://arxiv.org/abs/1705.03123">paper </a>. It generates random numbers with 52 bit precision (double
35 precision) and it has an higher luxury level than the original Ranlux generator (`p = 2048` instead of `p=794`).
36 - ::TRandomMixMax: Generator based on the family of the MIXMAX matrix generators (see the
37 <a href="https://mixmax.hepforge.org">MIXMAX HEPFORGE Web page</a> and the the documentation of the class
38 ROOT::Math::MixMaxEngine for more information), that are base on the Asanov dynamical C systems. This generator has a
39 state of N=240 64 bit integers, proof random properties, it provides 61 random bits and it has a very large period
40 (\f$10^{4839}\f$). Furthermore, it provides the capability to be seeded with the guarantee that, for each given
41 different seed, a different sequence of random numbers will be generated. The only drawback is that the seeding time is
42 time consuming, of the order of 0.1 ms, while the time to generate a number is few ns (more than 10000 faster).
43 - ::TRandomMixMax17: Another MixMax generator, but with a smaller state, N=17, and this results in a smaller entropy
44 than the generator with N=240. However, it has the same seeding capabilities, with a much faster seeding time (about 200
45 times less than TRandomMixMax240 and comparable to TRandom3).
46 - ::TRandomMixMax256 : A variant of the MIXMAX generators, based on a state of N=256, and described in the
47  <a href="http://arxiv.org/abs/1403.5355">2015 paper</a>. This implementation has been modified with respect to
48 the paper, by skipping 2 internal interations, to provide improved random properties.
49 - ::TRandomMT64 : Generator based on a the Mersenne-Twister generator with 64 bits,
50  using the implementation provided by the standard library ( <a
51 href="http://www.cplusplus.com/reference/random/mt19937_64/">std::mt19937_64</a> )
52 - TRandom1 based on the RANLUX algorithm, has mathematically proven random proprieties
53  and a period of about \f$10{171}\f$. It is however much slower than the others and it has only 24 random bits. It can
54 be constructed with different luxury levels.
55 - ::TRandomRanlux48 : Generator based on a the RanLux generator with 48 bits and highest luxury level
56  using the implementation provided by the standard library (<a
57 href="http://www.cplusplus.com/reference/random/ranlux48/">std::ranlux48</a>). The drawback of this generator is its
58 slow generation time.
59 - TRandom2 is based on the Tausworthe generator of L'Ecuyer, and it has the advantage
60 of being fast and using only 3 words (of 32 bits) for the state. The period however is not impressively long, it is
61 10**26.
62 
63 Using the template TRandomGen class (template on the contained Engine type), it is possible to add any generator based
64 on the standard C++ random library (see the C++ <a href="http://www.cplusplus.com/reference/random/">random</a>
65 documentation.) or different variants of the MIXMAX generator using the ROOT::Math::MixMaxEngine. Some of the listed
66 generator above (e.g. TRandomMixMax256 or TRandomMT64) are convenient typedef's of generator built using the template
67 TRandomGen class.
68 
69 Please note also that this class (TRandom) implements also a very simple generator (linear congruential) with period =
70 \f$10^9\f$, known to have defects (the lower random bits are correlated) and it is failing the majority of the random
71 number generator tests. Therefore it should NOT be used in any statistical study.
72 
73 The following table shows some timings (in nanoseconds/call)
74 for the random numbers obtained using a macbookpro 2.6 GHz Intel Core i7 CPU:
75 
76 
77 - TRandom 3 ns/call (but this is a very BAD Generator, not to be used)
78 - TRandom2 5 ns/call
79 - TRandom3 5 ns/call
80 - ::TRandomMixMax 6 ns/call
81 - ::TRandomMixMax17 6 ns/call
82 - ::TRandomMT64 9 ns/call
83 - ::TRandomMixMax256 10 ns/call
84 - ::TRandomRanluxpp 14 ns/call
85 - ::TRandom1 80 ns/call
86 - ::TRandomRanlux48 250 ns/call
87 
88 The following methods are provided to generate random numbers disctributed according to some basic distributions:
89 
90 - Exp(Double_t tau)
91 - Integer(UInt_t imax)
92 - Gaus(Double_t mean, Double_t sigma)
93 - Rndm()
94 - Uniform(Double_t)
95 - Landau(Double_t mean, Double_t sigma)
96 - Poisson(Double_t mean)
97 - Binomial(Int_t ntot, Double_t prob)
98 
99 Random numbers distributed according to 1-d, 2-d or 3-d distributions contained in TF1, TF2 or TF3 objects can also be
100 generated. For example, to get a random number distributed following abs(sin(x)/x)*sqrt(x) you can do : \code{.cpp} TF1
101 *f1 = new TF1("f1","abs(sin(x)/x)*sqrt(x)",0,10); double r = f1->GetRandom(); \endcode or you can use the UNURAN
102 package. You need in this case to initialize UNURAN to the function you would like to generate. \code{.cpp} TUnuran u;
103  u.Init(TUnuranDistrCont(f1));
104  double r = u.Sample();
105 \endcode
106 
107 The techniques of using directly a TF1,2 or 3 function is powerful and
108 can be used to generate numbers in the defined range of the function.
109 Getting a number from a TF1,2,3 function is also quite fast.
110 UNURAN is a powerful and flexible tool which containes various methods for
111 generate random numbers for continuous distributions of one and multi-dimension.
112 It requires some set-up (initialization) phase and can be very fast when the distribution
113 parameters are not changed for every call.
114 
115 The following table shows some timings (in nanosecond/call)
116 for basic functions, TF1 functions and using UNURAN obtained running
117 the tutorial math/testrandom.C
118 Numbers have been obtained on an Intel Xeon Quad-core Harpertown (E5410) 2.33 GHz running
119 Linux SLC4 64 bit and compiled with gcc 3.4
120 
121 ~~~~
122 Distribution nanoseconds/call
123  TRandom TRandom1 TRandom2 TRandom3
124 Rndm.............. 5.000 105.000 7.000 10.000
125 RndmArray......... 4.000 104.000 6.000 9.000
126 Gaus.............. 36.000 180.000 40.000 48.000
127 Rannor............ 118.000 220.000 120.000 124.000
128 Landau............ 22.000 123.000 26.000 31.000
129 Exponential....... 93.000 198.000 98.000 104.000
130 Binomial(5,0.5)... 30.000 548.000 46.000 65.000
131 Binomial(15,0.5).. 75.000 1615.000 125.000 178.000
132 Poisson(3)........ 96.000 494.000 109.000 125.000
133 Poisson(10)....... 138.000 1236.000 165.000 203.000
134 Poisson(70)....... 818.000 1195.000 835.000 844.000
135 Poisson(100)...... 837.000 1218.000 849.000 864.000
136 GausTF1........... 83.000 180.000 87.000 88.000
137 LandauTF1......... 80.000 180.000 83.000 86.000
138 GausUNURAN........ 40.000 139.000 41.000 44.000
139 PoissonUNURAN(10). 85.000 271.000 92.000 102.000
140 PoissonUNURAN(100) 62.000 256.000 69.000 78.000
141 ~~~~
142 
143 Note that the time to generate a number from an arbitrary TF1 function
144 using TF1::GetRandom or using TUnuran is independent of the complexity of the function.
145 
146 TH1::FillRandom(TH1 *) or TH1::FillRandom(const char *tf1name)
147 can be used to fill an histogram (1-d, 2-d, 3-d from an existing histogram
148 or from an existing function.
149 
150 Note this interesting feature when working with objects.
151  You can use several TRandom objects, each with their "independent"
152  random sequence. For example, one can imagine
153 ~~~~
154  TRandom *eventGenerator = new TRandom();
155  TRandom *tracking = new TRandom();
156 ~~~~
157  `eventGenerator` can be used to generate the event kinematics.
158  tracking can be used to track the generated particles with random numbers
159  independent from eventGenerator.
160  This very interesting feature gives the possibility to work with simple
161  and very fast random number generators without worrying about
162  random number periodicity as it was the case with Fortran.
163  One can use TRandom::SetSeed to modify the seed of one generator.
164 
165 A TRandom object may be written to a Root file
166 
167 - as part of another object
168 - or with its own key (example: `gRandom->Write("Random")` ) ;
169 
170 */
171 
172 #include "TROOT.h"
173 #include "TMath.h"
174 #include "TRandom.h"
175 #include "TRandom3.h"
176 #include "TSystem.h"
177 #include "TDirectory.h"
178 #include "Math/QuantFuncMathCore.h"
179 #include "TUUID.h"
180 
182 
183 ////////////////////////////////////////////////////////////////////////////////
184 /// Default constructor. For seed see SetSeed().
185 
186 TRandom::TRandom(UInt_t seed): TNamed("Random","Default Random number generator")
187 {
188  SetSeed(seed);
189 }
190 
191 ////////////////////////////////////////////////////////////////////////////////
192 /// Default destructor. Can reset gRandom to 0 if gRandom points to this
193 /// generator.
194 
196 {
197  if (gRandom == this) gRandom = 0;
198 }
199 
200 ////////////////////////////////////////////////////////////////////////////////
201 /// Generates a random integer N according to the binomial law.
202 /// Coded from Los Alamos report LA-5061-MS.
203 ///
204 /// N is binomially distributed between 0 and ntot inclusive
205 /// with mean prob*ntot and prob is between 0 and 1.
206 ///
207 /// Note: This function should not be used when ntot is large (say >100).
208 /// The normal approximation is then recommended instead
209 /// (with mean =*ntot+0.5 and standard deviation sqrt(ntot*prob*(1-prob)).
210 
212 {
213  if (prob < 0 || prob > 1) return 0;
214  Int_t n = 0;
215  for (Int_t i=0;i<ntot;i++) {
216  if (Rndm() > prob) continue;
217  n++;
218  }
219  return n;
220 }
221 
222 ////////////////////////////////////////////////////////////////////////////////
223 /// Return a number distributed following a BreitWigner function with mean and gamma.
224 
226 {
227  Double_t rval, displ;
228  rval = 2*Rndm() - 1;
229  displ = 0.5*gamma*TMath::Tan(rval*TMath::PiOver2());
230 
231  return (mean+displ);
232 }
233 
234 ////////////////////////////////////////////////////////////////////////////////
235 /// Generates random vectors, uniformly distributed over a circle of given radius.
236 /// Input : r = circle radius
237 /// Output: x,y a random 2-d vector of length r
238 
240 {
241  Double_t phi = Uniform(0,TMath::TwoPi());
242  x = r*TMath::Cos(phi);
243  y = r*TMath::Sin(phi);
244 }
245 
246 ////////////////////////////////////////////////////////////////////////////////
247 /// Returns an exponential deviate.
248 ///
249 /// exp( -t/tau )
250 
252 {
253  Double_t x = Rndm(); // uniform on ] 0, 1 ]
254  Double_t t = -tau * TMath::Log( x ); // convert to exponential distribution
255  return t;
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////
259 /// Samples a random number from the standard Normal (Gaussian) Distribution
260 /// with the given mean and sigma.
261 /// Uses the Acceptance-complement ratio from W. Hoermann and G. Derflinger
262 /// This is one of the fastest existing method for generating normal random variables.
263 /// It is a factor 2/3 faster than the polar (Box-Muller) method used in the previous
264 /// version of TRandom::Gaus. The speed is comparable to the Ziggurat method (from Marsaglia)
265 /// implemented for example in GSL and available in the MathMore library.
266 ///
267 /// REFERENCE: - W. Hoermann and G. Derflinger (1990):
268 /// The ACR Method for generating normal random variables,
269 /// OR Spektrum 12 (1990), 181-185.
270 ///
271 /// Implementation taken from
272 /// UNURAN (c) 2000 W. Hoermann & J. Leydold, Institut f. Statistik, WU Wien
273 
275 {
276  const Double_t kC1 = 1.448242853;
277  const Double_t kC2 = 3.307147487;
278  const Double_t kC3 = 1.46754004;
279  const Double_t kD1 = 1.036467755;
280  const Double_t kD2 = 5.295844968;
281  const Double_t kD3 = 3.631288474;
282  const Double_t kHm = 0.483941449;
283  const Double_t kZm = 0.107981933;
284  const Double_t kHp = 4.132731354;
285  const Double_t kZp = 18.52161694;
286  const Double_t kPhln = 0.4515827053;
287  const Double_t kHm1 = 0.516058551;
288  const Double_t kHp1 = 3.132731354;
289  const Double_t kHzm = 0.375959516;
290  const Double_t kHzmp = 0.591923442;
291  /*zhm 0.967882898*/
292 
293  const Double_t kAs = 0.8853395638;
294  const Double_t kBs = 0.2452635696;
295  const Double_t kCs = 0.2770276848;
296  const Double_t kB = 0.5029324303;
297  const Double_t kX0 = 0.4571828819;
298  const Double_t kYm = 0.187308492 ;
299  const Double_t kS = 0.7270572718 ;
300  const Double_t kT = 0.03895759111;
301 
302  Double_t result;
303  Double_t rn,x,y,z;
304 
305  do {
306  y = Rndm();
307 
308  if (y>kHm1) {
309  result = kHp*y-kHp1; break; }
310 
311  else if (y<kZm) {
312  rn = kZp*y-1;
313  result = (rn>0) ? (1+rn) : (-1+rn);
314  break;
315  }
316 
317  else if (y<kHm) {
318  rn = Rndm();
319  rn = rn-1+rn;
320  z = (rn>0) ? 2-rn : -2-rn;
321  if ((kC1-y)*(kC3+TMath::Abs(z))<kC2) {
322  result = z; break; }
323  else {
324  x = rn*rn;
325  if ((y+kD1)*(kD3+x)<kD2) {
326  result = rn; break; }
327  else if (kHzmp-y<exp(-(z*z+kPhln)/2)) {
328  result = z; break; }
329  else if (y+kHzm<exp(-(x+kPhln)/2)) {
330  result = rn; break; }
331  }
332  }
333 
334  while (1) {
335  x = Rndm();
336  y = kYm * Rndm();
337  z = kX0 - kS*x - y;
338  if (z>0)
339  rn = 2+y/x;
340  else {
341  x = 1-x;
342  y = kYm-y;
343  rn = -(2+y/x);
344  }
345  if ((y-kAs+x)*(kCs+x)+kBs<0) {
346  result = rn; break; }
347  else if (y<x+kT)
348  if (rn*rn<4*(kB-log(x))) {
349  result = rn; break; }
350  }
351  } while(0);
352 
353  return mean + sigma * result;
354 }
355 
356 ////////////////////////////////////////////////////////////////////////////////
357 /// Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
358 /// Note that the interval contains the values of 0 and imax-1 but not imax.
359 
361 {
362  UInt_t ui;
363  ui = (UInt_t)(imax*Rndm());
364  return ui;
365 }
366 
367 ////////////////////////////////////////////////////////////////////////////////
368 /// Generate a random number following a Landau distribution
369 /// with location parameter mu and scale parameter sigma:
370 /// Landau( (x-mu)/sigma )
371 /// Note that mu is not the mpv(most probable value) of the Landa distribution
372 /// and sigma is not the standard deviation of the distribution which is not defined.
373 /// For mu =0 and sigma=1, the mpv = -0.22278
374 ///
375 /// The Landau random number generation is implemented using the
376 /// function landau_quantile(x,sigma), which provides
377 /// the inverse of the landau cumulative distribution.
378 /// landau_quantile has been converted from CERNLIB ranlan(G110).
379 
381 {
382  if (sigma <= 0) return 0;
383  Double_t x = Rndm();
385  return res;
386 }
387 
388 ////////////////////////////////////////////////////////////////////////////////
389 /// Generates a random integer N according to a Poisson law.
390 /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
391 ///
392 /// Use a different procedure according to the mean value.
393 /// The algorithm is the same used by CLHEP.
394 /// For lower value (mean < 25) use the rejection method based on
395 /// the exponential.
396 /// For higher values use a rejection method comparing with a Lorentzian
397 /// distribution, as suggested by several authors.
398 /// This routine since is returning 32 bits integer will not work for values
399 /// larger than 2*10**9.
400 /// One should then use the Trandom::PoissonD for such large values.
401 
403 {
404  Int_t n;
405  if (mean <= 0) return 0;
406  if (mean < 25) {
407  Double_t expmean = TMath::Exp(-mean);
408  Double_t pir = 1;
409  n = -1;
410  while(1) {
411  n++;
412  pir *= Rndm();
413  if (pir <= expmean) break;
414  }
415  return n;
416  }
417  // for large value we use inversion method
418  else if (mean < 1E9) {
419  Double_t em, t, y;
420  Double_t sq, alxm, g;
421  Double_t pi = TMath::Pi();
422 
423  sq = TMath::Sqrt(2.0*mean);
424  alxm = TMath::Log(mean);
425  g = mean*alxm - TMath::LnGamma(mean + 1.0);
426 
427  do {
428  do {
429  y = TMath::Tan(pi*Rndm());
430  em = sq*y + mean;
431  } while( em < 0.0 );
432 
433  em = TMath::Floor(em);
434  t = 0.9*(1.0 + y*y)* TMath::Exp(em*alxm - TMath::LnGamma(em + 1.0) - g);
435  } while( Rndm() > t );
436 
437  return static_cast<Int_t> (em);
438 
439  }
440  else {
441  // use Gaussian approximation vor very large values
442  n = Int_t(Gaus(0,1)*TMath::Sqrt(mean) + mean +0.5);
443  return n;
444  }
445 }
446 
447 ////////////////////////////////////////////////////////////////////////////////
448 /// Generates a random number according to a Poisson law.
449 /// Prob(N) = exp(-mean)*mean^N/Factorial(N)
450 ///
451 /// This function is a variant of TRandom::Poisson returning a double
452 /// instead of an integer.
453 
455 {
456  Int_t n;
457  if (mean <= 0) return 0;
458  if (mean < 25) {
459  Double_t expmean = TMath::Exp(-mean);
460  Double_t pir = 1;
461  n = -1;
462  while(1) {
463  n++;
464  pir *= Rndm();
465  if (pir <= expmean) break;
466  }
467  return static_cast<Double_t>(n);
468  }
469  // for large value we use inversion method
470  else if (mean < 1E9) {
471  Double_t em, t, y;
472  Double_t sq, alxm, g;
473  Double_t pi = TMath::Pi();
474 
475  sq = TMath::Sqrt(2.0*mean);
476  alxm = TMath::Log(mean);
477  g = mean*alxm - TMath::LnGamma(mean + 1.0);
478 
479  do {
480  do {
481  y = TMath::Tan(pi*Rndm());
482  em = sq*y + mean;
483  } while( em < 0.0 );
484 
485  em = TMath::Floor(em);
486  t = 0.9*(1.0 + y*y)* TMath::Exp(em*alxm - TMath::LnGamma(em + 1.0) - g);
487  } while( Rndm() > t );
488 
489  return em;
490 
491  } else {
492  // use Gaussian approximation vor very large values
493  return Gaus(0,1)*TMath::Sqrt(mean) + mean +0.5;
494  }
495 }
496 
497 ////////////////////////////////////////////////////////////////////////////////
498 /// Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
499 
501 {
502  Double_t r, x, y, z;
503 
504  y = Rndm();
505  z = Rndm();
506  x = z * 6.28318530717958623;
507  r = TMath::Sqrt(-2*TMath::Log(y));
508  a = (Float_t)(r * TMath::Sin(x));
509  b = (Float_t)(r * TMath::Cos(x));
510 }
511 
512 ////////////////////////////////////////////////////////////////////////////////
513 /// Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
514 
516 {
517  Double_t r, x, y, z;
518 
519  y = Rndm();
520  z = Rndm();
521  x = z * 6.28318530717958623;
522  r = TMath::Sqrt(-2*TMath::Log(y));
523  a = r * TMath::Sin(x);
524  b = r * TMath::Cos(x);
525 }
526 
527 ////////////////////////////////////////////////////////////////////////////////
528 /// Reads saved random generator status from filename.
529 
530 void TRandom::ReadRandom(const char *filename)
531 {
532  if (!gDirectory) return;
533  char *fntmp = gSystem->ExpandPathName(filename);
534  TDirectory *file = (TDirectory*)gROOT->ProcessLine(Form("TFile::Open(\"%s\");",fntmp));
535  delete [] fntmp;
536  if(file && file->GetFile()) {
537  gDirectory->ReadTObject(this,GetName());
538  delete file;
539  }
540 }
541 
542 ////////////////////////////////////////////////////////////////////////////////
543 /// Machine independent random number generator.
544 /// Based on the BSD Unix (Rand) Linear congrential generator.
545 /// Produces uniformly-distributed floating points between 0 and 1.
546 /// Identical sequence on all machines of >= 32 bits.
547 /// Periodicity = 2**31, generates a number in (0,1).
548 /// Note that this is a generator which is known to have defects
549 /// (the lower random bits are correlated) and therefore should NOT be
550 /// used in any statistical study).
551 
553 {
554 #ifdef OLD_TRANDOM_IMPL
555  const Double_t kCONS = 4.6566128730774E-10;
556  const Int_t kMASK24 = 2147483392;
557 
558  fSeed *= 69069;
559  UInt_t jy = (fSeed&kMASK24); // Set lower 8 bits to zero to assure exact float
560  if (jy) return kCONS*jy;
561  return Rndm();
562 #endif
563 
564  // kCONS = 1./2147483648 = 1./(RAND_MAX+1) and RAND_MAX= 0x7fffffffUL
565  const Double_t kCONS = 4.6566128730774E-10; // (1/pow(2,31)
566  fSeed = (1103515245 * fSeed + 12345) & 0x7fffffffUL;
567 
568  if (fSeed) return kCONS*fSeed;
569  return Rndm();
570 }
571 
572 ////////////////////////////////////////////////////////////////////////////////
573 /// Return an array of n random numbers uniformly distributed in ]0,1].
574 
576 {
577  const Double_t kCONS = 4.6566128730774E-10; // (1/pow(2,31))
578  Int_t i=0;
579  while (i<n) {
580  fSeed = (1103515245 * fSeed + 12345) & 0x7fffffffUL;
581  if (fSeed) {array[i] = kCONS*fSeed; i++;}
582  }
583 }
584 
585 ////////////////////////////////////////////////////////////////////////////////
586 /// Return an array of n random numbers uniformly distributed in ]0,1].
587 
589 {
590  const Double_t kCONS = 4.6566128730774E-10; // (1/pow(2,31))
591  Int_t i=0;
592  while (i<n) {
593  fSeed = (1103515245 * fSeed + 12345) & 0x7fffffffUL;
594  if (fSeed) {array[i] = Float_t(kCONS*fSeed); i++;}
595  }
596 }
597 
598 ////////////////////////////////////////////////////////////////////////////////
599 /// Set the random generator seed. Note that default value is zero, which is
600 /// different than the default value used when constructing the class.
601 /// If the seed is zero the seed is set to a random value
602 /// which in case of TRandom depends on the lowest 4 bytes of TUUID
603 /// The UUID will be identical if SetSeed(0) is called with time smaller than 100 ns
604 /// Instead if a different generator implementation is used (TRandom1, 2 or 3)
605 /// the seed is generated using a 128 bit UUID. This results in different seeds
606 /// and then random sequence for every SetSeed(0) call.
607 
609 {
610  if( seed==0 ) {
611  TUUID u;
612  UChar_t uuid[16];
613  u.GetUUID(uuid);
614  fSeed = UInt_t(uuid[3])*16777216 + UInt_t(uuid[2])*65536 + UInt_t(uuid[1])*256 + UInt_t(uuid[0]);
615  } else {
616  fSeed = seed;
617  }
618 }
619 
620 ////////////////////////////////////////////////////////////////////////////////
621 /// Get the random generator seed.
622 /// Note that this function returns the given seed only when using
623 /// as random generator engine TRandom itself, which is an LCG generator
624 /// and it has as seed (state) only one 32 bit word.
625 /// In case of the other generators GetSeed will return one of the state elements and not the
626 /// given seed. See the documentation of the corresponding generator used
627 /// (for example TRandom3::GetSeed() when using TRandom3 or gRandom.
628 /// If one needs to save the generator seed in order to be used later for obtaining reproducible
629 /// numbers, one should store the full generator, either in a file or in memory in a separate TRandom
630 /// object. Here is an example on how to store reproducible states:
631 /// ```
632 /// // set a unique seed
633 /// gRandom->SetSeed(0);
634 /// // save generator state in a different TRandom instance
635 /// TRandom* rngSaved = static_cast<TRandom*>(gRandom->Clone());
636 /// // now both rngSaved and gRandom will produce the same sequence of numbers
637 /// for (int i = 0; i < 10; ++i )
638 /// std::cout << "genrated number from gRandom : " << gRandom->Rndm() << " from saved generator " <<
639 /// rngSaved->Rndm() << std::endl;
640 /// ```
642 {
643  return fSeed;
644 }
645 
646 ////////////////////////////////////////////////////////////////////////////////
647 /// Generates random vectors, uniformly distributed over the surface
648 /// of a sphere of given radius.
649 /// Input : r = sphere radius
650 /// Output: x,y,z a random 3-d vector of length r
651 /// Method: (based on algorithm suggested by Knuth and attributed to Robert E Knop)
652 /// which uses less random numbers than the CERNLIB RN23DIM algorithm
653 
655 {
656  Double_t a=0,b=0,r2=1;
657  while (r2 > 0.25) {
658  a = Rndm() - 0.5;
659  b = Rndm() - 0.5;
660  r2 = a*a + b*b;
661  }
662  z = r* ( -1. + 8.0 * r2 );
663 
664  Double_t scale = 8.0 * r * TMath::Sqrt(0.25 - r2);
665  x = a*scale;
666  y = b*scale;
667 }
668 
669 ////////////////////////////////////////////////////////////////////////////////
670 /// Returns a uniform deviate on the interval (0, x1).
671 
673 {
674  Double_t ans = Rndm();
675  return x1*ans;
676 }
677 
678 ////////////////////////////////////////////////////////////////////////////////
679 /// Returns a uniform deviate on the interval (x1, x2).
680 
682 {
683  Double_t ans= Rndm();
684  return x1 + (x2-x1)*ans;
685 }
686 
687 ////////////////////////////////////////////////////////////////////////////////
688 /// Writes random generator status to filename.
689 
690 void TRandom::WriteRandom(const char *filename) const
691 {
692  if (!gDirectory) return;
693  char *fntmp = gSystem->ExpandPathName(filename);
694  TDirectory *file = (TDirectory*)gROOT->ProcessLine(Form("TFile::Open(\"%s\",\"recreate\");",fntmp));
695  delete [] fntmp;
696  if(file && file->GetFile()) {
697  gDirectory->WriteTObject(this,GetName());
698  delete file;
699  }
700 }
ROOT::Math::Cephes::gamma
double gamma(double x)
Definition: SpecFuncCephes.cxx:339
n
const Int_t n
Definition: legend1.C:16
TRandom::Gaus
virtual Double_t Gaus(Double_t mean=0, Double_t sigma=1)
Samples a random number from the standard Normal (Gaussian) Distribution with the given mean and sigm...
Definition: TRandom.cxx:274
TDirectory.h
TMath::Cos
Double_t Cos(Double_t)
Definition: TMath.h:643
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
Form
char * Form(const char *fmt,...)
r
ROOT::R::TRInterface & r
Definition: Object.C:4
TMath::Log
Double_t Log(Double_t x)
Definition: TMath.h:760
TMath::Sqrt
Double_t Sqrt(Double_t x)
Definition: TMath.h:691
exp
double exp(double)
TMath::Tan
Double_t Tan(Double_t)
Definition: TMath.h:647
TRandom::PoissonD
virtual Double_t PoissonD(Double_t mean)
Generates a random number according to a Poisson law.
Definition: TRandom.cxx:454
TRandom.h
Float_t
float Float_t
Definition: RtypesCore.h:57
log
double log(double)
TMath::Exp
Double_t Exp(Double_t x)
Definition: TMath.h:727
TRandom::fSeed
UInt_t fSeed
Definition: TRandom.h:30
TMath::PiOver2
constexpr Double_t PiOver2()
Definition: TMath.h:51
Int_t
int Int_t
Definition: RtypesCore.h:45
TRandom::Uniform
virtual Double_t Uniform(Double_t x1=1)
Returns a uniform deviate on the interval (0, x1).
Definition: TRandom.cxx:672
x
Double_t x[n]
Definition: legend1.C:17
TMath::Abs
Short_t Abs(Short_t d)
Definition: TMathBase.h:120
TMath::LnGamma
Double_t LnGamma(Double_t z)
Computation of ln[gamma(z)] for all z.
Definition: TMath.cxx:486
TRandom::WriteRandom
virtual void WriteRandom(const char *filename) const
Writes random generator status to filename.
Definition: TRandom.cxx:690
b
#define b(i)
Definition: RSha256.hxx:100
QuantFuncMathCore.h
x1
static const double x1[5]
Definition: RooGaussKronrodIntegrator1D.cxx:346
TROOT.h
TUUID.h
TRandom::Rannor
virtual void Rannor(Float_t &a, Float_t &b)
Return 2 numbers distributed following a gaussian with mean=0 and sigma=1.
Definition: TRandom.cxx:500
TRandom::Sphere
virtual void Sphere(Double_t &x, Double_t &y, Double_t &z, Double_t r)
Generates random vectors, uniformly distributed over the surface of a sphere of given radius.
Definition: TRandom.cxx:654
TMath::Pi
constexpr Double_t Pi()
Definition: TMath.h:37
TRandom::BreitWigner
virtual Double_t BreitWigner(Double_t mean=0, Double_t gamma=1)
Return a number distributed following a BreitWigner function with mean and gamma.
Definition: TRandom.cxx:225
TRandom::TRandom
TRandom(UInt_t seed=65539)
Default constructor. For seed see SetSeed().
Definition: TRandom.cxx:186
TRandom::Binomial
virtual Int_t Binomial(Int_t ntot, Double_t prob)
Generates a random integer N according to the binomial law.
Definition: TRandom.cxx:211
TRandom
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:27
TSystem.h
TMath::Floor
Double_t Floor(Double_t x)
Definition: TMath.h:703
a
auto * a
Definition: textangle.C:12
TNamed
The TNamed class is the base class for all named ROOT classes.
Definition: TNamed.h:29
gDirectory
#define gDirectory
Definition: TDirectory.h:236
TRandom::RndmArray
virtual void RndmArray(Int_t n, Float_t *array)
Return an array of n random numbers uniformly distributed in ]0,1].
Definition: TRandom.cxx:588
gRandom
R__EXTERN TRandom * gRandom
Definition: TRandom.h:62
TRandom::SetSeed
virtual void SetSeed(ULong_t seed=0)
Set the random generator seed.
Definition: TRandom.cxx:608
TRandom3.h
TMath::Sin
Double_t Sin(Double_t)
Definition: TMath.h:639
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
TRandom::Rndm
virtual Double_t Rndm()
Machine independent random number generator.
Definition: TRandom.cxx:552
TRandom::Landau
virtual Double_t Landau(Double_t mean=0, Double_t sigma=1)
Generate a random number following a Landau distribution with location parameter mu and scale paramet...
Definition: TRandom.cxx:380
y
Double_t y[n]
Definition: legend1.C:17
TRandom::ReadRandom
virtual void ReadRandom(const char *filename)
Reads saved random generator status from filename.
Definition: TRandom.cxx:530
ULong_t
unsigned long ULong_t
Definition: RtypesCore.h:55
TUUID
This class defines a UUID (Universally Unique IDentifier), also known as GUIDs (Globally Unique IDent...
Definition: TUUID.h:42
TSystem::ExpandPathName
virtual Bool_t ExpandPathName(TString &path)
Expand a pathname getting rid of special shell characters like ~.
Definition: TSystem.cxx:1272
TRandom::Integer
virtual UInt_t Integer(UInt_t imax)
Returns a random integer uniformly distributed on the interval [ 0, imax-1 ].
Definition: TRandom.cxx:360
unsigned int
TMath::TwoPi
constexpr Double_t TwoPi()
Definition: TMath.h:44
gSystem
R__EXTERN TSystem * gSystem
Definition: TSystem.h:559
sigma
const Double_t sigma
Definition: h1analysisProxy.h:11
Double_t
double Double_t
Definition: RtypesCore.h:59
TRandom::Circle
virtual void Circle(Double_t &x, Double_t &y, Double_t r)
Generates random vectors, uniformly distributed over a circle of given radius.
Definition: TRandom.cxx:239
TGeant4Unit::pi
static constexpr double pi
Definition: TGeant4SystemOfUnits.h:67
TRandom::Poisson
virtual Int_t Poisson(Double_t mean)
Generates a random integer N according to a Poisson law.
Definition: TRandom.cxx:402
TRandom::~TRandom
virtual ~TRandom()
Default destructor.
Definition: TRandom.cxx:195
file
Definition: file.py:1
UChar_t
unsigned char UChar_t
Definition: RtypesCore.h:38
TDirectory
Describe directory structure in memory.
Definition: TDirectory.h:40
x2
static const double x2[5]
Definition: RooGaussKronrodIntegrator1D.cxx:364
ROOT::Math::landau_quantile
double landau_quantile(double z, double xi=1)
Inverse ( ) of the cumulative distribution function of the lower tail of the Landau distribution (lan...
Definition: QuantFuncMathCore.cxx:189
TRandom::Exp
virtual Double_t Exp(Double_t tau)
Returns an exponential deviate.
Definition: TRandom.cxx:251
TNamed::GetName
virtual const char * GetName() const
Returns name of object.
Definition: TNamed.h:47
TMath.h
gROOT
#define gROOT
Definition: TROOT.h:406
int
TRandom::GetSeed
virtual UInt_t GetSeed() const
Get the random generator seed.
Definition: TRandom.cxx:641
TUUID::GetUUID
void GetUUID(UChar_t uuid[16]) const
Return uuid in specified buffer (16 byte = 128 bits).
Definition: TUUID.cxx:694
g
#define g(i)
Definition: RSha256.hxx:105