Logo ROOT  
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 
32 
33 ////////////////////////////////////////////////////////////////////////////////
34 /// Default constructor
35 
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 
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 
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 
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 /// Note that after seeting the seed the generator is warmed up by calling it internally few
120 /// times therefore the returned seed in TRandom2::GetSeed will be a different value.
121 /// For this generator the user will have to store the provided seed externally
122 /// if he wants to reproduce the random sequence
124 {
125 #define LCG(n) ((69069 * n) & 0xffffffffUL) // linear congurential generator
126 
127  if (seed > 0) {
128  fSeed = LCG (seed);
129  if (fSeed < 2) fSeed += 2UL;
130  fSeed1 = LCG (fSeed);
131  if (fSeed1 < 8) fSeed1 += 8UL;
132  fSeed2 = LCG (fSeed1);
133  if (fSeed2 < 16) fSeed2 += 16UL;
134  } else {
135  // initialize using a TUUID
136  TUUID u;
137  UChar_t uuid[16];
138  u.GetUUID(uuid);
139  fSeed = UInt_t(uuid[3])*16777216 + UInt_t(uuid[2])*65536 + UInt_t(uuid[1])*256 + UInt_t(uuid[0]);
140  fSeed1 = UInt_t(uuid[7])*16777216 + UInt_t(uuid[6])*65536 + UInt_t(uuid[5])*256 + UInt_t(uuid[4]);
141  fSeed2 = UInt_t(uuid[11])*16777216 + UInt_t(uuid[10])*65536 + UInt_t(uuid[9])*256 + UInt_t(uuid[8]);
142  // use also the other bytes
143  UInt_t seed3 = UInt_t(uuid[15])*16777216 + UInt_t(uuid[14])*65536 + UInt_t(uuid[13])*256 + UInt_t(uuid[12]);
144  fSeed2 += seed3;
145 
146 
147  // TRandom r3(0);
148  // fSeed = static_cast<UInt_t> (4294967296.*r3.Rndm());
149  // fSeed1 = static_cast<UInt_t> (4294967296.*r3.Rndm());
150  // fSeed2 = static_cast<UInt_t> (4294967296.*r3.Rndm());
151 
152  if (fSeed < 2) fSeed += 2UL;
153  if (fSeed1 < 8) fSeed1 += 8UL;
154  if (fSeed2 < 16) fSeed2 += 16UL;
155  }
156 
157  // "warm it up" by calling it 6 times
158  for (int i = 0; i < 6; ++i)
159  Rndm();
160 
161  return;
162 }
n
const Int_t n
Definition: legend1.C:16
TRandom2::fSeed2
UInt_t fSeed2
Definition: TRandom2.h:37
TNamed::SetName
virtual void SetName(const char *name)
Set the name of the TNamed.
Definition: TNamed.cxx:140
ClassImp
#define ClassImp(name)
Definition: Rtypes.h:364
TRandom2.h
LCG
#define LCG(n)
Float_t
float Float_t
Definition: RtypesCore.h:57
TRandom::fSeed
UInt_t fSeed
Definition: TRandom.h:36
TRandom2::Rndm
virtual Double_t Rndm()
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:56
TRandom2::fSeed1
UInt_t fSeed1
Definition: TRandom2.h:36
TUUID.h
TRandom2
Definition: TRandom2.h:27
TRandom3.h
UInt_t
unsigned int UInt_t
Definition: RtypesCore.h:46
ULong_t
unsigned long ULong_t
Definition: RtypesCore.h:55
TUUID
Definition: TUUID.h:42
TAUSWORTHE
#define TAUSWORTHE(s, a, b, c, d)
TNamed::SetTitle
virtual void SetTitle(const char *title="")
Set the title of the TNamed.
Definition: TNamed.cxx:164
TRandom2::TRandom2
TRandom2(UInt_t seed=1)
Default constructor.
Definition: TRandom2.cxx:36
unsigned int
TRandom2::SetSeed
virtual void SetSeed(ULong_t seed=0)
Set the generator seed.
Definition: TRandom2.cxx:123
Double_t
double Double_t
Definition: RtypesCore.h:59
UChar_t
unsigned char UChar_t
Definition: RtypesCore.h:38
TRandom2::~TRandom2
virtual ~TRandom2()
Default destructor.
Definition: TRandom2.cxx:46
kScale
const Float_t kScale
Definition: TASImage.cxx:130
TRandom2::RndmArray
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
int
TUUID::GetUUID
void GetUUID(UChar_t uuid[16]) const
Return uuid in specified buffer (16 byte = 128 bits).
Definition: TUUID.cxx:686