Logo ROOT   6.13/01
Reference Guide
TRandom2.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: Rene Brun, Lorenzo Moneta 17/05/2006
3 
4 /**
5 
6 \class TRandom2
7 
8 Random number generator class based on the maximally quidistributed combined
9 Tausworthe generator by L'Ecuyer.
10 
11 The period of the generator is 2**88 (about 10**26) and it uses only 3 words
12 for the state.
13 
14 For more information see:
15 P. L'Ecuyer, Mathematics of Computation, 65, 213 (1996)
16 P. L'Ecuyer, Mathematics of Computation, 68, 225 (1999)
17 
18 The publication are available online at
19  [http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme.ps]
20  [http://www.iro.umontreal.ca/~lecuyer/myftp/papers/tausme2.ps]
21 
22 @ingroup Random
23 
24 */
25 
26 #include "TRandom2.h"
27 #include "TRandom3.h"
28 #include "TUUID.h"
29 
30 
31 ClassImp(TRandom2);
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// Default constructor
35 
36 TRandom2::TRandom2(UInt_t seed)
37 {
38  SetName("Random2");
39  SetTitle("Random number generator with period of about 10**26");
40  SetSeed(seed);
41 }
42 
43 ////////////////////////////////////////////////////////////////////////////////
44 /// Default destructor
45 
47 {
48 }
49 
50 ////////////////////////////////////////////////////////////////////////////////
51 /// TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers
52 /// Use a mask of 0xffffffffUL to make in work on 64 bit machines
53 /// Periodicity of about 10**26
54 /// Generate number in interval (0,1) : 0 and 1 are not included in the interval
55 
56 Double_t TRandom2::Rndm()
57 {
58 #define TAUSWORTHE(s,a,b,c,d) (((s &c) <<d) & 0xffffffffUL ) ^ ((((s <<a) & 0xffffffffUL )^s) >>b)
59 
60  // scale by 1./(Max<UINT> + 1) = 1./4294967296
61  const double kScale = 2.3283064365386963e-10; // range in 32 bit ( 1/(2**32)
62 
63  fSeed = TAUSWORTHE (fSeed, 13, 19, 4294967294UL, 12);
64  fSeed1 = TAUSWORTHE (fSeed1, 2, 25, 4294967288UL, 4);
65  fSeed2 = TAUSWORTHE (fSeed2, 3, 11, 4294967280UL, 17);
66 
67  UInt_t iy = fSeed ^ fSeed1 ^ fSeed2;
68  if (iy) return kScale*static_cast<Double_t>(iy);
69  return Rndm();
70 }
71 
72 ////////////////////////////////////////////////////////////////////////////////
73 /// Return an array of n random numbers uniformly distributed in ]0,1]
74 
75 void TRandom2::RndmArray(Int_t n, Float_t *array)
76 {
77  const double kScale = 2.3283064365386963e-10; // range in 32 bit ( 1/(2**32)
78 
79  UInt_t iy;
80 
81  for(Int_t i=0; i<n; i++) {
82  fSeed = TAUSWORTHE (fSeed, 13, 19, 4294967294UL, 12);
83  fSeed1 = TAUSWORTHE (fSeed1, 2, 25, 4294967288UL, 4);
84  fSeed2 = TAUSWORTHE (fSeed2, 3, 11, 4294967280UL, 17);
85 
86  iy = fSeed ^ fSeed1 ^ fSeed2;
87  if (iy) array[i] = (Float_t)(kScale*static_cast<Double_t>(iy));
88  else array[i] = Rndm();
89  }
90 }
91 
92 ////////////////////////////////////////////////////////////////////////////////
93 /// Return an array of n random numbers uniformly distributed in ]0,1]
94 
95 void TRandom2::RndmArray(Int_t n, Double_t *array)
96 {
97  const double kScale = 2.3283064365386963e-10; // range in 32 bit ( 1/(2**32)
98 
99  UInt_t iy;
100  for(Int_t i=0; i<n; i++) {
101  fSeed = TAUSWORTHE (fSeed, 13, 19, 4294967294UL, 12);
102  fSeed1 = TAUSWORTHE (fSeed1, 2, 25, 4294967288UL, 4);
103  fSeed2 = TAUSWORTHE (fSeed2, 3, 11, 4294967280UL, 17);
104 
105  iy = fSeed ^ fSeed1 ^ fSeed2;
106  if (iy) array[i] = kScale*static_cast<Double_t>(iy);
107  else array[i] = Rndm();
108  }
109 }
110 
111 ////////////////////////////////////////////////////////////////////////////////
112 /// Set the generator seed.
113 /// If the seed given is zero, generate automatically seed values which
114 /// are different every time by using TRandom3 and TUUID
115 /// If a seed is given generate the other two needed for the generator state using
116 /// a linear congruential generator
117 /// The only condition, stated at the end of the 1999 L'Ecuyer paper is that the seeds
118 /// must be greater than 1,7 and 15.
119 
120 void TRandom2::SetSeed(ULong_t seed)
121 {
122 #define LCG(n) ((69069 * n) & 0xffffffffUL) // linear congurential generator
123 
124  if (seed > 0) {
125  fSeed = LCG (seed);
126  if (fSeed < 2) fSeed += 2UL;
127  fSeed1 = LCG (fSeed);
128  if (fSeed1 < 8) fSeed1 += 8UL;
129  fSeed2 = LCG (fSeed1);
130  if (fSeed2 < 16) fSeed2 += 16UL;
131  } else {
132  // initialize using a TUUID
133  TUUID u;
134  UChar_t uuid[16];
135  u.GetUUID(uuid);
136  fSeed = UInt_t(uuid[3])*16777216 + UInt_t(uuid[2])*65536 + UInt_t(uuid[1])*256 + UInt_t(uuid[0]);
137  fSeed1 = UInt_t(uuid[7])*16777216 + UInt_t(uuid[6])*65536 + UInt_t(uuid[5])*256 + UInt_t(uuid[4]);
138  fSeed2 = UInt_t(uuid[11])*16777216 + UInt_t(uuid[10])*65536 + UInt_t(uuid[9])*256 + UInt_t(uuid[8]);
139  // use also the other bytes
140  UInt_t seed3 = UInt_t(uuid[15])*16777216 + UInt_t(uuid[14])*65536 + UInt_t(uuid[13])*256 + UInt_t(uuid[12]);
141  fSeed2 += seed3;
142 
143 
144  // TRandom r3(0);
145  // fSeed = static_cast<UInt_t> (4294967296.*r3.Rndm());
146  // fSeed1 = static_cast<UInt_t> (4294967296.*r3.Rndm());
147  // fSeed2 = static_cast<UInt_t> (4294967296.*r3.Rndm());
148 
149  if (fSeed < 2) fSeed += 2UL;
150  if (fSeed1 < 8) fSeed1 += 8UL;
151  if (fSeed2 < 16) fSeed2 += 16UL;
152  }
153 
154  // "warm it up" by calling it 6 times
155  for (int i = 0; i < 6; ++i)
156  Rndm();
157 
158  return;
159 }
160 
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:27
UInt_t fSeed2
Definition: TRandom2.h:31
virtual void SetSeed(ULong_t seed=0)
Set the generator seed.
Definition: TRandom2.cxx:120
UInt_t fSeed1
Definition: TRandom2.h:30
virtual ~TRandom2()
Default destructor.
Definition: TRandom2.cxx:46
virtual void RndmArray(Int_t n, Float_t *array)
Return an array of n random numbers uniformly distributed in ]0,1].
Definition: TRandom2.cxx:75
virtual Double_t Rndm()
TausWorth generator from L&#39;Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:56
UInt_t fSeed
Definition: TRandom.h:30
#define LCG(n)
TRandom2(UInt_t seed=1)
Default constructor.
Definition: TRandom2.cxx:36
#define TAUSWORTHE(s, a, b, c, d)