SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
MRG31k3p.java
1/*
2 * Class: MRG31k3p
3 * Description: combined multiple recursive generator proposed by L'Ecuyer and Touzin
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;
28// import java.io.Serializable;
29
52public class MRG31k3p extends RandomStreamBase {
53
54 private static final long serialVersionUID = 70510L;
55 // La date de modification a l'envers, lire 10/05/2007
56
57 // generator constants :
58 private static final int M1 = 2147483647; // 2^31 - 1
59 private static final int M2 = 2147462579; // 2^31 - 21069
60 private static final int MASK12 = 511; // 2^9 - 1
61 private static final int MASK13 = 16777215; // 2^24 - 1
62 private static final int MASK2 = 65535; // 2^16 - 1
63 private static final int MULT2 = 21069;
64 private static final double NORM = 4.656612873077392578125e-10;
65 // private static final double NORM = 1.0 / (M1 + 1.0);
66
67 // state variables
68 private int x11;
69 private int x12;
70 private int x13;
71 private int x21;
72 private int x22;
73 private int x23;
74
75 // stream and substream variables
76 private int[] stream;
77 private int[] substream;
78 private static int[] curr_stream = { 12345, 12345, 12345, 12345, 12345, 12345 };
79
80 // streams constants :
81 private static final int[][] A1p0 = { { 0, 4194304, 129 }, { 1, 0, 0 }, { 0, 1, 0 } };
82 private static final int[][] A2p0 = { { 32768, 0, 32769 }, { 1, 0, 0 }, { 0, 1, 0 } };
83
84 private static final int[][] A1p72 = { { 1516919229, 758510237, 499121365 }, { 1884998244, 1516919229, 335398200 },
85 { 601897748, 1884998244, 358115744 } };
86 private static final int[][] A2p72 = { { 1228857673, 1496414766, 954677935 }, { 1133297478, 1407477216, 1496414766 },
87 { 2002613992, 1639496704, 1407477216 } };
88
89 private static final int[][] A1p134 = { { 1702500920, 1849582496, 1656874625 },
90 { 828554832, 1702500920, 1512419905 }, { 1143731069, 828554832, 102237247 } };
91 private static final int[][] A2p134 = { { 796789021, 1464208080, 607337906 }, { 1241679051, 1431130166, 1464208080 },
92 { 1401213391, 1178684362, 1431130166 } };
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(int[] v, int[][] A, int m1, int[][] B, int m2) {
97 int[] vv = new int[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 }
111
117 public MRG31k3p() {
118 name = null;
119
120 prec53 = false;
121 anti = false;
122
123 stream = new int[6];
124 substream = new int[6];
125 for (int i = 0; i < 6; i++)
126 stream[i] = curr_stream[i];
127
129
130 multMatVect(curr_stream, A1p134, M1, A2p134, M2);
131 }
132
139 public MRG31k3p(String name) {
140 this();
141 this.name = name;
142 }
143
155 public static void setPackageSeed(int seed[]) {
156 if (seed.length < 6)
157 throw new IllegalArgumentException("Seed must contain 6 values");
158 if (seed[0] == 0 && seed[1] == 0 && seed[2] == 0)
159 throw new IllegalArgumentException("The first 3 values must not be 0");
160 if (seed[5] == 0 && seed[3] == 0 && seed[4] == 0)
161 throw new IllegalArgumentException("The last 3 values must not be 0");
162 if (seed[0] >= M1 || seed[1] >= M1 || seed[2] >= M1)
163 throw new IllegalArgumentException("The first 3 values must be less than " + M1);
164 if (seed[5] >= M2 || seed[3] >= M2 || seed[4] >= M2)
165 throw new IllegalArgumentException("The last 3 values must be less than " + M2);
166 for (int i = 0; i < 6; ++i)
167 curr_stream[i] = seed[i];
168 }
169
182 public void setSeed(int seed[]) {
183 if (seed.length < 6)
184 throw new IllegalArgumentException("Seed must contain 6 values");
185 if (seed[0] == 0 && seed[1] == 0 && seed[2] == 0)
186 throw new IllegalArgumentException("The first 3 values must not be 0");
187 if (seed[3] == 0 && seed[4] == 0 && seed[5] == 0)
188 throw new IllegalArgumentException("The last 3 values must not be 0");
189 if (seed[0] >= M1 || seed[1] >= M1 || seed[2] >= M1)
190 throw new IllegalArgumentException("The first 3 values must be less than " + M1);
191 if (seed[3] >= M2 || seed[4] >= M2 || seed[5] >= M2)
192 throw new IllegalArgumentException("The last 3 values must be less than " + M2);
193 for (int i = 0; i < 6; ++i)
194 stream[i] = seed[i];
196 }
197
198 public void resetStartStream() {
199 for (int i = 0; i < 6; i++)
200 substream[i] = stream[i];
202 }
203
204 public void resetStartSubstream() {
205 x11 = substream[0];
206 x12 = substream[1];
207 x13 = substream[2];
208 x21 = substream[3];
209 x22 = substream[4];
210 x23 = substream[5];
211 }
212
213 public void resetNextSubstream() {
214 multMatVect(substream, A1p72, M1, A2p72, M2);
216 }
217
225 public int[] getState() {
226 return new int[] { x11, x12, x13, x21, x22, x23 };
227 }
228
234 public MRG31k3p clone() {
235 MRG31k3p retour = null;
236 retour = (MRG31k3p) super.clone();
237 retour.substream = new int[6];
238 retour.stream = new int[6];
239 for (int i = 0; i < 6; i++) {
240 retour.substream[i] = substream[i];
241 retour.stream[i] = stream[i];
242 }
243 return retour;
244 }
245
246 public String toString() {
247 if (name == null)
248 return "The state of the MRG31k3p is: " + x11 + ", " + x12 + ", " + x13 + "; " + x21 + ", " + x22 + ", "
249 + x23;
250 else
251 return "The state of " + name + " is: " + x11 + ", " + x12 + ", " + x13 + "; " + x21 + ", " + x22 + ", "
252 + x23;
253 }
254
255 protected double nextValue() {
256 int y1, y2;
257
258 // first component
259 y1 = ((x12 & MASK12) << 22) + (x12 >>> 9) + ((x13 & MASK13) << 7) + (x13 >>> 24);
260 if (y1 < 0 || y1 >= M1) // must also check overflow
261 y1 -= M1;
262 y1 += x13;
263 if (y1 < 0 || y1 >= M1)
264 y1 -= M1;
265
266 x13 = x12;
267 x12 = x11;
268 x11 = y1;
269
270 // second component
271 y1 = ((x21 & MASK2) << 15) + (MULT2 * (x21 >>> 16));
272 if (y1 < 0 || y1 >= M2)
273 y1 -= M2;
274 y2 = ((x23 & MASK2) << 15) + (MULT2 * (x23 >>> 16));
275 if (y2 < 0 || y2 >= M2)
276 y2 -= M2;
277 y2 += x23;
278 if (y2 < 0 || y2 >= M2)
279 y2 -= M2;
280 y2 += y1;
281 if (y2 < 0 || y2 >= M2)
282 y2 -= M2;
283
284 x23 = x22;
285 x22 = x21;
286 x21 = y2;
287
288 // Must never return either 0 or 1
289 if (x11 <= x21)
290 return (x11 - x21 + M1) * NORM;
291 else
292 return (x11 - x21) * NORM;
293 }
294
295}
double nextValue()
This method should return the next random number (between 0 and 1) from the current stream.
void resetNextSubstream()
Reinitializes the stream to the beginning of its next substream:
void resetStartSubstream()
Reinitializes the stream to the beginning of its current substream:
MRG31k3p()
Constructs a new stream, initialized to its seed, which is.
int[] getState()
Returns the current state of this stream.
static void setPackageSeed(int seed[])
Sets the initial seed for the class MRG31k3p to the six integers of the vector seed[0....
String toString()
Returns a string containing the current state of this stream.
void setSeed(int seed[])
Use of this method is strongly discouraged.
MRG31k3p(String name)
Constructs a new stream with the identifier name (used when formatting the stream state).
MRG31k3p clone()
Clones the current generator and return its copy.
void resetStartStream()
Reinitializes the stream to its initial state : and are set to .
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.