forked from GooFit/GooFit
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathTRandom3.cc
180 lines (151 loc) · 6.26 KB
/
TRandom3.cc
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
// This file is derived from TRandom3.cxx in ROOT version 5.30/06.
// It is distributed under the GNU LGPL. The original copyright notice
// is reproduced in full below.
//////////////////////////////////////////////////////////////////////////
//
// TRandom3
//
// Random number generator class based on
// M. Matsumoto and T. Nishimura,
// Mersenne Twistor: A 623-diminsionally equidistributed
// uniform pseudorandom number generator
// ACM Transactions on Modeling and Computer Simulation,
// Vol. 8, No. 1, January 1998, pp 3--30.
//
// For more information see the Mersenne Twistor homepage
// http://www.math.keio.ac.jp/~matumoto/emt.html
//
// Advantage: large period 2**19937-1
// relativly fast
// (only two times slower than TRandom, but
// two times faster than TRandom2)
// Drawback: a relative large internal state of 624 integers
//
//
// Aug.99 ROOT implementation based on CLHEP by P.Malzacher
//
// the original code contains the following copyright notice:
/* This library is free software; you can redistribute it and/or */
/* modify it under the terms of the GNU Library General Public */
/* License as published by the Free Software Foundation; either */
/* version 2 of the License, or (at your option) any later */
/* version. */
/* This library is distributed in the hope that it will be useful, */
/* but WITHOUT ANY WARRANTY; without even the implied warranty of */
/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. */
/* See the GNU Library General Public License for more details. */
/* You should have received a copy of the GNU Library General */
/* Public License along with this library; if not, write to the */
/* Free Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA */
/* 02111-1307 USA */
/* Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. */
/* When you use this, send an email to: [email protected] */
/* with an appropriate reference to your work. */
/////////////////////////////////////////////////////////////////////
#include "TRandom3.hh"
TRandom* TRandom::gRandom = new TRandom3();
//______________________________________________________________________________
TRandom3::TRandom3 (unsigned int seed) {
//*-*-*-*-*-*-*-*-*-*-*default constructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
// If seed is 0, the seed is automatically computed via a TUUID object.
// In this case the seed is guaranteed to be unique in space and time.
SetSeed(seed);
}
//______________________________________________________________________________
TRandom3::~TRandom3() {
//*-*-*-*-*-*-*-*-*-*-*default destructor*-*-*-*-*-*-*-*-*-*-*-*-*-*-*
//*-* ==================
}
//______________________________________________________________________________
double TRandom3::Rndm (int) {
// Machine independent random number generator.
// Produces uniformly-distributed floating points in ]0,1]
// Method: Mersenne Twistor
unsigned int y;
const int kM = 397;
const int kN = 624;
const unsigned int kTemperingMaskB = 0x9d2c5680;
const unsigned int kTemperingMaskC = 0xefc60000;
const unsigned int kUpperMask = 0x80000000;
const unsigned int kLowerMask = 0x7fffffff;
const unsigned int kMatrixA = 0x9908b0df;
if (fCount624 >= kN) {
register int i;
for (i=0; i < kN-kM; i++) {
y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
fMt[i] = fMt[i+kM] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
}
for ( ; i < kN-1 ; i++) {
y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
fMt[i] = fMt[i+kM-kN] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
}
y = (fMt[kN-1] & kUpperMask) | (fMt[0] & kLowerMask);
fMt[kN-1] = fMt[kM-1] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
fCount624 = 0;
}
y = fMt[fCount624++];
y ^= (y >> 11);
y ^= ((y << 7 ) & kTemperingMaskB );
y ^= ((y << 15) & kTemperingMaskC );
y ^= (y >> 18);
if (y) return ( (double) y * 2.3283064365386963e-10); // * Power(2,-32)
return Rndm();
}
//______________________________________________________________________________
void TRandom3::RndmArray(int n, float *array)
{
// Return an array of n random numbers uniformly distributed in ]0,1]
for(int i=0; i<n; i++) array[i]=(float)Rndm();
}
//______________________________________________________________________________
void TRandom3::RndmArray(int n, double *array)
{
// Return an array of n random numbers uniformly distributed in ]0,1]
int k = 0;
unsigned int y;
const int kM = 397;
const int kN = 624;
const unsigned int kTemperingMaskB = 0x9d2c5680;
const unsigned int kTemperingMaskC = 0xefc60000;
const unsigned int kUpperMask = 0x80000000;
const unsigned int kLowerMask = 0x7fffffff;
const unsigned int kMatrixA = 0x9908b0df;
while (k < n) {
if (fCount624 >= kN) {
register int i;
for (i=0; i < kN-kM; i++) {
y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
fMt[i] = fMt[i+kM] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
}
for ( ; i < kN-1 ; i++) {
y = (fMt[i] & kUpperMask) | (fMt[i+1] & kLowerMask);
fMt[i] = fMt[i+kM-kN] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
}
y = (fMt[kN-1] & kUpperMask) | (fMt[0] & kLowerMask);
fMt[kN-1] = fMt[kM-1] ^ (y >> 1) ^ ((y & 0x1) ? kMatrixA : 0x0);
fCount624 = 0;
}
y = fMt[fCount624++];
y ^= (y >> 11);
y ^= ((y << 7 ) & kTemperingMaskB );
y ^= ((y << 15) & kTemperingMaskC );
y ^= (y >> 18);
if (y) {
array[k] = double( y * 2.3283064365386963e-10); // * Power(2,-32)
k++;
}
}
}
//______________________________________________________________________________
void TRandom3::SetSeed(unsigned int seed) {
// Set the random generator sequence
TRandom::SetSeed(seed);
fCount624 = 624;
int i,j;
fMt[0] = fSeed;
j = 1;
// use multipliers from Knuth's "Art of Computer Programming" Vol. 2, 3rd Ed. p.106
for(i=j; i<624; i++) {
fMt[i] = (1812433253 * ( fMt[i-1] ^ ( fMt[i-1] >> 30)) + i);
}
}