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