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