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