| line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
|
1
|
|
|
|
|
|
|
#include "mt.h" |
|
2
|
|
|
|
|
|
|
|
|
3
|
|
|
|
|
|
|
#include |
|
4
|
|
|
|
|
|
|
#include |
|
5
|
|
|
|
|
|
|
|
|
6
|
|
|
|
|
|
|
/* This code is based on mt19937ar.c, written by Takuji Nishimura and |
|
7
|
|
|
|
|
|
|
Makoto Matsumoto (20020126). Further details are available at |
|
8
|
|
|
|
|
|
|
. |
|
9
|
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
REFERENCE |
|
11
|
|
|
|
|
|
|
M. Matsumoto and T. Nishimura, |
|
12
|
|
|
|
|
|
|
"Mersenne Twister: A 623-Dimensionally Equidistributed Uniform |
|
13
|
|
|
|
|
|
|
Pseudo-Random Number Generator", |
|
14
|
|
|
|
|
|
|
ACM Transactions on Modeling and Computer Simulation, |
|
15
|
|
|
|
|
|
|
Vol. 8, No. 1, January 1998, pp 3--30. */ |
|
16
|
|
|
|
|
|
|
|
|
17
|
2
|
|
|
|
|
|
void mt_init_seed( struct mt *m, uint32_t seed ) |
|
18
|
|
|
|
|
|
|
{ |
|
19
|
|
|
|
|
|
|
int i; |
|
20
|
|
|
|
|
|
|
uint32_t *mt; |
|
21
|
|
|
|
|
|
|
|
|
22
|
2
|
|
|
|
|
|
mt = m->mt; |
|
23
|
2
|
|
|
|
|
|
mt[0] = seed & 0xffffffff; |
|
24
|
1248
|
100
|
|
|
|
|
for ( i = 1; i < N; i++ ) |
|
25
|
1246
|
|
|
|
|
|
mt[i] = 1812433253 * (mt[i-1]^(mt[i-1]>>30)) + i; |
|
26
|
2
|
|
|
|
|
|
m->mti = N; |
|
27
|
2
|
|
|
|
|
|
} |
|
28
|
|
|
|
|
|
|
|
|
29
|
2
|
|
|
|
|
|
struct mt *mt_setup(uint32_t seed) |
|
30
|
|
|
|
|
|
|
{ |
|
31
|
2
|
|
|
|
|
|
struct mt *self = malloc(sizeof(struct mt)); |
|
32
|
|
|
|
|
|
|
|
|
33
|
2
|
50
|
|
|
|
|
if (self) |
|
34
|
2
|
|
|
|
|
|
mt_init_seed( self, seed ); |
|
35
|
|
|
|
|
|
|
|
|
36
|
2
|
|
|
|
|
|
return self; |
|
37
|
|
|
|
|
|
|
} |
|
38
|
|
|
|
|
|
|
|
|
39
|
0
|
|
|
|
|
|
struct mt *mt_setup_array( uint32_t *array, int n ) |
|
40
|
|
|
|
|
|
|
{ |
|
41
|
|
|
|
|
|
|
int i, j, k; |
|
42
|
0
|
|
|
|
|
|
struct mt *self = malloc(sizeof(struct mt)); |
|
43
|
|
|
|
|
|
|
uint32_t *mt; |
|
44
|
|
|
|
|
|
|
|
|
45
|
0
|
0
|
|
|
|
|
if (self) { |
|
46
|
0
|
|
|
|
|
|
mt_init_seed( self, 19650218UL ); |
|
47
|
|
|
|
|
|
|
|
|
48
|
0
|
|
|
|
|
|
i = 1; j = 0; |
|
49
|
0
|
|
|
|
|
|
k = ( N > n ? N : n ); |
|
50
|
0
|
|
|
|
|
|
mt = self->mt; |
|
51
|
|
|
|
|
|
|
|
|
52
|
0
|
0
|
|
|
|
|
for (; k; k--) { |
|
53
|
0
|
|
|
|
|
|
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1664525UL)) |
|
54
|
0
|
|
|
|
|
|
+ array[j] + j; |
|
55
|
0
|
|
|
|
|
|
i++; j++; |
|
56
|
0
|
0
|
|
|
|
|
if (i>=N) { mt[0] = mt[N-1]; i=1; } |
|
57
|
0
|
0
|
|
|
|
|
if (j>=n) j=0; |
|
58
|
|
|
|
|
|
|
} |
|
59
|
0
|
0
|
|
|
|
|
for (k=N-1; k; k--) { |
|
60
|
0
|
|
|
|
|
|
mt[i] = (mt[i] ^ ((mt[i-1] ^ (mt[i-1] >> 30)) * 1566083941UL)) - i; |
|
61
|
0
|
|
|
|
|
|
i++; |
|
62
|
0
|
0
|
|
|
|
|
if (i>=N) { mt[0] = mt[N-1]; i=1; } |
|
63
|
|
|
|
|
|
|
} |
|
64
|
|
|
|
|
|
|
|
|
65
|
0
|
|
|
|
|
|
mt[0] = 0x80000000UL; |
|
66
|
|
|
|
|
|
|
} |
|
67
|
|
|
|
|
|
|
|
|
68
|
0
|
|
|
|
|
|
return self; |
|
69
|
|
|
|
|
|
|
} |
|
70
|
|
|
|
|
|
|
|
|
71
|
2
|
|
|
|
|
|
void mt_free(struct mt *self) |
|
72
|
|
|
|
|
|
|
{ |
|
73
|
2
|
|
|
|
|
|
free(self); |
|
74
|
2
|
|
|
|
|
|
} |
|
75
|
|
|
|
|
|
|
|
|
76
|
|
|
|
|
|
|
/* Returns a pseudorandom number which is uniformly distributed in [0,1) */ |
|
77
|
671
|
|
|
|
|
|
double mt_genrand(struct mt *self) |
|
78
|
|
|
|
|
|
|
{ |
|
79
|
|
|
|
|
|
|
int kk; |
|
80
|
|
|
|
|
|
|
uint32_t y; |
|
81
|
|
|
|
|
|
|
static uint32_t mag01[2] = {0x0, 0x9908b0df}; |
|
82
|
|
|
|
|
|
|
static const uint32_t UP_MASK = 0x80000000, LOW_MASK = 0x7fffffff; |
|
83
|
|
|
|
|
|
|
|
|
84
|
671
|
100
|
|
|
|
|
if (self->mti >= N) { |
|
85
|
456
|
100
|
|
|
|
|
for (kk = 0; kk < N-M; kk++) { |
|
86
|
454
|
|
|
|
|
|
y = (self->mt[kk] & UP_MASK) | (self->mt[kk+1] & LOW_MASK); |
|
87
|
454
|
|
|
|
|
|
self->mt[kk] = self->mt[kk+M] ^ (y >> 1) ^ mag01[y & 1]; |
|
88
|
|
|
|
|
|
|
} |
|
89
|
|
|
|
|
|
|
|
|
90
|
794
|
100
|
|
|
|
|
for (; kk < N-1; kk++) { |
|
91
|
792
|
|
|
|
|
|
y = (self->mt[kk] & UP_MASK) | (self->mt[kk+1] & LOW_MASK); |
|
92
|
792
|
|
|
|
|
|
self->mt[kk] = self->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 1]; |
|
93
|
|
|
|
|
|
|
} |
|
94
|
|
|
|
|
|
|
|
|
95
|
2
|
|
|
|
|
|
y = (self->mt[N-1] & UP_MASK) | (self->mt[0] & LOW_MASK); |
|
96
|
2
|
|
|
|
|
|
self->mt[N-1] = self->mt[M-1] ^ (y >> 1) ^ mag01[y & 1]; |
|
97
|
|
|
|
|
|
|
|
|
98
|
2
|
|
|
|
|
|
self->mti = 0; |
|
99
|
|
|
|
|
|
|
} |
|
100
|
|
|
|
|
|
|
|
|
101
|
671
|
|
|
|
|
|
y = self->mt[self->mti++]; |
|
102
|
671
|
|
|
|
|
|
y ^= y >> 11; |
|
103
|
671
|
|
|
|
|
|
y ^= y << 7 & 0x9d2c5680; |
|
104
|
671
|
|
|
|
|
|
y ^= y << 15 & 0xefc60000; |
|
105
|
671
|
|
|
|
|
|
y ^= y >> 18; |
|
106
|
|
|
|
|
|
|
|
|
107
|
671
|
|
|
|
|
|
return y*(1.0/4294967296.0); |
|
108
|
|
|
|
|
|
|
} |