SSJ API Documentation
Stochastic Simulation in Java
Loading...
Searching...
No Matches
DigitalNetBase2.java
1/*
2 * Class: DigitalNetBase2
3 * Description:
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.hups;
26
27import java.util.Arrays;
28
29import umontreal.ssj.rng.*;
30import umontreal.ssj.util.*;
31
55public class DigitalNetBase2 extends DigitalNet {
56
57 // These three variables are redefined here, so the methods in DigitalNet that
58 // use them must be redefined here!
59 private transient int[] originalMat; // Original matrices, without randomization.
60 protected int[] genMat; // The current generator matrix.
61 protected transient int[] digitalShift; // Stores the digital shift vector.
62 // recall that `outdigits = 31. It is initialized in the constructors.
63
64 public double getCoordinate(int i, int j) {
65 int res;
66 int pos = 0;
67 int grayCode = i ^ (i >> 1);
68 if (digitalShift == null)
69 res = 0;
70 else
71 res = digitalShift[j];
72 while ((grayCode >> pos) != 0) {
73 if (((grayCode >> pos) & 1) != 0)
74 res ^= genMat[j * numCols + pos];
75 pos++;
76 }
77 if (digitalShift != null)
78 return res * normFactor + EpsilonHalf;
79 else
80 return res * normFactor;
81 }
82
83 public double getCoordinateNoGray(int i, int j) {
84 int res;
85 if (digitalShift == null)
86 res = 0;
87 else
88 res = digitalShift[j];
89 int pos = 0; // Position of the bit that is examined.
90 // Add (xor) the columns of C_j for which the corresponding bit of i is 1.
91 // Least significant bit of i goes with first column of C_j.
92 // The first row of C_j is for the most significant bit of output, u_{i,j,1}.
93 while ((i >> pos) != 0) {
94 if ((((i >> pos) & 1) != 0) && (pos < numCols))
95 res ^= genMat[j * numCols + pos];
96 pos++;
97 }
98 if (digitalShift != null)
99 // This EpsilonHalf must be explained in the doc.
100 // It prevents the output of 0.
101 // normFactor is 2^{-outDigits}.
102 return res * normFactor + EpsilonHalf;
103 else
104 return res * normFactor;
105 }
106
112 return new DigitalNetBase2Iterator();
113 }
114
122
123 public String toString() {
124 StringBuffer sb = new StringBuffer("DigitalNetBase2: ");
125 sb.append(super.toString());
126 return sb.toString();
127 }
128
129 // The digital random shift always has `w = outDigits` bits.
130 public void addRandomShift(int d1, int d2, RandomStream stream) {
131 if (null == stream)
132 throw new IllegalArgumentException(PrintfFormat.NEWLINE +
133 " Calling addRandomShift with null stream");
134 if (0 == d2)
135 d2 = Math.max(1, dim);
136 if (digitalShift == null) {
137 digitalShift = new int[d2];
138 capacityShift = d2;
139 } else if (d2 > capacityShift) {
140 int d3 = Math.max(4, capacityShift);
141 while (d2 > d3)
142 d3 *= 2;
143 int[] temp = new int[d3];
144 capacityShift = d3;
145 for (int i = 0; i < d1; i++)
146 temp[i] = digitalShift[i];
147 digitalShift = temp;
148 }
149 int maxj;
150 if (outDigits < 31) // outDigit (= w) is used here for the shift!
151 maxj = (1 << outDigits) - 1;
152 else
153 maxj = 2147483647;
154 for (int i = d1; i < d2; i++)
155 digitalShift[i] = stream.nextInt(0, maxj);
156 dimShift = d2;
157 shiftStream = stream;
158 }
159
160 public void addRandomShift(RandomStream stream) {
161 addRandomShift(0, dim, stream);
162 }
163
164 public void clearRandomShift() {
165 super.clearRandomShift();
166 digitalShift = null;
167 }
168
169 // Left-multiplies lower-triangular matrix Mj by original C_j,
170 // where original C_j is in originalMat and result is in genMat.
171 // Mj[d] is assumed to contain the d-th subdiagonal of matrix Mj,
172 // for d=0,...,w-1. Each subdiagonal is represented as a
173 // w-bit integer, whose most significant bits are those on the
174 // diagonal. For example, for d=w-3, the subdiagonal has 3 bits,
175 // say b1, b2, b3, and is represented by the integer
176 // Mj[w-3] = b1 * 2^{w-1} + b2 * 2^{w-2} + b3 * b^{w-3}.
177 //
178 private void leftMultiplyMatSubdiag (int j, int[] Mj) {
179 int c, d, col; // Dimension j, column c for new C_j.
180 for (c = 0; c < numCols; c++) {
181 col = 0;
182 for (d = 0; d < outDigits; d++)
183 // Multiply subdiagonal d of M_j by column c of C_j, and xor.
184 col ^= (Mj[d] & originalMat[j * numCols + c]) >> d;
185 genMat[j * numCols + c] = col; // Column c for coordinate j.
186 }
187 }
188
189
190 // Right-multiplies upper-triangular matrix Mj by original C_j,
191 // where original C_j is in originalMat and result is in genMat.
192 // Mj[d] is assumed to contain the d-th column of matrix Mj,
193 // for d=0,...,w-1. Each column is represented as a w-bit integer,
194 // whose most significant bits are those at index 0.
195 // For example, for d=2, the column has 3 bits, (the others are 0
196 // since under the diagonal) say b1, b2, b3, and is represented by
197 // the integer Mj[2] = b1 * 2^{w-1} + b2 * 2^{w-2} + b3 * b^{w-3}.
198 //
199 private void rightMultiplyMat(int j, int[] Mj) {
200 int c, r, col; // Dimension j, column c for new C_j.
201 int mask; // Bit of column Mj[c]
202
203 for (c = 0; c < numCols; c++) {
204 mask = 1 << outDigits - 1;
205 col = originalMat[j * numCols + c];
206 for (r = 0; r < c; r++) {
207 // If bit (outDigits - 1 - r) of Mj[c] is 1, add column r
208 if ((Mj[c] & mask) != 0)
209 col ^= originalMat[j * numCols + r];
210 mask >>= 1;
211 }
212 genMat[j * numCols + c] = col;
213 }
214 }
215
222 public void leftMatrixScramble (int r, RandomStream stream) {
223 int j, c, d; // dimension j, column c of original Cj, column d of new Cj.
224 int jk;
225 final int tworm1 = 1 << (r - 1); // 2^{r-1}
226 final int wmr = outDigits - r;
227 // If genMat contains the original gen. matrices, copy to originalMat.
228 // Normally, we do this only once!
229 if (originalMat == null) { // This is only if `originalMat` was never created.
230 // System.out.println("Copying genMat to originalMat \n");
231 originalMat = genMat;
232 genMat = new int[dim * numCols]; // Creates a new object, but only once.
233 }
234 for (d = 0; d < dim * numCols; d++) genMat[d] = 0;
235 for (j = 0; j < dim; j++) {
236 jk = j * numCols; // Number of columns to skip
237 for (c = 0; c < numRows; c++) {
238 // colc is column c of L_j, which has numRows columns.
239 int colc = (tworm1 + stream.nextInt(0, tworm1-1)) >> (c + wmr);
240 // System.out.println("colc = " + colc + "\n");
241 for (d = 0; d < numCols; d++) // Column d for coordinate j.
242 genMat[jk + d] ^= ((originalMat[jk + d] >> (outDigits-1-c)) & 1) * colc;
243 }
244 }
245 }
246
247 /*
248 public void leftMatrixScramble (RandomStream stream) {
249 int j, c, d; // dimension j, column c of original Cj, column d of new Cj.
250 int jk;
251 final int tworm1 = 1 << (outDigits - 1); // 2^{r-1}
252 // If genMat contains the original gen. matrices, copy to originalMat.
253 // Normally, we do this only once!
254 if (originalMat == null) { // This is only if `originalMat` was never created.
255 System.out.println("Copying genMat to originalMat" + PrintfFormat.NEWLINE);
256 originalMat = genMat;
257 genMat = new int[dim * numCols]; // Creates a new object, but only once.
258 }
259 for (d = 0; d < dim * numCols; d++) genMat[d] = 0;
260 for (j = 0; j < dim; j++) {
261 jk = j * numCols; // Number of columns to skip
262 for (c = 0; c < numRows; c++) {
263 // colc is column c of L_j, which has numRows columns.
264 int colc = (tworm1 + stream.nextInt(0, tworm1-1)) >> c; // Column c of L_j
265 // System.out.println("colc = " + colc + "\n");
266 for (d = 0; d < numCols; d++) // Column d for coordinate j.
267 genMat[jk + d] ^= ((originalMat[jk + d] >> (outDigits-1-c)) & 1) * colc;
268 }
269 }
270 }
271 */
272
276 public void leftMatrixScramble (RandomStream stream) {
277 leftMatrixScramble (outDigits, stream);
278 }
279
280/*
281 // This is a version of LMS in which each subdiagonal of the lower-triangular
282 public void leftMatrixScramble(RandomStream stream) {
283 int j, d; // dimension j, subdiagonal d.
284 final int allOnes = (1 << outDigits) - 1; // outDigits ones.
285
286 // If genMat contains the original gen. matrices, copy to originalMat.
287 if (originalMat == null) {
288 originalMat = genMat;
289 genMat = new int[dim * numCols];
290 }
291 // Constructs the lower-triangular scrambling matrices M_j, w by w.
292 // scrambleMat[j][l] contains row l in a single integer (binary repres.)
293 int[][] scrambleMat = new int[dim][outDigits];
294 for (j = 0; j < dim; j++) {
295 scrambleMat[j][0] = allOnes;
296 for (d = 1; d < outDigits; d++)
297 scrambleMat[j][d] = (stream.nextInt(0, allOnes >> d)) << d;
298 }
299 // Multiply M_j by the generator matrix C_j for each j.
300 for (j = 0; j < dim; j++)
301 leftMultiplyMat(j, scrambleMat[j]);
302 }
303*/
304
305 // This is a version of LMS in which each subdiagonal of the lower-triangular
306 // scrambling matrix is represented as an integer.
307 // It is equivalent to `leftMatrixScrambleSubdiag (0, stream)`.
308 public void leftMatrixScrambleSubdiag (RandomStream stream) {
309 int j, d; // dimension j, subdiagonal d.
310 final int allOnes = (1 << outDigits) - 1; // outDigits ones.
311
312 // If genMat contains the original gen. matrices, copy to originalMat.
313 // This is done only once.
314 if (originalMat == null) {
315 originalMat = genMat;
316 genMat = new int[dim * numCols];
317 }
318 // Constructs the lower-triangular scrambling matrices M_j, w by w.
319 int[][] scrambleMat = new int[dim][outDigits]; // This creates a big object!
320 for (j = 0; j < dim; j++) {
321 scrambleMat[j][0] = allOnes; // This is the diagonal of a w x w matrix.
322 for (d = 1; d < outDigits; d++)
323 // The d-th subdiagonal will contain w-d random bits.
324 // It is represented as a (w-d)-bit integer.
325 scrambleMat[j][d] = (stream.nextInt(0, allOnes >> d)) << d;
326 }
327 // Multiply M_j by the generator matrix C_j for each j.
328 for (j = 0; j < dim; j++)
329 leftMultiplyMatSubdiag(j, scrambleMat[j]);
330 }
331
332 // A more general version added by Youssef Cherkani.
333 // The matrix scramble is applied only the r most significant bits.
334 public void leftMatrixScrambleSubdiag (int r, RandomStream stream) {
335 int j, d; // dimension j, subdiagonal d.
336 final int allOnes = (1 << r) - 1; // `outDigits` ones.
337
338 // If genMat contains the original gen. matrices, copy to originalMat.
339 if (originalMat == null) {
340 originalMat = genMat;
341 genMat = new int[dim * numCols]; // Creates a new object!
342 }
343 // Constructs the lower-triangular scrambling matrices M_j, w by w.
344 // scrambleMat[j][l] contains row l in a single integer (binary repres.)
345 int[][] scrambleMat = new int[dim][outDigits];
346 for (j = 0; j < dim; j++) {
347 scrambleMat[j][0] = allOnes << (outDigits - r);
348 for (d = 1; d < r; d++)
349 scrambleMat[j][d] = (stream.nextInt(0, allOnes >> d)) << (outDigits - r + d);
350 }
351 // Multiply M_j by the generator matrix C_j for each j.
352 for (j = 0; j < dim; j++)
353 leftMultiplyMatSubdiag(j, scrambleMat[j]);
354 }
355
361 int j, d; // Dimension j, subdiagonal d of M_j.
362 final int allOnes = (1 << outDigits) - 1; // outDigits ones.
363 int lastRow; // Last row of M_j: w-1 random bits followed by 1.
364
365 // If genMat is original generator matrices, copy it to originalMat.
366 if (originalMat == null) {
367 originalMat = genMat;
368 genMat = new int[dim * numCols];
369 }
370 // Constructs the lower-triangular scrambling matrices M_j, w by w.
371 // scrambleMat[j][l] contains the subdiagonal l of M_j.
372 // *** Pierre: We should avoid creating and storing all these matrices. ****
373 int[][] scrambleMat = new int[dim][outDigits];
374 for (j = 0; j < dim; j++) {
375 scrambleMat[j][0] = allOnes;
376 lastRow = stream.nextInt(0, allOnes) | 1;
377 for (d = 1; d < outDigits; d++)
378 // Subdiagonal d contains either all ones or all zeros.
379 if (((1 << d) & lastRow) == 0)
380 scrambleMat[j][d] = 0;
381 else
382 scrambleMat[j][d] = (allOnes >> d) << d;
383 }
384 for (j = 0; j < dim; j++)
385 leftMultiplyMatSubdiag(j, scrambleMat[j]);
386 // leftMultiplyMat (scrambleMat);
387 }
388
390 int j, d; // dimension j, subdiagonal d of M_j.
391
392 // If genMat is original generator matrices, copy it to originalMat.
393 if (originalMat == null) {
394 originalMat = genMat;
395 genMat = new int[dim * numCols];
396 }
397 // Constructs the lower-triangular scrambling matrix M, w by w,
398 // filled with 1's. scrambleMat[d] contains subdiagonal d of M.
399 int[] scrambleMat = new int[outDigits];
400 final int allOnes = (1 << outDigits) - 1; // outDigits ones.
401 for (d = 0; d < outDigits; d++)
402 scrambleMat[d] = (allOnes >> d) << d;
403 for (j = 0; j < dim; j++)
404 leftMultiplyMatSubdiag(j, scrambleMat);
405 }
406
407
408 public void rightMatrixScramble(RandomStream stream) {
409 int j, c; // Dimension j, column c for new C_j.
410 if (originalMat == null) {
411 originalMat = genMat;
412 genMat = new int[dim * numCols];
413 }
414 // Generate an upper triangular matrix for the Faure-Tezuka right-scramble.
415 // scrambleMat[c] contains column c of M.
416 int[] scrambleMat = new int[outDigits];
417 int boundInt = 0;
418 for (c = 0; c < numCols; c++) {
419 boundInt += (1 << c); // Integer repres. by string of c+1 ones.
420 scrambleMat[c] = (1 | stream.nextInt(0, boundInt)) << (outDigits - c - 1);
421 }
422 // Right-multiply the generator matrices by the scrambling matrix.
423 for (j = 0; j < dim; j++)
424 rightMultiplyMat(j, scrambleMat);
425 }
426
431 private int randomBitVector(RandomStream stream, int numBits) {
432 if (numBits < 1)
433 throw new IllegalArgumentException("numBits must be >= 1");
434 if (numBits > 31)
435 throw new IllegalArgumentException("numBits must be <= 31");
436 int maxj;
437 if (numBits < 31)
438 maxj = (1 << numBits) - 1;
439 else
440 maxj = 2147483647;
441 return stream.nextInt(0, maxj) << (31 - numBits);
442 }
443
448 public void nestedUniformScramble(RandomStream stream, double[][] output) {
449 nestedUniformScramble(stream, output, 0);
450 }
451
473 public void nestedUniformScramble(RandomStream stream, double[][] output, int numBits) {
474 assert output.length == numPoints;
475 assert output.length > 0;
476 assert output[0].length == dim;
477
478 int[][] int_output = new int[numPoints][dim];
479 nestedUniformScramble(stream, int_output, numBits);
480 for (int j = 0; j < dim; ++j) {
481 for (int i = 0; i < numPoints; i++) {
482 output[i][j] = int_output[i][j] * normFactor + EpsilonHalf;
483 }
484 }
485 }
486
491 public void nestedUniformScramble(RandomStream stream, int[][] output, int numBits) {
492 assert output.length == numPoints;
493 assert output.length > 0;
494 assert output[0].length == dim;
495 if (numBits == 0)
496 numBits = outDigits;
497 int[] poslist = new int[2 * numPoints];
498 int[] bvlist = new int[2 * numPoints];
499 int[] counts = new int[256];
500 int[] binpos = new int[256];
501
502 for (int j = 0; j < dim; ++j) {
503 bvlist[0] = 0;
504 poslist[0] = 0;
505 for (int i = 1; i < numPoints; i++) {
506 // We use Gray code order (could be optional).
507 // We could have used a point set iterator here, but the iterator computes all
508 // coordinates at once and we need only one at a time.
509 int pos = 0;
510 int bv = 1;
511 while ((i & bv) == 0) {
512 pos++;
513 bv <<= 1;
514 }
515 bvlist[i] = bvlist[i - 1] ^ genMat[j * numCols + pos];
516 poslist[i] = i;
517 }
518 for (int b = 0; b < 4; b++) {
519 for (int i = 0; i < 256; i++)
520 counts[i] = 0;
521 int m = (b % 2) * numPoints;
522 int bb = 8 * b;
523 int bv = 0xff << bb;
524 for (int i = 0; i < numPoints; i++)
525 counts[(bvlist[m + i] & bv) >>> bb]++;
526 binpos[0] = (1 - b % 2) * numPoints;
527 for (int i = 0; i < 255; i++)
528 binpos[i + 1] = binpos[i] + counts[i];
529 for (int i = 0; i < numPoints; i++) {
530 int pos = (bvlist[m + i] & bv) >>> bb;
531 int k = binpos[pos]++;
532 bvlist[k] = bvlist[m + i];
533 poslist[k] = poslist[m + i];
534 }
535 }
536 int bv = randomBitVector(stream, numBits);
537 output[poslist[0]][j] = bvlist[0] ^ bv;
538 for (int i = 1; i < numPoints; i++) {
539 int bv2 = bvlist[i - 1];
540 bv2 ^= bvlist[i];
541 bv2 = randomBitVector(stream, numBits) & ((int) (1 << (int) Num.log2((double) bv2)) - 1);
542 bv ^= bv2;
543 output[poslist[i]][j] = bvlist[i] ^ bv;
544 }
545
546 }
547 }
548
549 // -----------------------------------------------------------------------
550 private void ScrambleError(String method) {
551 throw new UnsupportedOperationException(
552 PrintfFormat.NEWLINE + " " + method + " is not yet implemented for a DigitalNetBase2");
553 }
554
556 ScrambleError("leftMatrixScrambleDiag");
557 }
558
559 public void leftMatrixScrambleFaurePermut(RandomStream stream, int sb) {
560 ScrambleError("leftMatrixScrambleFaurePermut");
561 }
562
564 ScrambleError("leftMatrixScrambleFaurePermutDiag");
565 }
566
567 public void leftMatrixScrambleFaurePermutAll(RandomStream stream, int sb) {
568 ScrambleError("leftMatrixScrambleFaurePermutAll");
569 }
570
572 ScrambleError("iBinomialMatrixScrambleFaurePermut");
573 }
574
576 ScrambleError("iBinomialMatrixScrambleFaurePermutDiag");
577 }
578
580 ScrambleError("iBinomialMatrixScrambleFaurePermutAll");
581 }
582
584 ScrambleError("stripedMatrixScrambleFaurePermutAll");
585 }
586
587
591 public void unrandomize() {
593 digitalShift = null;
594 }
595
600 public void resetGenMatrices() {
601 if (originalMat != null) {
602 genMat = originalMat;
603 originalMat = null;
604 }
605 }
606
613 originalMat = null;
614 }
615
616
622 public int[][][] genMatricesToBitByBitFormat(){
623 int r, c, j; // Row r, column c, dimension j.
624 int[][][] bitMatrices = new int[dim][numRows][numCols];
625 for (j = 0; j < dim; j++) {
626 for (c = 0; c < numCols; c++) {
627 int column = genMat[j * numCols + c]; // This column as an integer.
628 column >>= outDigits - numRows; // outDigits (or w) is used here.
629 for (r = numRows - 1; r >= 0; r--) {
630 bitMatrices[j][r][c] = (column & 1);
631 column >>= 1;
632 }
633 }
634 }
635 return bitMatrices;
636 }
637
642 public void genMatricesFromBitByBitFormat(int[][][] matrices){
643 assert matrices.length == dim;
644 assert matrices.length > 0;
645 assert matrices[0].length == numRows;
646 assert matrices[0].length > 0;
647 assert matrices[0][0].length == numCols;
648 genMat = new int[dim * numCols];
649 int r, c, j; // Row r, column c, dimension j.
650 for(j = 0; j < dim; ++j){
651 for(r = 0; r < numRows; ++r){
652 for(c = 0; c < numCols; ++c){
653 if (matrices[j][r][c] > 0)
654 genMat[j * numCols + c] += (1 << (outDigits - 1 - r));
655 }
656 }
657 }
658 }
659
664 public void printGeneratorMatrices(int s) {
665 int r, c, j; // Row r, column c, dimension j.
666 int[][][] bitMatrices = genMatricesToBitByBitFormat();
667 for (j = 0; j < s; j++) {
668 System.out.println("dim = " + (j + 1) + PrintfFormat.NEWLINE);
669 for (r = 0; r < numRows; r++) {
670 StringBuffer sb = new StringBuffer();
671 for (c = 0; c < numCols; c++) {
672 sb.append(bitMatrices[j][r][c]);
673 }
674 System.out.println(sb);
675 }
676 System.out.println("----------------------------------");
677 }
678 }
679
684 public void printGenMatrices(int s) {
685 // column c, dimension j.
686 for (int j = 0; j < s; j++) {
687 System.out.println("dim = " + (j + 1) + PrintfFormat.NEWLINE);
688 for (int c = 0; c < numCols; c++)
689 System.out.println(genMat[j * numCols + c]);
690 System.out.println("----------------------------------");
691 }
692 }
693
698 public void printOriginalMatrices(int s) {
699 // column c, dimension j.
700 for (int j = 0; j < s; j++) {
701 System.out.println("dim = " + (j + 1) + PrintfFormat.NEWLINE);
702 for (int c = 0; c < numCols; c++)
703 System.out.println(originalMat[j * numCols + c]);
704 System.out.println("----------------------------------");
705 }
706 }
707
712 public int[] getGenMatrices() {
713 return Arrays.copyOf(genMat, genMat.length);
714 }
715
716
717
733 public void outputInterlace(int[][] points, double[][] interlacedPoints) {
734 assert points.length == numPoints;
735 assert points.length > 0;
736 assert points[0].length == dim;
737
738 assert interlacedPoints.length == numPoints;
739 assert interlacedPoints.length > 0;
740 assert interlacedPoints[0].length * interlacing == dim;
741
742 double longNormFactor = 1 / (Math.pow(2, 63));
743
744 for (int i = 0; i < numPoints; i++) {
745 for (int j = 0; j < dim / interlacing; ++j) {
746 long result = 0;
747 for (int idx = 0; idx < interlacing; ++idx) {
748 int coord = j * interlacing + idx;
749 int interlaced_pos = 62 - idx;
750 int original_pos = 30;
751 int mask = 1 << original_pos;
752 while (interlaced_pos >= 0 && original_pos >= 0) {
753 assert interlaced_pos >= original_pos;
754 result += (((long) (points[i][coord] & mask)) << (interlaced_pos - original_pos));
755 interlaced_pos -= interlacing;
756 original_pos -= 1;
757 mask >>= 1;
758 }
759 }
760 interlacedPoints[i][j] = result * longNormFactor + EpsilonHalf;
761 }
762 }
763 }
764
774 DigitalNetBase2 result = new DigitalNetBase2();
775 result.dim = dim / interlacing;
776 result.interlacing = 1;
777 result.numCols = numCols;
778 result.numRows = Math.min(MAXBITS, numRows * interlacing);
779 result.numPoints = numPoints;
780 result.outDigits = outDigits;
781 result.normFactor = normFactor;
782
783 int[][][] nonInterlacedMatrices = genMatricesToBitByBitFormat();
784 int[][][] interlacedMatrices = new int[result.dim][result.numRows][result.numCols];
785 int r, j; // Row r, dimension j.
786 for (j = 0; j < result.dim; ++j) {
787 for (r = 0; r < result.numRows; ++r) {
788 interlacedMatrices[j][r] = nonInterlacedMatrices[j * interlacing + r % interlacing][r / interlacing];
789 }
790 }
791 result.genMatricesFromBitByBitFormat(interlacedMatrices);
792 return result;
793 }
794
795
796
797 // *******************************************************************
798 protected class DigitalNetBase2Iterator extends DigitalNetIterator {
799
800 // Coordinates of the current point stored (cached) as integers.
801 // Initially contains zeros, because first point is always zero.
802 // Incorporates the random shift, except for the first point.
803 // There is one more dimension for the points because of the
804 // shift iterators children of DigitalNetBase2Iterator.
805 // dimS = dim, except for the shift iterator children where
806 // dimS = dim + 1.
807 protected int dimS;
808
809 public DigitalNetBase2Iterator() {
810 super();
811 EpsilonHalf = 0.5 / Num.TWOEXP[outDigits];
812 cachedCurPoint = new int[dim + 1];
813 dimS = dim;
814 init2();
815 }
816
817 public void init() { // This empty method is necessary to overload
818 } // the init() of DigitalNetIterator
819
820 public void init2() { // See constructor
822 }
823
824 // We want to avoid generating 0 or 1
825 public double nextDouble() {
826 return nextCoordinate();
827 }
828
829 public double nextCoordinate() {
830 if (curPointIndex >= numPoints || curCoordIndex >= dimS)
831 outOfBounds();
832 if (digitalShift == null)
833 return cachedCurPoint[curCoordIndex++] * normFactor;
834 else
835 return cachedCurPoint[curCoordIndex++] * normFactor + EpsilonHalf;
836 // *** Pierre: EpsilonHalf could be replaced by a variable `epsAdd` to avoid the "if".
837 }
838
839 protected void addShiftToCache() {
840 if (digitalShift == null)
841 for (int j = 0; j < dim; j++)
842 cachedCurPoint[j] = 0;
843 else {
844 if (dimShift < dimS)
846 for (int j = 0; j < dim; j++)
847 cachedCurPoint[j] = digitalShift[j];
848 }
849 }
850
851 public void resetCurPointIndex() {
852 addShiftToCache();
853 curPointIndex = 0;
854 curCoordIndex = 0;
855 }
856
857 public void setCurPointIndex(int i) {
858 if (i == 0) {
860 return;
861 }
862 // Out of order computation, must recompute the cached current
863 // point from scratch.
864 curPointIndex = i;
865 curCoordIndex = 0;
866 addShiftToCache();
867
868 int j;
869 int grayCode = i ^ (i >> 1);
870 int pos = 0; // Position of the bit that is examined.
871 while ((grayCode >> pos) != 0) {
872 if (((grayCode >> pos) & 1) != 0)
873 for (j = 0; j < dim; j++)
874 cachedCurPoint[j] ^= genMat[j * numCols + pos];
875 pos++;
876 }
877 }
878
879 public int resetToNextPoint() {
880 int pos = 0; // Will be position of change in Gray code,
881 // = pos. of first 0 in binary code of point index.
882 while (((curPointIndex >> pos) & 1) != 0)
883 pos++;
884 if (pos < numCols) {
885 for (int j = 0; j < dim; j++)
886 cachedCurPoint[j] ^= genMat[j * numCols + pos];
887 }
888 curCoordIndex = 0;
889 return ++curPointIndex;
890 }
891
892 public int nextPoint(double p[], int d) {
893 if (curPointIndex >= numPoints || d > dimS)
894 outOfBounds();
895 if (digitalShift == null) {
896 for (int j = 0; j < d; j++)
897 p[j] = cachedCurPoint[j] * normFactor;
898 } else {
899 for (int j = 0; j < d; j++)
900 p[j] = cachedCurPoint[j] * normFactor + EpsilonHalf;
901 }
902 return resetToNextPoint();
903 }
904 }
905
906
907 // *******************************************************************
908 protected class DigitalNetBase2IteratorNoGray extends DigitalNetBase2Iterator {
909
910 // Same as DigitalNetBase2Iterator,
911 // except that the Gray code is not used.
912
913 public DigitalNetBase2IteratorNoGray() {
914 super();
915 }
916
917 public void setCurPointIndex(int i) {
918 if (i == 0) {
920 return;
921 }
922 // Out of order computation, must recompute the cached current
923 // point from scratch.
924 curPointIndex = i;
925 curCoordIndex = 0;
926 addShiftToCache();
927 int pos = 0; // Position of the bit that is examined.
928 while ((i >> pos) != 0) {
929 if ((((i >> pos) & 1) != 0) && (pos < numCols)) {
930 for (int j = 0; j < dim; j++)
931 cachedCurPoint[j] ^= genMat[j * numCols + pos];
932 }
933 pos++;
934 }
935 }
936
937 public int resetToNextPoint() {
938 // Contains the bits of i that changed.
939 if (curPointIndex + 1 >= numPoints)
940 return ++curPointIndex;
941 int diff = curPointIndex ^ (curPointIndex + 1);
942 int pos = 0; // Position of the bit that is examined.
943 while ((diff >> pos) != 0) {
944 if ((((diff >> pos) & 1) != 0) && (pos < numCols)) {
945 for (int j = 0; j < dim; j++)
946 cachedCurPoint[j] ^= genMat[j * numCols + pos];
947 }
948 pos++;
949 }
950 curCoordIndex = 0;
951 return ++curPointIndex;
952 }
953
954 }
955}
int resetToNextPoint()
Resets the current point index to the next one and current coordinate to 0, and returns the new curre...
void setCurPointIndex(int i)
Resets the current point index to i and current coordinate to 0.
int nextPoint(double p[], int d)
Same as nextPoint(p, 0, d).
void resetCurPointIndex()
Resets both the current point index and the current coordinate to 0.
int resetToNextPoint()
Resets the current point index to the next one and current coordinate to 0, and returns the new curre...
void setCurPointIndex(int i)
Resets the current point index to i and current coordinate to 0.
A special case of DigitalNet for the base .
void iBinomialMatrixScrambleFaurePermutDiag(RandomStream stream, int sb)
Similar to iBinomialMatrixScrambleFaurePermut except that all the off-diagonal elements are 0.
void leftMatrixScramble(RandomStream stream)
By default, the matrices L_j have r = w rows.
void addRandomShift(int d1, int d2, RandomStream stream)
Generates a random digital shift for coordinates from d1 to d2-1, using stream to generate the rando...
int[][][] genMatricesToBitByBitFormat()
Returns the generator matrices as a 3-dimensional array of shape dim x numRows x numCols integers,...
void rightMatrixScramble(RandomStream stream)
Applies a linear scramble by multiplying each on the right by a single nonsingular upper-triangular...
void genMatricesFromBitByBitFormat(int[][][] matrices)
Reverse of the previous function.
void clearRandomShift()
Erases the current digital random shift, if any.
PointSetIterator iterator()
Returns a DigitalNetBase2Iterator which enumerates the points using a Gray code.
void leftMatrixScrambleFaurePermutDiag(RandomStream stream, int sb)
Similar to leftMatrixScrambleFaurePermut except that all off-diagonal elements are 0.
void nestedUniformScramble(RandomStream stream, int[][] output, int numBits)
Same as nestedUniformScramble(RandomStream,double[][],int), but it returns the points as integers fro...
DigitalNetBase2 matrixInterlace()
Interlaces the matrices from a digital net.
void stripedMatrixScramble(RandomStream stream)
Applies the striped matrix scramble proposed by Owen.
void leftMatrixScramble(int r, RandomStream stream)
This is a version of LMS in which each column of the lower-triangular scrambling matrix is represente...
void nestedUniformScramble(RandomStream stream, double[][] output)
Same as nestedUniformScramble(stream, output, 0) .
void stripedMatrixScrambleFaurePermutAll(RandomStream stream, int sb)
Similar to stripedMatrixScramble except that the elements on and under the diagonal of each matrix a...
void unrandomize()
Restores the original generator matrices and removes the random shift.
void outputInterlace(int[][] points, double[][] interlacedPoints)
Interlaces the points from a digital net.
PointSetIterator iteratorNoGray()
This iterator does not use the Gray code.
void printGeneratorMatrices(int s)
Prints the generating matrices bit by bit for dimensions 1 to .
void iBinomialMatrixScrambleFaurePermut(RandomStream stream, int sb)
Similar to iBinomialMatrixScramble except that the diagonal elements of each matrix are chosen as in...
void leftMatrixScrambleFaurePermut(RandomStream stream, int sb)
Similar to leftMatrixScramble except that the diagonal elements of each matrix are chosen from a res...
String toString()
Formats a string that contains information on this digital net.
double getCoordinateNoGray(int i, int j)
Returns , the coordinate of point , the points being enumerated in the standard order (no Gray code)...
void printOriginalMatrices(int s)
Prints the generating matrices in the standard format, one integer per column, for dimensions 1 to .
void eraseOriginalGenMatrices()
Erases the original generator matrices and replaces them by the current ones.
void nestedUniformScramble(RandomStream stream, double[][] output, int numBits)
Applies Owen's nested uniform scrambling to the digital net and returns the scrambled points in the t...
void addRandomShift(RandomStream stream)
Same as addRandomShift(0, dim, stream), where dim is the dimension of the digital net.
void resetGenMatrices()
Restores genMat to the original generator matrices.
double getCoordinate(int i, int j)
Returns , the coordinate of point , where is the Gray code for .
void leftMatrixScrambleFaurePermutAll(RandomStream stream, int sb)
Similar to leftMatrixScrambleFaurePermut except that the elements under the diagonal are also chosen ...
void leftMatrixScrambleDiag(RandomStream stream)
Similar to leftMatrixScramble except that all the off-diagonal elements of the are 0.
int[] getGenMatrices()
Returns a copy of the generator matrices for dimensions 1 to .
void printGenMatrices(int s)
Prints the generating matrices in the standard format, one integer per column, for dimensions 1 to .
void iBinomialMatrixScrambleFaurePermutAll(RandomStream stream, int sb)
Similar to iBinomialMatrixScrambleFaurePermut except that the elements under the diagonal are also ch...
void iBinomialMatrixScramble(RandomStream stream)
Similar to leftMatrixScramble, except that all entries on any given diagonal or subdiagonal of any gi...
DigitalNet()
Empty constructor.
void resetGeneratorMatrices()
Restores the original generator matrices.
int curPointIndex
Index of the current point.
int curCoordIndex
Index of the current coordinate.
double EpsilonHalf
Default constant epsilon/2 added to the points after a random shift.
void outOfBounds()
Error message for index out of bounds.
static final int MAXBITS
Since Java has no unsigned type, the 32nd bit cannot be used efficiently, so we have only 31 bits.
int dimShift
Current dimension of the shift.
void addRandomShift()
Same as addRandomShift(0, dim), where dim is the dimension of the point set.
int numPoints
Number of points.
double EpsilonHalf
To avoid 0 for nextCoordinate when random shifting, we add this to each coordinate.
int capacityShift
Number of array elements in the shift vector, always >= dimShift.
int dim
Dimension of the points.
RandomStream shiftStream
Stream used to generate the random shifts.
This class provides various constants and methods to compute numerical quantities such as factorials,...
Definition Num.java:35
static double log2(double x)
Returns x .
Definition Num.java:405
static final double TWOEXP[]
Contains the precomputed positive powers of 2.
Definition Num.java:170
This class acts like a StringBuffer which defines new types of append methods.
static final String NEWLINE
End-of-line symbol or line separator.
This is the interface for iterators that permit one to go through the points of a PointSet and the su...
This interface defines the basic structures to handle multiple streams of uniform (pseudo)random numb...
int nextInt(int i, int j)
Returns a (pseudo)random number from the discrete uniform distribution over the integers ,...