25package umontreal.ssj.rng;
27import java.io.Serializable;
49 private static final long serialVersionUID = 70510L;
53 private static final double NORM = 1.0 / 0x100000001L;
63 private int[] substream;
64 private static int[] curr_stream = { 987654321, 987654321, 987654321, 987654321 };
73 substream =
new int[4];
75 for (
int i = 0; i < 4; i++)
76 stream[i] = curr_stream[i];
91 z = curr_stream[0] & -2;
93 z = (z) ^ (z << 2) ^ (z << 3) ^ (z << 10) ^ (z << 13) ^ (z << 16) ^ (z << 19) ^ (z << 22) ^ (z << 25) ^ (z << 27)
94 ^ (z << 28) ^ (b >>> 3) ^ (b >>> 4) ^ (b >>> 6) ^ (b >>> 9) ^ (b >>> 12) ^ (b >>> 15) ^ (b >>> 18)
98 z = curr_stream[1] & -8;
100 z = (b >>> 13) ^ (z << 16);
103 z = curr_stream[2] & -16;
105 z = (z << 2) ^ (z << 4) ^ (z << 10) ^ (z << 12) ^ (z << 13) ^ (z << 17) ^ (z << 25) ^ (b >>> 3) ^ (b >>> 11)
106 ^ (b >>> 15) ^ (b >>> 16) ^ (b >>> 24);
109 z = curr_stream[3] & -128;
111 z = (z << 9) ^ (z << 10) ^ (z << 11) ^ (z << 14) ^ (z << 16) ^ (z << 18) ^ (z << 23) ^ (z << 24) ^ (b >>> 1)
112 ^ (b >>> 2) ^ (b >>> 7) ^ (b >>> 9) ^ (b >>> 11) ^ (b >>> 14) ^ (b >>> 15) ^ (b >>> 16) ^ (b >>> 23)
140 for (
int i = 0; i < 4; i++)
141 curr_stream[i] = seed[i];
144 private static void checkSeed(
int[] seed) {
146 throw new IllegalArgumentException(
"Seed must contain 4 values");
147 if ((seed[0] >= 0 && seed[0] < 2) || (seed[1] >= 0 && seed[1] < 8) || (seed[2] >= 0 && seed[2] < 16)
148 || (seed[3] >= 0 && seed[3] < 128))
149 throw new IllegalArgumentException(
150 "The seed elements must be either negative or greater than 1, 7, 15 and 127 respectively");
166 for (
int i = 0; i < 4; i++)
178 return new int[] { z0, z1, z2, z3 };
189 retour.stream =
new int[4];
190 retour.substream =
new int[4];
191 for (
int i = 0; i < 4; i++) {
192 retour.substream[i] = substream[i];
193 retour.stream[i] = stream[i];
199 for (
int i = 0; i < 4; i++)
200 substream[i] = stream[i];
242 z = substream[0] & -2;
244 z = (z) ^ (z << 3) ^ (z << 4) ^ (z << 6) ^ (z << 7) ^ (z << 8) ^ (z << 10) ^ (z << 11) ^ (z << 13) ^ (z << 14)
245 ^ (z << 16) ^ (z << 17) ^ (z << 18) ^ (z << 22) ^ (z << 24) ^ (z << 25) ^ (z << 26) ^ (z << 28) ^ (z << 30);
246 z ^= (b >>> 1) ^ (b >>> 3) ^ (b >>> 5) ^ (b >>> 6) ^ (b >>> 7) ^ (b >>> 9) ^ (b >>> 13) ^ (b >>> 14) ^ (b >>> 15)
247 ^ (b >>> 17) ^ (b >>> 18) ^ (b >>> 20) ^ (b >>> 21) ^ (b >>> 23) ^ (b >>> 24) ^ (b >>> 25) ^ (b >>> 26)
248 ^ (b >>> 27) ^ (b >>> 30);
251 z = substream[1] & -8;
258 b ^= (z << 22) ^ (z << 25) ^ (z << 27);
259 if ((z & 0x80000000) != 0)
261 if ((z & 0x40000000) != 0)
263 z = b ^ (z >>> 7) ^ (z >>> 20) ^ (z >>> 21);
266 z = substream[2] & -16;
268 z = (b >>> 3) ^ (b >>> 17) ^ (z << 10) ^ (z << 11) ^ (z << 25);
271 z = substream[3] & -128;
273 z = (z << 14) ^ (z << 16) ^ (z << 20) ^ (b >>> 5) ^ (b >>> 9) ^ (b >>> 11);
281 return "The state of the LFSR113 is: { " + z0 +
", " + z1 +
", " + z2 +
", " + z3 +
" }";
283 return "The state of " + name +
" is: { " + z0 +
", " + z1 +
", " + z2 +
", " + z3 +
" }";
286 private long nextNumber() {
288 b = (((z0 << 6) ^ z0) >>> 13);
289 z0 = (((z0 & -2) << 18) ^ b);
290 b = (((z1 << 2) ^ z1) >>> 27);
291 z1 = (((z1 & -8) << 2) ^ b);
292 b = (((z2 << 13) ^ z2) >>> 21);
293 z2 = (((z2 & -16) << 7) ^ b);
294 b = (((z3 << 3) ^ z3) >>> 12);
295 z3 = (((z3 & -128) << 13) ^ b);
297 long r = (z0 ^ z1 ^ z2 ^ z3);
307 return nextNumber() * NORM;
312 throw new IllegalArgumentException(i +
" is larger than " + j +
".");
314 long q = 0x100000000L / d;
315 long r = 0x100000000L % d;
320 }
while (res >= 0x100000000L - r);
322 return (
int) (res / q) + i;
double nextValue()
This method should return the next random number (between 0 and 1) from the current stream.
int[] getState()
Returns the current state of the stream, represented as an array of four integers.
void resetStartSubstream()
Reinitializes the stream to the beginning of its current substream:
void resetNextSubstream()
Reinitializes the stream to the beginning of its next substream:
LFSR113 clone()
Clones the current generator and return its copy.
String toString()
Returns a string containing the current state of this stream.
void resetStartStream()
Reinitializes the stream to its initial state : and are set to .
void setSeed(int[] seed)
This method is discouraged for normal use.
static void setPackageSeed(int[] seed)
Sets the initial seed for the class LFSR113 to the four integers of the vector seed[0....
LFSR113(String name)
Constructs a new stream with the identifier name.
int nextInt(int i, int j)
Calls nextDouble once to create one integer between i and j.
LFSR113()
Constructs a new stream.
This class provides a convenient foundation on which RNGs can be built.