SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MRG32k3aL.java
1/*
2 * Class: MRG32k3aL
3 * Description: Long version of MRG32k3a
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
37public class MRG32k3aL extends RandomStreamBase {
38
39 private static final long serialVersionUID = 70510L;
40 // La date de modification a l'envers, lire 10/05/2007
41
42 // Private constants %%%%%%%%%%%%%%%%%%%%%%%%%%
43
44 private static final long m1 = 4294967087L;
45 private static final long m2 = 4294944443L;
46 private static final long a12 = 1403580L;
47 private static final long a13n = 810728L;
48 private static final long a21 = 527612L;
49 private static final long a23n = 1370589L;
50 private static final long two17 = 131072L;
51 private static final long two53 = 9007199254740992L;
52 private static final double invtwo24 = 5.9604644775390625e-8;
53 private static final double norm = 2.328306549295727688e-10;
54 // private static final double norm = 1.0 / (m1 + 1.0);
55
56 /*
57 * Unused private static final double InvA1[][] = { // Inverse of A1p0 {
58 * 184888585.0, 0.0, 1945170933.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 } };
59 * private static final double InvA2[][] = { // Inverse of A2p0 { 0.0,
60 * 360363334.0, 4225571728.0 }, { 1.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0 } };
61 */
62
63 private static final long A1p0[][] = { { 0L, 1L, 0L }, { 0L, 0L, 1L }, { -810728L, 1403580L, 0L } };
64 private static final long A2p0[][] = { { 0L, 1L, 0L }, { 0L, 0L, 1L }, { -1370589L, 0L, 527612L } };
65 private static final long A1p76[][] = { { 82758667L, 1871391091L, 4127413238L },
66 { 3672831523L, 69195019L, 1871391091L }, { 3672091415L, 3528743235L, 69195019L } };
67 private static final long A2p76[][] = { { 1511326704L, 3759209742L, 1610795712L },
68 { 4292754251L, 1511326704L, 3889917532L }, { 3859662829L, 4292754251L, 3708466080L } };
69 private static final long A1p127[][] = { { 2427906178L, 3580155704L, 949770784L },
70 { 226153695L, 1230515664L, 3580155704L }, { 1988835001L, 986791581L, 1230515664L } };
71 private static final long A2p127[][] = { { 1464411153L, 277697599L, 1610723613L },
72 { 32183930L, 1464411153L, 1022607788L }, { 2824425944L, 32183930L, 2093834863L } };
73
74 // Private variables for each stream %%%%%%%%%%%%%%%%%%%%%%%%
75
76 // Default seed of the package for the first stream
77 private static long nextSeed[] = { 12345, 12345, 12345, 12345, 12345, 12345 };
78 private long Cg0, Cg1, Cg2, Cg3, Cg4, Cg5;
79 private long Bg[] = new long[6];
80 private long Ig[] = new long[6];
81 // The arrays Cg, Bg and Ig contain the current state,
82 // the starting point of the current substream,
83 // and the starting point of the stream, respectively.
84
85 // multiply the first half of v by A with a modulo of m1
86 // and the second half by B with a modulo of m2
87 private static void multMatVect(long[] v, long[][] A, long m1, long[][] B, long m2) {
88 long[] vv = new long[3];
89 for (int i = 0; i < 3; i++)
90 vv[i] = v[i];
91 ArithmeticMod.matVecModM(A, vv, vv, m1);
92 for (int i = 0; i < 3; i++)
93 v[i] = vv[i];
94
95 for (int i = 0; i < 3; i++)
96 vv[i] = v[i + 3];
97 ArithmeticMod.matVecModM(B, vv, vv, m2);
98 for (int i = 0; i < 3; i++)
99 v[i + 3] = vv[i];
100 }
101
102 public MRG32k3aL() {
103 name = null;
104 anti = false;
105 prec53 = false;
106 for (int i = 0; i < 6; i++)
107 Ig[i] = nextSeed[i];
109 multMatVect(nextSeed, A1p127, m1, A2p127, m2);
110 }
111
112 public MRG32k3aL(String name) {
113 this();
114 this.name = name;
115 }
116
122 public static void setPackageSeed(long seed[]) {
123 // Must use long because there is no unsigned int type.
124 validateSeed(seed);
125 for (int i = 0; i < 6; ++i)
126 nextSeed[i] = seed[i];
127 }
128
132 public void setSeed(long seed[]) {
133 // Must use long because there is no unsigned int type.
134 validateSeed(seed);
135 for (int i = 0; i < 6; ++i)
136 Ig[i] = seed[i];
138 }
139
143
144 public void resetStartStream() {
145 for (int i = 0; i < 6; ++i)
146 Bg[i] = Ig[i];
148 }
149
150 public void resetStartSubstream() {
151 Cg0 = Bg[0];
152 Cg1 = Bg[1];
153 Cg2 = Bg[2];
154 Cg3 = Bg[3];
155 Cg4 = Bg[4];
156 Cg5 = Bg[5];
157 }
158
159 public void resetNextSubstream() {
160 multMatVect(Bg, A1p76, m1, A2p76, m2);
162 }
163
164 public long[] getState() {
165 return new long[] { Cg0, Cg1, Cg2, Cg3, Cg4, Cg5 };
166 }
167
171 public String toString() {
172 PrintfFormat str = new PrintfFormat();
173
174 str.append("The current state of the MRG32k3aL");
175 if (name != null && name.length() > 0)
176 str.append(" " + name);
177 str.append(":" + PrintfFormat.NEWLINE + " Cg = { ");
178 str.append(Cg0 + ", ");
179 str.append(Cg1 + ", ");
180 str.append(Cg2 + ", ");
181 str.append(Cg3 + ", ");
182 str.append(Cg4 + ", ");
183 str.append(Cg5 + " }" + PrintfFormat.NEWLINE + PrintfFormat.NEWLINE);
184
185 return str.toString();
186 }
187
191 public String toStringFull() {
192 PrintfFormat str = new PrintfFormat();
193 str.append("The MRG32k3aL stream");
194 if (name != null && name.length() > 0)
195 str.append(" " + name);
196 str.append(":" + PrintfFormat.NEWLINE + " anti = " + (anti ? "true" : "false")).append(PrintfFormat.NEWLINE);
197 str.append(" prec53 = " + (prec53 ? "true" : "false")).append(PrintfFormat.NEWLINE);
198
199 str.append(" Ig = { ");
200 for (int i = 0; i < 5; i++)
201 str.append(Ig[i] + ", ");
202 str.append(Ig[5] + " }" + PrintfFormat.NEWLINE);
203
204 str.append(" Bg = { ");
205 for (int i = 0; i < 5; i++)
206 str.append(Bg[i] + ", ");
207 str.append(Bg[5] + " }" + PrintfFormat.NEWLINE);
208
209 str.append(" Cg = { ");
210 str.append(Cg0 + ", ");
211 str.append(Cg1 + ", ");
212 str.append(Cg2 + ", ");
213 str.append(Cg3 + ", ");
214 str.append(Cg4 + ", ");
215 str.append(Cg5 + " }" + PrintfFormat.NEWLINE + PrintfFormat.NEWLINE);
216
217 return str.toString();
218 }
219
223 public MRG32k3aL clone() {
224 MRG32k3aL retour = null;
225
226 retour = (MRG32k3aL) super.clone();
227 retour.Bg = new long[6];
228 retour.Ig = new long[6];
229 for (int i = 0; i < 6; i++) {
230 retour.Bg[i] = Bg[i];
231 retour.Ig[i] = Ig[i];
232 }
233 return retour;
234 }
235
239
240 protected double nextValue() {
241 int k;
242 long p1, p2;
243
244 /* Component 1 */
245 p1 = (a12 * Cg1 - a13n * Cg0) % m1;
246 if (p1 < 0)
247 p1 += m1;
248 Cg0 = Cg1;
249 Cg1 = Cg2;
250 Cg2 = p1;
251
252 /* Component 2 */
253 p2 = (a21 * Cg5 - a23n * Cg3) % m2;
254 if (p2 < 0)
255 p2 += m2;
256 Cg3 = Cg4;
257 Cg4 = Cg5;
258 Cg5 = p2;
259
260 /* Combination */
261 return (double) ((p1 > p2) ? (p1 - p2) * norm : (p1 - p2 + m1) * norm);
262 }
263
264 private static void validateSeed(long seed[]) {
265 if (seed.length < 6)
266 throw new IllegalArgumentException("Seed must contain 6 values");
267 if (seed[0] == 0 && seed[1] == 0 && seed[2] == 0)
268 throw new IllegalArgumentException("The first 3 values must not be 0");
269 if (seed[3] == 0 && seed[4] == 0 && seed[5] == 0)
270 throw new IllegalArgumentException("The last 3 values must not be 0");
271 final long m1 = 4294967087L;
272 if (seed[0] >= m1 || seed[1] >= m1 || seed[2] >= m1)
273 throw new IllegalArgumentException("The first 3 values must be less than " + m1);
274 final long m2 = 4294944443L;
275 if (seed[3] >= m2 || seed[4] >= m2 || seed[5] >= m2)
276 throw new IllegalArgumentException("The last 3 values must be less than " + m2);
277 }
278}
void setSeed(long seed[])
static void setPackageSeed(long seed[])
void resetStartSubstream()
Reinitializes the stream to the beginning of its current substream:
void resetNextSubstream()
Reinitializes the stream to the beginning of its next substream:
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.