SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MRG32k3a.java
1/*
2 * Class: MRG32k3a
3 * Description: combined multiple recursive generator proposed by L'Ecuyer
4 * Environment: Java
5 * Software: SSJ
6 * Copyright (C) 2001 Pierre L'Ecuyer and Universite de Montreal
7 * Organization: DIRO, Universite de Montreal
8 * @author
9 * @since
10 *
11 *
12 * Licensed under the Apache License, Version 2.0 (the "License");
13 * you may not use this file except in compliance with the License.
14 * You may obtain a copy of the License at
15 *
16 * http://www.apache.org/licenses/LICENSE-2.0
17 *
18 * Unless required by applicable law or agreed to in writing, software
19 * distributed under the License is distributed on an "AS IS" BASIS,
20 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 * See the License for the specific language governing permissions and
22 * limitations under the License.
23 *
24 */
25package umontreal.ssj.rng;
26
27import umontreal.ssj.util.ArithmeticMod;
28import umontreal.ssj.util.PrintfFormat;
29import java.io.Serializable;
30
46public class MRG32k3a extends RandomStreamBase {
47
48 private static final long serialVersionUID = 70510L;
49 // La date de modification a l'envers, lire 10/05/2007
50
51 // Private constants %%%%%%%%%%%%%%%%%%%%%%%%%%
52
53 private static final double m1 = 4294967087.0;
54 private static final double m2 = 4294944443.0;
55 private static final double a12 = 1403580.0;
56 private static final double a13n = 810728.0;
57 private static final double a21 = 527612.0;
58 private static final double a23n = 1370589.0;
59 private static final double two17 = 131072.0;
60 private static final double two53 = 9007199254740992.0;
61 private static final double invtwo24 = 5.9604644775390625e-8;
62 private static final double norm = 2.328306549295727688e-10;
63 // private static final double norm = 1.0 / (m1 + 1.0);
64
65 /*
66 * Unused private static final double InvA1[][] = { // Inverse of A1p0 {
67 * 184888585.0, 0.0, 1945170933.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 } };
68 * private static final double InvA2[][] = { // Inverse of A2p0 { 0.0,
69 * 360363334.0, 4225571728.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 } };
70 */
71
72 private static final double A1p0[][] = { { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { -810728.0, 1403580.0, 0.0 } };
73 private static final double A2p0[][] = { { 0.0, 1.0, 0.0 }, { 0.0, 0.0, 1.0 }, { -1370589.0, 0.0, 527612.0 } };
74 private static final double A1p76[][] = { { 82758667.0, 1871391091.0, 4127413238.0 },
75 { 3672831523.0, 69195019.0, 1871391091.0 }, { 3672091415.0, 3528743235.0, 69195019.0 } };
76 private static final double A2p76[][] = { { 1511326704.0, 3759209742.0, 1610795712.0 },
77 { 4292754251.0, 1511326704.0, 3889917532.0 }, { 3859662829.0, 4292754251.0, 3708466080.0 } };
78 private static final double A1p127[][] = { { 2427906178.0, 3580155704.0, 949770784.0 },
79 { 226153695.0, 1230515664.0, 3580155704.0 }, { 1988835001.0, 986791581.0, 1230515664.0 } };
80 private static final double A2p127[][] = { { 1464411153.0, 277697599.0, 1610723613.0 },
81 { 32183930.0, 1464411153.0, 1022607788.0 }, { 2824425944.0, 32183930.0, 2093834863.0 } };
82
83 // Private variables for each stream %%%%%%%%%%%%%%%%%%%%%%%%
84
85 // Default seed of the package for the first stream
86 private static double nextSeed[] = { 12345, 12345, 12345, 12345, 12345, 12345 };
87 private double Cg0, Cg1, Cg2, Cg3, Cg4, Cg5;
88 private double Bg[] = new double[6];
89 private double Ig[] = new double[6];
90 // The arrays Cg, Bg and Ig contain the current state,
91 // the starting point of the current substream,
92 // and the starting point of the stream, respectively.
93
94 // multiply the first half of v by A with a modulo of m1
95 // and the second half by B with a modulo of m2
96 private static void multMatVect(double[] v, double[][] A, double m1, double[][] B, double m2) {
97 double[] vv = new double[3];
98 for (int i = 0; i < 3; i++)
99 vv[i] = v[i];
100 ArithmeticMod.matVecModM(A, vv, vv, m1);
101 for (int i = 0; i < 3; i++)
102 v[i] = vv[i];
103
104 for (int i = 0; i < 3; i++)
105 vv[i] = v[i + 3];
106 ArithmeticMod.matVecModM(B, vv, vv, m2);
107 for (int i = 0; i < 3; i++)
108 v[i + 3] = vv[i];
109 }
110
120 public MRG32k3a() {
121 name = null;
122 anti = false;
123 prec53 = false;
124 for (int i = 0; i < 6; i++)
125 Ig[i] = nextSeed[i];
127 multMatVect(nextSeed, A1p127, m1, A2p127, m2);
128 }
129
136 public MRG32k3a(String name) {
137 this();
138 this.name = name;
139 }
140
151 public static void setPackageSeed(long seed[]) {
152 // Must use long because there is no unsigned int type.
153 validateSeed(seed);
154 for (int i = 0; i < 6; ++i)
155 nextSeed[i] = seed[i];
156 }
157
170 public void setSeed(long seed[]) {
171 // Must use long because there is no unsigned int type.
172 validateSeed(seed);
173 for (int i = 0; i < 6; ++i)
174 Ig[i] = seed[i];
176 }
177
178 public void resetStartStream() {
179 for (int i = 0; i < 6; ++i)
180 Bg[i] = Ig[i];
182 }
183
184 public void resetStartSubstream() {
185 Cg0 = Bg[0];
186 Cg1 = Bg[1];
187 Cg2 = Bg[2];
188 Cg3 = Bg[3];
189 Cg4 = Bg[4];
190 Cg5 = Bg[5];
191 }
192
193 public void resetNextSubstream() {
194 multMatVect(Bg, A1p76, m1, A2p76, m2);
196 }
197
205 public long[] getState() {
206 return new long[] { (long) Cg0, (long) Cg1, (long) Cg2, (long) Cg3, (long) Cg4, (long) Cg5 };
207 }
208
215 public String toString() {
216 PrintfFormat str = new PrintfFormat();
217
218 str.append("The current state of the MRG32k3a");
219 if (name != null && name.length() > 0)
220 str.append(" " + name);
221 str.append(":" + PrintfFormat.NEWLINE + " Cg = { ");
222 str.append((long) Cg0 + ", ");
223 str.append((long) Cg1 + ", ");
224 str.append((long) Cg2 + ", ");
225 str.append((long) Cg3 + ", ");
226 str.append((long) Cg4 + ", ");
227 str.append((long) Cg5 + " }" + PrintfFormat.NEWLINE + PrintfFormat.NEWLINE);
228
229 return str.toString();
230 }
231
238 public String toStringFull() {
239 PrintfFormat str = new PrintfFormat();
240 str.append("The MRG32k3a stream");
241 if (name != null && name.length() > 0)
242 str.append(" " + name);
243 str.append(":" + PrintfFormat.NEWLINE + " anti = " + (anti ? "true" : "false")).append(PrintfFormat.NEWLINE);
244 str.append(" prec53 = " + (prec53 ? "true" : "false")).append(PrintfFormat.NEWLINE);
245
246 str.append(" Ig = { ");
247 for (int i = 0; i < 5; i++)
248 str.append((long) Ig[i] + ", ");
249 str.append((long) Ig[5] + " }" + PrintfFormat.NEWLINE);
250
251 str.append(" Bg = { ");
252 for (int i = 0; i < 5; i++)
253 str.append((long) Bg[i] + ", ");
254 str.append((long) Bg[5] + " }" + PrintfFormat.NEWLINE);
255
256 str.append(" Cg = { ");
257 str.append((long) Cg0 + ", ");
258 str.append((long) Cg1 + ", ");
259 str.append((long) Cg2 + ", ");
260 str.append((long) Cg3 + ", ");
261 str.append((long) Cg4 + ", ");
262 str.append((long) Cg5 + " }" + PrintfFormat.NEWLINE + PrintfFormat.NEWLINE);
263
264 return str.toString();
265 }
266
272 public MRG32k3a clone() {
273 MRG32k3a retour = null;
274
275 retour = (MRG32k3a) super.clone();
276 retour.Bg = new double[6];
277 retour.Ig = new double[6];
278 for (int i = 0; i < 6; i++) {
279 retour.Bg[i] = Bg[i];
280 retour.Ig[i] = Ig[i];
281 }
282 return retour;
283 }
284
285 protected double nextValue() {
286 int k;
287 double p1, p2;
288 /* Component 1 */
289 p1 = a12 * Cg1 - a13n * Cg0;
290 k = (int) (p1 / m1);
291 p1 -= k * m1;
292 if (p1 < 0.0)
293 p1 += m1;
294 Cg0 = Cg1;
295 Cg1 = Cg2;
296 Cg2 = p1;
297 /* Component 2 */
298 p2 = a21 * Cg5 - a23n * Cg3;
299 k = (int) (p2 / m2);
300 p2 -= k * m2;
301 if (p2 < 0.0)
302 p2 += m2;
303 Cg3 = Cg4;
304 Cg4 = Cg5;
305 Cg5 = p2;
306 /* Combination */
307 return ((p1 > p2) ? (p1 - p2) * norm : (p1 - p2 + m1) * norm);
308 }
309
310 private static void validateSeed(long seed[]) {
311 if (seed.length < 6)
312 throw new IllegalArgumentException("Seed must contain 6 values");
313 if (seed[0] == 0 && seed[1] == 0 && seed[2] == 0)
314 throw new IllegalArgumentException("The first 3 values must not be 0");
315 if (seed[3] == 0 && seed[4] == 0 && seed[5] == 0)
316 throw new IllegalArgumentException("The last 3 values must not be 0");
317 final long m1 = 4294967087L;
318 if (seed[0] >= m1 || seed[1] >= m1 || seed[2] >= m1)
319 throw new IllegalArgumentException("The first 3 values must be less than " + m1);
320 final long m2 = 4294944443L;
321 if (seed[3] >= m2 || seed[4] >= m2 || seed[5] >= m2)
322 throw new IllegalArgumentException("The last 3 values must be less than " + m2);
323 }
324}
String toString()
Returns a string containing the name and the current state of this stream.
long[] getState()
Returns the current state of this stream.
void setSeed(long seed[])
Sets the initial seed of this stream to the vector seed[0..5].
void resetStartStream()
Reinitializes the stream to its initial state : and are set to .
MRG32k3a(String name)
Constructs a new stream with an identifier name (used when printing the stream state).
double nextValue()
This method should return the next random number (between 0 and 1) from the current stream.
MRG32k3a()
Constructs a new stream, initializes its seed , sets.
void resetNextSubstream()
Reinitializes the stream to the beginning of its next substream:
MRG32k3a clone()
Clones the current generator and return its copy.
void resetStartSubstream()
Reinitializes the stream to the beginning of its current substream:
static void setPackageSeed(long seed[])
Sets the initial seed for the class MRG32k3a to the six integers in the vector seed[0....
String toStringFull()
Returns a string containing the name of this stream and the values of all its internal variables.
This class provides a convenient foundation on which RNGs can be built.
This class provides facilities to compute multiplications of scalars, of vectors and of matrices modu...
static void matVecModM(double A[][], double s[], double v[], double m)
Computes the result of and puts the result in v.
This class acts like a StringBuffer which defines new types of append methods.
String toString()
Converts the buffer into a String.
PrintfFormat append(String str)
Appends str to the buffer.
static final String NEWLINE
End-of-line symbol or line separator.