25package umontreal.ssj.hups;
27import java.util.Arrays;
29import umontreal.ssj.rng.*;
30import umontreal.ssj.util.*;
59 private transient int[] originalMat;
60 protected int[] genMat;
61 protected transient int[] digitalShift;
67 int grayCode = i ^ (i >> 1);
68 if (digitalShift ==
null)
71 res = digitalShift[j];
72 while ((grayCode >> pos) != 0) {
73 if (((grayCode >> pos) & 1) != 0)
74 res ^= genMat[j * numCols + pos];
77 if (digitalShift !=
null)
80 return res * normFactor;
85 if (digitalShift ==
null)
88 res = digitalShift[j];
93 while ((i >> pos) != 0) {
94 if ((((i >> pos) & 1) != 0) && (pos < numCols))
95 res ^= genMat[j * numCols + pos];
98 if (digitalShift !=
null)
104 return res * normFactor;
124 StringBuffer sb =
new StringBuffer(
"DigitalNetBase2: ");
125 sb.append(super.toString());
126 return sb.toString();
133 " Calling addRandomShift with null stream");
135 d2 = Math.max(1,
dim);
136 if (digitalShift ==
null) {
137 digitalShift =
new int[d2];
143 int[] temp =
new int[d3];
145 for (
int i = 0; i < d1; i++)
146 temp[i] = digitalShift[i];
151 maxj = (1 << outDigits) - 1;
154 for (
int i = d1; i < d2; i++)
155 digitalShift[i] = stream.
nextInt(0, maxj);
165 super.clearRandomShift();
178 private void leftMultiplyMatSubdiag (
int j,
int[] Mj) {
180 for (c = 0; c < numCols; c++) {
182 for (d = 0; d < outDigits; d++)
184 col ^= (Mj[d] & originalMat[j * numCols + c]) >> d;
185 genMat[j * numCols + c] = col;
199 private void rightMultiplyMat(
int j,
int[] Mj) {
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++) {
208 if ((Mj[c] & mask) != 0)
209 col ^= originalMat[j * numCols + r];
212 genMat[j * numCols + c] = col;
225 final int tworm1 = 1 << (r - 1);
226 final int wmr = outDigits - r;
229 if (originalMat ==
null) {
231 originalMat = genMat;
232 genMat =
new int[
dim * numCols];
234 for (d = 0; d <
dim * numCols; d++) genMat[d] = 0;
235 for (j = 0; j <
dim; j++) {
237 for (c = 0; c < numRows; c++) {
239 int colc = (tworm1 + stream.
nextInt(0, tworm1-1)) >> (c + wmr);
241 for (d = 0; d < numCols; d++)
242 genMat[jk + d] ^= ((originalMat[jk + d] >> (outDigits-1-c)) & 1) * colc;
308 public void leftMatrixScrambleSubdiag (
RandomStream stream) {
310 final int allOnes = (1 << outDigits) - 1;
314 if (originalMat ==
null) {
315 originalMat = genMat;
316 genMat =
new int[
dim * numCols];
319 int[][] scrambleMat =
new int[
dim][outDigits];
320 for (j = 0; j <
dim; j++) {
321 scrambleMat[j][0] = allOnes;
322 for (d = 1; d < outDigits; d++)
325 scrambleMat[j][d] = (stream.
nextInt(0, allOnes >> d)) << d;
328 for (j = 0; j <
dim; j++)
329 leftMultiplyMatSubdiag(j, scrambleMat[j]);
334 public void leftMatrixScrambleSubdiag (
int r,
RandomStream stream) {
336 final int allOnes = (1 << r) - 1;
339 if (originalMat ==
null) {
340 originalMat = genMat;
341 genMat =
new int[
dim * numCols];
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);
352 for (j = 0; j <
dim; j++)
353 leftMultiplyMatSubdiag(j, scrambleMat[j]);
362 final int allOnes = (1 << outDigits) - 1;
366 if (originalMat ==
null) {
367 originalMat = genMat;
368 genMat =
new int[
dim * numCols];
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++)
379 if (((1 << d) & lastRow) == 0)
380 scrambleMat[j][d] = 0;
382 scrambleMat[j][d] = (allOnes >> d) << d;
384 for (j = 0; j <
dim; j++)
385 leftMultiplyMatSubdiag(j, scrambleMat[j]);
393 if (originalMat ==
null) {
394 originalMat = genMat;
395 genMat =
new int[
dim * numCols];
399 int[] scrambleMat =
new int[outDigits];
400 final int allOnes = (1 << outDigits) - 1;
401 for (d = 0; d < outDigits; d++)
402 scrambleMat[d] = (allOnes >> d) << d;
403 for (j = 0; j <
dim; j++)
404 leftMultiplyMatSubdiag(j, scrambleMat);
410 if (originalMat ==
null) {
411 originalMat = genMat;
412 genMat =
new int[
dim * numCols];
416 int[] scrambleMat =
new int[outDigits];
418 for (c = 0; c < numCols; c++) {
419 boundInt += (1 << c);
420 scrambleMat[c] = (1 | stream.
nextInt(0, boundInt)) << (outDigits - c - 1);
423 for (j = 0; j <
dim; j++)
424 rightMultiplyMat(j, scrambleMat);
431 private int randomBitVector(
RandomStream stream,
int numBits) {
433 throw new IllegalArgumentException(
"numBits must be >= 1");
435 throw new IllegalArgumentException(
"numBits must be <= 31");
438 maxj = (1 << numBits) - 1;
441 return stream.
nextInt(0, maxj) << (31 - numBits);
475 assert output.length > 0;
476 assert output[0].length ==
dim;
480 for (
int j = 0; j <
dim; ++j) {
482 output[i][j] = int_output[i][j] * normFactor +
EpsilonHalf;
493 assert output.length > 0;
494 assert output[0].length ==
dim;
499 int[] counts =
new int[256];
500 int[] binpos =
new int[256];
502 for (
int j = 0; j <
dim; ++j) {
511 while ((i & bv) == 0) {
515 bvlist[i] = bvlist[i - 1] ^ genMat[j * numCols + pos];
518 for (
int b = 0; b < 4; b++) {
519 for (
int i = 0; i < 256; i++)
525 counts[(bvlist[m + i] & bv) >>> bb]++;
527 for (
int i = 0; i < 255; i++)
528 binpos[i + 1] = binpos[i] + counts[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];
536 int bv = randomBitVector(stream, numBits);
537 output[poslist[0]][j] = bvlist[0] ^ bv;
539 int bv2 = bvlist[i - 1];
541 bv2 = randomBitVector(stream, numBits) & ((int) (1 << (int)
Num.
log2((
double) bv2)) - 1);
543 output[poslist[i]][j] = bvlist[i] ^ bv;
550 private void ScrambleError(String method) {
551 throw new UnsupportedOperationException(
556 ScrambleError(
"leftMatrixScrambleDiag");
560 ScrambleError(
"leftMatrixScrambleFaurePermut");
564 ScrambleError(
"leftMatrixScrambleFaurePermutDiag");
568 ScrambleError(
"leftMatrixScrambleFaurePermutAll");
572 ScrambleError(
"iBinomialMatrixScrambleFaurePermut");
576 ScrambleError(
"iBinomialMatrixScrambleFaurePermutDiag");
580 ScrambleError(
"iBinomialMatrixScrambleFaurePermutAll");
584 ScrambleError(
"stripedMatrixScrambleFaurePermutAll");
601 if (originalMat !=
null) {
602 genMat = originalMat;
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];
628 column >>= outDigits - numRows;
629 for (r = numRows - 1; r >= 0; r--) {
630 bitMatrices[j][r][c] = (column & 1);
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];
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));
667 for (j = 0; j < s; j++) {
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]);
674 System.out.println(sb);
676 System.out.println(
"----------------------------------");
686 for (
int j = 0; j < s; j++) {
688 for (
int c = 0; c < numCols; c++)
689 System.out.println(genMat[j * numCols + c]);
690 System.out.println(
"----------------------------------");
700 for (
int j = 0; j < s; j++) {
702 for (
int c = 0; c < numCols; c++)
703 System.out.println(originalMat[j * numCols + c]);
704 System.out.println(
"----------------------------------");
713 return Arrays.copyOf(genMat, genMat.length);
735 assert points.length > 0;
736 assert points[0].length ==
dim;
738 assert interlacedPoints.length ==
numPoints;
739 assert interlacedPoints.length > 0;
740 assert interlacedPoints[0].length * interlacing ==
dim;
742 double longNormFactor = 1 / (Math.pow(2, 63));
745 for (
int j = 0; j <
dim / interlacing; ++j) {
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;
760 interlacedPoints[i][j] = result * longNormFactor +
EpsilonHalf;
775 result.dim =
dim / interlacing;
776 result.interlacing = 1;
777 result.numCols = numCols;
778 result.numRows = Math.min(
MAXBITS, numRows * interlacing);
780 result.outDigits = outDigits;
781 result.normFactor = normFactor;
784 int[][][] interlacedMatrices =
new int[result.
dim][result.numRows][result.numCols];
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];
798 protected class DigitalNetBase2Iterator
extends DigitalNetIterator {
809 public DigitalNetBase2Iterator() {
812 cachedCurPoint =
new int[
dim + 1];
820 public void init2() {
832 if (digitalShift ==
null)
839 protected void addShiftToCache() {
840 if (digitalShift ==
null)
841 for (
int j = 0; j <
dim; j++)
842 cachedCurPoint[j] = 0;
846 for (
int j = 0; j <
dim; j++)
847 cachedCurPoint[j] = digitalShift[j];
869 int grayCode = i ^ (i >> 1);
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];
885 for (
int j = 0; j <
dim; j++)
886 cachedCurPoint[j] ^= genMat[j * numCols + pos];
895 if (digitalShift ==
null) {
896 for (
int j = 0; j < d; j++)
897 p[j] = cachedCurPoint[j] * normFactor;
899 for (
int j = 0; j < d; j++)
900 p[j] = cachedCurPoint[j] * normFactor +
EpsilonHalf;
908 protected class DigitalNetBase2IteratorNoGray
extends DigitalNetBase2Iterator {
913 public DigitalNetBase2IteratorNoGray() {
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];
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];
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).
double nextDouble()
Same as nextCoordinate().
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,...
static double log2(double x)
Returns x .
static final double TWOEXP[]
Contains the precomputed positive powers of 2.
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 ,...