ROOT  6.06/09
Reference Guide
TRandom3.cxx
Go to the documentation of this file.
1 // @(#)root/mathcore:$Id$
2 // Author: Peter Malzacher 31/08/99
3 
4 /**
5 
6 \class TRandom3
7 
8 Random number generator class based on
9  M. Matsumoto and T. Nishimura,
10  Mersenne Twister: A 623-diminsionally equidistributed
11  uniform pseudorandom number generator
12  ACM Transactions on Modeling and Computer Simulation,
13  Vol. 8, No. 1, January 1998, pp 3--30.
14 
15 For more information see the Mersenne Twister homepage
16  [http://www.math.keio.ac.jp/~matumoto/emt.html]
17 
18 Advantage:
19 
20 - large period 2**19937 -1
21 - relativly fast (slightly slower than TRandom1 and TRandom2 but much faster than TRandom1)
22 
23 Drawback: a relative large internal state of 624 integers
24 
25 @ingroup Random
26 
27 */
28 
29 //////////////////////////////////////////////////////////////////////
30 // Aug.99 ROOT implementation based on CLHEP by P.Malzacher
31 //
32 // the original code contains the following copyright notice:
33 /* This library is free software; you can redistribute it and/or */
34 /* modify it under the terms of the GNU Library General Public */
35 /* License as published by the Free Software Foundation; either */
36 /* version 2 of the License, or (at your option) any later */
37 /* version. */
38 /* This library is distributed in the hope that it will be useful, */
39 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */
40 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
41 /* See the GNU Library General Public License for more details. */
42 /* You should have received a copy of the GNU Library General */
43 /* Public License along with this library; if not, write to the */
44 /* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
45 /* 02111-1307 USA */
46 /* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
47 /* When you use this, send an email to: matumoto@math.keio.ac.jp */
48 /* with an appropriate reference to your work. */
49 /////////////////////////////////////////////////////////////////////
50 
51 #include "TRandom3.h"
52 #include "TRandom2.h"
53 #include "TClass.h"
54 #include "TUUID.h"
55 
56 TRandom *gRandom = new TRandom3();
57 #ifdef R__COMPLETE_MEM_TERMINATION
58 namespace {
59  struct TRandomCleanup {
60  ~TRandomCleanup() { delete gRandom; gRandom = 0; }
61  };
62  static TRandomCleanup gCleanupRandom;
63 }
64 #endif
65 
67 
68 ////////////////////////////////////////////////////////////////////////////////
69 ///*-*-*-*-*-*-*-*-*-*-*default constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
70 /// If seed is 0, the seed is automatically computed via a TUUID object.
71 /// In this case the seed is guaranteed to be unique in space and time.
72 
74 {
75  SetName("Random3");
76  SetTitle("Random number generator: Mersenne Twister");
77  SetSeed(seed);
78 }
79 
80 ////////////////////////////////////////////////////////////////////////////////
81 ///*-*-*-*-*-*-*-*-*-*-*default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
82 ///*-* ==================
83 
85 {
86 }
87 
88 ////////////////////////////////////////////////////////////////////////////////
89 /// Machine independent random number generator.
90 /// Produces uniformly-distributed floating points in (0,1)
91 /// Method: Mersenne Twister
92 
94 {
95  UInt_t y;
96 
97  const Int_t kM = 397;
98  const Int_t kN = 624;
99  const UInt_t kTemperingMaskB = 0x9d2c5680;
100  const UInt_t kTemperingMaskC = 0xefc60000;
101  const UInt_t kUpperMask = 0x80000000;
102  const UInt_t kLowerMask = 0x7fffffff;
103  const UInt_t kMatrixA = 0x9908b0df;
104 
105  if (fCount624 >= kN) {
106  Int_t i;
107 
108  for (i=0; i < kN-kM; i++) {
109  y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
110  fMt[i] = fMt[i+kM] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
111  }
112 
113  for ( ; i < kN-1 ; i++) {
114  y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
115  fMt[i] = fMt[i+kM-kN] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
116  }
117 
118  y = (fMt[kN-1] & kUpperMask) | (fMt[0] & kLowerMask);
119  fMt[kN-1] = fMt[kM-1] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
120  fCount624 = 0;
121  }
122 
123  y = fMt[fCount624++];
124  y ^= (y >> 11);
125  y ^= ((y << 7 ) & kTemperingMaskB );
126  y ^= ((y << 15) & kTemperingMaskC );
127  y ^= (y >> 18);
128 
129  // 2.3283064365386963e-10 == 1./(max<UINt_t>+1) -> then returned value cannot be = 1.0
130  if (y) return ( (Double_t) y * 2.3283064365386963e-10); // * Power(2,-32)
131  return Rndm();
132 }
133 
134 ////////////////////////////////////////////////////////////////////////////////
135 /// Return an array of n random numbers uniformly distributed in ]0,1]
136 
138 {
139  for(Int_t i=0; i<n; i++) array[i]=(Float_t)Rndm();
140 }
141 
142 ////////////////////////////////////////////////////////////////////////////////
143 /// Return an array of n random numbers uniformly distributed in ]0,1]
144 
146 {
147  Int_t k = 0;
148 
149  UInt_t y;
150 
151  const Int_t kM = 397;
152  const Int_t kN = 624;
153  const UInt_t kTemperingMaskB = 0x9d2c5680;
154  const UInt_t kTemperingMaskC = 0xefc60000;
155  const UInt_t kUpperMask = 0x80000000;
156  const UInt_t kLowerMask = 0x7fffffff;
157  const UInt_t kMatrixA = 0x9908b0df;
158 
159  while (k < n) {
160  if (fCount624 >= kN) {
161  Int_t i;
162 
163  for (i=0; i < kN-kM; i++) {
164  y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
165  fMt[i] = fMt[i+kM] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
166  }
167 
168  for ( ; i < kN-1 ; i++) {
169  y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
170  fMt[i] = fMt[i+kM-kN] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
171  }
172 
173  y = (fMt[kN-1] & kUpperMask) | (fMt[0] & kLowerMask);
174  fMt[kN-1] = fMt[kM-1] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
175  fCount624 = 0;
176  }
177 
178  y = fMt[fCount624++];
179  y ^= (y >> 11);
180  y ^= ((y << 7 ) & kTemperingMaskB );
181  y ^= ((y << 15) & kTemperingMaskC );
182  y ^= (y >> 18);
183 
184  if (y) {
185  array[k] = Double_t( y * 2.3283064365386963e-10); // * Power(2,-32)
186  k++;
187  }
188  }
189 }
190 
191 ////////////////////////////////////////////////////////////////////////////////
192 /// Set the random generator sequence
193 /// if seed is 0 (default value) a TUUID is generated and used to fill
194 /// the first 8 integers of the seed array.
195 /// In this case the seed is guaranteed to be unique in space and time.
196 /// Use upgraded seeding procedure to fix a known problem when seeding with values
197 /// with many zero in the bit pattern (like 2**28).
198 /// see http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/MT2002/emt19937ar.html
199 
201 {
202  TRandom::SetSeed(seed);
203  fCount624 = 624;
204  if (seed > 0) {
205  fMt[0] = fSeed;
206 
207  // use multipliers from Knuth's "Art of Computer Programming" Vol. 2, 3rd Ed. p.106
208  for(Int_t i=1; i<624; i++) {
209  fMt[i] = (1812433253 * ( fMt[i-1] ^ ( fMt[i-1] >> 30)) + i );
210  }
211 
212  } else {
213 
214  // use TRandom2 (which is based on TUUId to generate the seed
215  // TRandom2 works fairly well and has been tested against example
216  // layout in https://savannah.cern.ch/bugs/?99516
217  TRandom2 r(0);
218  for (Int_t i = 0; i< 624; i++) {
219  fMt[i] = static_cast<UInt_t> (4294967296.*r.Rndm());
220  }
221  // warm up the generator calling it 10 times
222  for (Int_t i = 0; i < 10; ++i) Rndm();
223  }
224 
225 
226 }
227 
228 ////////////////////////////////////////////////////////////////////////////////
229 /// Stream an object of class TRandom3.
230 
231 void TRandom3::Streamer(TBuffer &R__b)
232 {
233  if (R__b.IsReading()) {
234  UInt_t R__s, R__c;
235  Version_t R__v = R__b.ReadVersion(&R__s, &R__c);
236  if (R__v > 1) {
237  R__b.ReadClassBuffer(TRandom3::Class(), this, R__v, R__s, R__c);
238  return;
239  }
240  //====process old versions before automatic schema evolution
241  TRandom::Streamer(R__b);
242  R__b.ReadStaticArray(fMt);
243  R__b >> fCount624;
244  R__b.CheckByteCount(R__s, R__c, TRandom3::IsA());
245  //====end of old versions
246 
247  } else {
248  R__b.WriteClassBuffer(TRandom3::Class(),this);
249  }
250 }
virtual Int_t WriteClassBuffer(const TClass *cl, void *pointer)=0
Random number generator class based on M.
Definition: TRandom3.h:29
Bool_t IsReading() const
Definition: TBuffer.h:81
short Version_t
Definition: RtypesCore.h:61
float Float_t
Definition: RtypesCore.h:53
virtual ~TRandom3()
*-*-*-*-*-*-*-*-*-*-*default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-* *-* ================== ...
Definition: TRandom3.cxx:84
Random number generator class based on the maximally quidistributed combined Tausworthe generator by ...
Definition: TRandom2.h:29
virtual Double_t Rndm(Int_t i=0)
TausWorth generator from L'Ecuyer, uses as seed 3x32bits integers Use a mask of 0xffffffffUL to make ...
Definition: TRandom2.cxx:58
Buffer base class used for serializing objects.
Definition: TBuffer.h:40
virtual Int_t CheckByteCount(UInt_t startpos, UInt_t bcnt, const TClass *clss)=0
int Int_t
Definition: RtypesCore.h:41
virtual void SetSeed(UInt_t seed=0)
Set the random generator seed.
Definition: TRandom.cxx:568
virtual Int_t ReadStaticArray(Bool_t *b)=0
void Class()
Definition: Class.C:29
This is the base class for the ROOT Random number generators.
Definition: TRandom.h:29
virtual Double_t Rndm(Int_t i=0)
Machine independent random number generator.
Definition: TRandom3.cxx:93
virtual void SetSeed(UInt_t seed=0)
Set the random generator sequence if seed is 0 (default value) a TUUID is generated and used to fill ...
Definition: TRandom3.cxx:200
ROOT::R::TRInterface & r
Definition: Object.C:4
TRandom * gRandom
Definition: TRandom3.cxx:56
TClass * IsA() const
unsigned int UInt_t
Definition: RtypesCore.h:42
virtual void RndmArray(Int_t n, Float_t *array)
Return an array of n random numbers uniformly distributed in ]0,1].
Definition: TRandom3.cxx:137
virtual Int_t ReadClassBuffer(const TClass *cl, void *pointer, const TClass *onfile_class=0)=0
static const double x1[5]
UInt_t fSeed
Definition: TRandom.h:32
double Double_t
Definition: RtypesCore.h:55
Int_t fCount624
Definition: TRandom3.h:33
Double_t y[n]
Definition: legend1.C:17
UInt_t fMt[624]
Definition: TRandom3.h:32
const Int_t n
Definition: legend1.C:16
gr SetName("gr")
ClassImp(TRandom3) TRandom3
*-*-*-*-*-*-*-*-*-*-*default constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-* If seed is 0, the seed is automatically computed via a TUUID object.
Definition: TRandom3.cxx:66
virtual Version_t ReadVersion(UInt_t *start=0, UInt_t *bcnt=0, const TClass *cl=0)=0