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