package umontreal.iro.lecuyer.hups;
/* *
 * Title:        

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ /** * This abstract class describes methods specific to digital sequences. * Concrete classes must implement the {@link #extendSequence extendSequence} method * that increases the number of points of the digital sequence. * Calling the methods {@link #toNet toNet} or {@link #toNetShiftCj toNetShiftCj} * will transform the digital sequence into a digital net, which has * a fixed number of points n. * */ public abstract class DigitalSequence extends DigitalNet { /** * Increases the number of points to n = bk from now on. * * @param k there will be b^k points * * */ public abstract void extendSequence (int k); private int[][] copyDigitalShift (int[][] S) { // Copy the shift S into T and returns T. if (S == null) return null; int[][] T = new int [S.length][S[0].length]; for (int i = 0; i < S.length; ++i) for (int j = 0; j < S[0].length; ++j) T[i][j] = S[i][j]; return T; } private DigitalNet initNetVar (boolean shiftFlag) { // Initializes the net for the two toNet methods below. DigitalNet net = new DigitalNet (); if (shiftFlag) net.dim = dim + 1; else net.dim = dim; net.numPoints = numPoints; net.numCols = numCols; net.numRows = numRows; net.outDigits = outDigits; net.normFactor = normFactor; net.b = b; net.factor = new double[outDigits]; for (int i = 0; i < outDigits; i++) net.factor[i] = factor[i]; net.genMat = new int[net.dim * numCols][numRows]; net.shiftStream = shiftStream; net.capacityShift = capacityShift; net.dimShift = dimShift; net.digitalShift = copyDigitalShift (digitalShift); if (shiftFlag && shiftStream != null) { net.addRandomShift (dimShift, dimShift + 1, shiftStream); } return net; } /** * Transforms this digital sequence into a digital net without changing * the coordinates of the points. Returns the digital net. * */ public DigitalNet toNet() { DigitalNet net = initNetVar (false); final int N = dim * numCols; for (int i = 0; i < N; i++) for (int j = 0; j < numRows; j++) net.genMat[i][j] = genMat[i][j]; return net; } /** * Transforms this digital sequence into a digital net by adding one dimension * and shifting all coordinates by one position. The first coordinate of point * i is i/n, where n is the total number of points. * Thus if the coordinates of a point of the digital sequence were * * (x0, x1, x2,…, xs-1), then the coordinates of the * point of the digital net will be * (i/n, x0, x1,…, xs-1). * In other words, for the digital net, * C0 is the reflected * identity and for j >= 1, the * Cj used is the * * Cj-1 of the digital sequence. If the digital sequence uses * a digital shift, then the digital net will include the digital shift with * one more dimension also. Returns the digital net. * */ public DigitalNet toNetShiftCj() { DigitalNet net = initNetVar (true); int j, c, l, start; /* Shift all coordinates from the sequence by 1 dimension */ for (j = dim; j >= 1; j--) { start = j * numCols; for (c = 0; c < numCols; c++) for (l = 0; l < numRows; l++) net.genMat[start+c][l] = genMat[start - numCols + c][l]; } // j = 0: initialize C_0 to the reflected identity. for (c = 0; c < numCols; c++) { for (l = 0; l < numRows; l++) net.genMat[c][l] = 0; net.genMat[c][numCols-c-1] = 1; } return net; } /** * Similar to {@link #iterator iterator}, except that the first coordinate * of the points is i/n, the second coordinate is obtained via * the generating matrix * C0, the next one via * C1, * and so on. Thus, this iterator shifts all coordinates of each point * one position to the right and sets the first coordinate of point i * to i/n, so that the points enumerated with this iterator have one more * dimension. A digital shift, if present, will have one more dimension also. * This iterator uses the Gray code. * */ public PointSetIterator iteratorShift() { return new DigitalNetIteratorShiftGenerators(); } /** * This iterator shifts all coordinates of each point one position to the right * and sets the first coordinate of point i to i/n, so that the points * enumerated with this iterator have one more dimension. * This iterator does not use the Gray code; the points are enumerated in the * order of their first coordinate before randomization. * A digital shift, if present, will have one more dimension also. * */ public PointSetIterator iteratorShiftNoGray() { return new DigitalNetIteratorShiftNoGray(); } // ************************************************************************ protected class DigitalNetIteratorShiftGenerators extends DigitalNetIterator { // Similar to DigitalNetIterator; the first coordinate // of point i is i/n, and all the others are shifted one position // to the right. The points have dimension = dim + 1. public DigitalNetIteratorShiftGenerators() { super(); dimS = dim + 1; if (digitalShift != null && dimShift < dimS) addRandomShift (dimShift, dimS, shiftStream); init2 (); } public void init() { // This method is necessary to overload } // the init() of DigitalNetIterator public void init2() { // See constructor resetCurPointIndex(); } public void setCurPointIndex (int i) { if (i == 0) { resetCurPointIndex(); return; } curPointIndex = i; curCoordIndex = 0; // Digits of Gray code, used to reconstruct cachedCurPoint. idigits = intToDigitsGray (b, i, numCols, bdigit, gdigit); int c, j, l, sum; for (j = 1; j <= dim; j++) { for (l = 0; l < outDigits; l++) { if (digitalShift == null) sum = 0; else sum = digitalShift[j][l]; if (l < numRows) for (c = 0; c < idigits; c++) sum += genMat[(j - 1)*numCols+c][l] * gdigit[c]; cachedCurPoint [j*outDigits+l] = sum % b; } } // The case j = 0 for (l = 0; l < outDigits; l++) { if (digitalShift == null) sum = 0; else sum = digitalShift[0][l]; if (l < numRows) for (c = 0; c < idigits; c++) if (l == numCols-c-1) sum += gdigit[c]; cachedCurPoint [l] = sum % b; } } public int resetToNextPoint() { // incremental computation. curPointIndex++; curCoordIndex = 0; if (curPointIndex >= numPoints) return curPointIndex; // Update the digital expansion of i in base b, and find the // position of change in the Gray code. Set all digits == b-1 to 0 // and increase the first one after by 1. int pos; // Position of change in the Gray code. for (pos = 0; gdigit[pos] == b-1; pos++) gdigit[pos] = 0; gdigit[pos]++; // Update the cachedCurPoint by adding the column of the gener. // matrix that corresponds to the Gray code digit that has changed. // The digital shift is already incorporated in the cached point. int c, j, l; int lsup = numRows; // Max index l if (outDigits < numRows) lsup = outDigits; for (j = 1; j <= dim; j++) { for (l = 0; l < lsup; l++) { cachedCurPoint[j*outDigits + l] += genMat[(j-1)*numCols + pos][l]; cachedCurPoint[j * outDigits + l] %= b; } } // The case j = 0 l = numCols-pos-1; if (l < lsup) { cachedCurPoint[l] += 1; cachedCurPoint[l] %= b; } return curPointIndex; } } // ************************************************************************ protected class DigitalNetIteratorShiftNoGray extends DigitalNetIterator { // Similar to DigitalNetIterator; the first coordinate // of point i is i/n, and all the others are shifted one position // to the right. The points have dimension = dim + 1. public DigitalNetIteratorShiftNoGray() { super(); dimS = dim + 1; if (digitalShift != null && dimShift < dimS) addRandomShift (dimShift, dimS, shiftStream); init2(); } public void init() { // This method is necessary to overload } // the init() of DigitalNetIterator public void init2() { // See constructor resetCurPointIndex(); } public void setCurPointIndex (int i) { if (i == 0) { resetCurPointIndex(); return; } curPointIndex = i; curCoordIndex = 0; // Convert i to b-ary representation, put digits in bdigit. idigits = intToDigitsGray (b, i, numCols, bdigit, gdigit); int c, j, l, sum; for (j = 1; j <= dim; j++) { for (l = 0; l < outDigits; l++) { if (digitalShift == null) sum = 0; else sum = digitalShift[j][l]; if (l < numRows) for (c = 0; c < idigits; c++) { sum += genMat[(j-1)*numCols+c][l] * bdigit[c]; sum %= b; } cachedCurPoint [j*outDigits+l] = sum; } } // The case j = 0 for (l = 0; l < outDigits; l++) { if (digitalShift == null) sum = 0; else sum = digitalShift[0][l]; if (l < numRows) for (c = 0; c < idigits; c++) if (l == numCols-c-1) sum += bdigit[c]; cachedCurPoint [l] = sum % b; } } public int resetToNextPoint() { curPointIndex++; curCoordIndex = 0; if (curPointIndex >= numPoints) return curPointIndex; // Find the position of change in the digits of curPointIndex in base // b. Set all digits = b-1 to 0; increase the first one after by 1. int pos; for (pos = 0; bdigit[pos] == b-1; pos++) bdigit[pos] = 0; bdigit[pos]++; // Update the digital expansion of curPointIndex in base b. // Update the cachedCurPoint by adding 1 unit at the digit pos. // If pos > 0, remove b-1 units in the positions < pos. Since // calculations are mod b, this is equivalent to adding 1 unit. // The digital shift is already incorporated in the cached point. int c, j, l; int lsup = numRows; // Max index l if (outDigits < numRows) lsup = outDigits; for (j = 1; j <= dim; j++) { for (l = 0; l < lsup; l++) { for (c = 0; c <= pos; c++) cachedCurPoint[j*outDigits + l] += genMat[(j-1)*numCols + c][l]; cachedCurPoint[j * outDigits + l] %= b; } } // The case j = 0 for (l = 0; l < lsup; l++) { for (c = 0; c <= pos; c++) if (l == numCols-c-1) { cachedCurPoint[l] += 1; cachedCurPoint[l] %= b; } } return curPointIndex; } } }

Ads help maintain this website.