1 package nl.tudelft.simulation.jstats.streams;
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 public class MersenneTwister extends RandomNumberGenerator
27 {
28
29 private static final long serialVersionUID = 20150426L;
30
31
32 private static final int N = 624;
33
34
35 private static final int M = 397;
36
37
38 private static final int MATRIX_A = 0x9908b0df;
39
40
41 private static final int UPPER_MASK = 0x80000000;
42
43
44 private static final int LOWER_MASK = 0x7fffffff;
45
46
47 private static final int TEMPERING_MASK_B = 0x9d2c5680;
48
49
50 private static final int TEMPERING_MASK_C = 0xefc60000;
51
52
53 private static final int UMASK = (1 << 31) - 1;
54
55
56 private int[] mt;
57
58
59 private int mti;
60
61
62 private int[] mag01;
63
64
65
66
67 public MersenneTwister()
68 {
69 this(System.currentTimeMillis());
70 }
71
72
73
74
75
76 public MersenneTwister(final long seed)
77 {
78 super(seed);
79 }
80
81
82
83
84 private void initialize()
85 {
86 this.mt = new int[N];
87
88 this.mt[0] = ((int) super.seed) & UMASK;
89 if (this.mt[0] == 0)
90 {
91
92
93 this.setSeed(System.currentTimeMillis());
94 }
95 for (this.mti = 1; this.mti < N; this.mti++)
96 {
97 this.mt[this.mti] = (69069 * this.mt[this.mti - 1]);
98 }
99
100
101 this.mag01 = new int[2];
102 this.mag01[0] = 0x0;
103 this.mag01[1] = MATRIX_A;
104 }
105
106
107 @Override
108 public synchronized long next(final int bits)
109 {
110 if (bits < 0 || bits > 64)
111 {
112 throw new IllegalArgumentException("bits (" + bits + ") not in range [0,64]");
113 }
114 int y;
115 if (this.mti >= N)
116 {
117 int kk;
118 for (kk = 0; kk < N - M; kk++)
119 {
120 y = (this.mt[kk] & UPPER_MASK) | (this.mt[kk + 1] & LOWER_MASK);
121 this.mt[kk] = this.mt[kk + M] ^ (y >>> 1) ^ this.mag01[y & 0x1];
122 }
123 for (; kk < N - 1; kk++)
124 {
125 y = (this.mt[kk] & UPPER_MASK) | (this.mt[kk + 1] & LOWER_MASK);
126 this.mt[kk] = this.mt[kk + (M - N)] ^ (y >>> 1) ^ this.mag01[y & 0x1];
127 }
128 y = (this.mt[N - 1] & UPPER_MASK) | (this.mt[0] & LOWER_MASK);
129 this.mt[N - 1] = this.mt[M - 1] ^ (y >>> 1) ^ this.mag01[y & 0x1];
130 this.mti = 0;
131 }
132 y = this.mt[this.mti++];
133 y ^= y >>> 11;
134 y ^= (y << 7) & TEMPERING_MASK_B;
135 y ^= (y << 15) & TEMPERING_MASK_C;
136 y ^= (y >>> 18);
137 if (bits <= 32)
138 {
139 return y >>> (32 - bits);
140 }
141 return y << 32 + this.next(bits - 32);
142 }
143
144
145 @Override
146 public synchronized void setSeed(final long seed)
147 {
148 super.seed = seed;
149 this.initialize();
150 }
151 }