package umontreal.iro.lecuyer.hups;
/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
import umontreal.iro.lecuyer.util.PrintfFormat;
/**
* This class implements digital nets or digital sequences formed by the
* first n = bk points of the Faure sequence in base b.
* Values of n up to 231 are allowed.
* One has r = k.
* The generator matrices are
*
*
*
* Cj = Pj mod b
*
* for
* j = 0,..., s - 1, where
* P is a k×k upper
* triangular matrix whose entry (l, c) is the number of combinations
* of l objects among c,
* for l <= c and is 0 for l > c.
* The matrix
* C0 is the identity,
* C1 = P,
* and the other
* Cj's can be defined recursively via
*
* Cj = PCj-1mod b.
* Our implementation uses the recursion
*
*
*
* Combination(c, l ) = Combination(c - 1, l ) + Combination(c - 1, l - 1)
*
* to evaluate the binomial coefficients in the matrices
* Cj,
* as suggested by Fox.
* The entries xj, l, c of
* Cj are computed as follows:
*
*
*
*
* xj, c, c
* =
* 1
* for c = 0,..., k - 1,
*
* xj, 0, c
* =
* jxj, 0, c-1
* for c = 1,..., k - 1,
*
* xj, l, c
* =
* xj, l-1, c-1 + jxj, l, c-1
* for 2 <= c < l <= k - 1,
*
* xj, l, c
* =
* 0
* for c > l or l >= k.
*
*
*
*
*
* For any integer m > 0 and ν >= 0, if we look at the
* vector
* (ui, j, 1,..., ui, j, m) (the first m digits
* of coordinate j of the output) when i goes from
* νbm to
* (ν +1)bm - 1, this vector takes each of its bm
* possible values exactly once.
* In particular, for ν = 0, ui, j visits each value in the
* set
* {0, 1/bm, 2/bm,...,(bm -1)/bm} exactly once, so all
* one-dimensional projections of the point set are identical.
* However, the values are visited in a different order for
* the different values of j (otherwise all coordinates would be identical).
* For j = 0, they are visited in the same
* order as in the van der Corput sequence in base b.
*
*
* An important property of Faure nets is that for any integers m > 0
* and ν >= 0, the point set
*
* {ui for
* i = νbm,...,(ν +1)bm -1}
* is a (0, m, s)-net in base b.
* In particular, for n = bk, the first n points form a
* (0, k, s)-net in base b.
* The Faure nets are also projection-regular and dimension-stationary.
*
*
* To obtain digital nets from the generalized Faure sequence
* , where
* Pj is left-multiplied by some
* invertible matrix
* Aj, it suffices to apply an appropriate
* matrix scramble (e.g., via {@link #leftMatrixScramble leftMatrixScramble}).
* This changes the order in which ui, j visits its different
* values, for each coordinate j, but does not change the set of values
* that are visited. The (0, m, s)-net property stated above remains valid.
*
*/
public class FaureSequence extends DigitalSequence {
// Maximum dimension for the case where b is not specified.
// Can be extended by extending the precomputed array prime[].
private static final int MAXDIM = 500;
// For storing the generator matrices for given dim and numPoints.
private int[][][] v;
/**
* Constructs a digital net in base b,
* with n = bk points and w output digits,
* in dim dimensions.
* The points are the first n points of the Faure sequence.
* The generator matrices
* Cj are r×k.
* Unless, one plans to apply a randomization on more than k digits
* (e.g., a random digital shift for w > k digits, or a linear
* scramble yielding r > k digits), one should
* take w = r = k for better computational efficiency.
* Restrictions: dim <= 500 and
* bk <= 231.
*
* @param b base
*
* @param k there will be b^k points
*
* @param r number of rows in the generator matrices
*
* @param w number of output digits
*
* @param dim dimension of the point set
*
*
*/
public FaureSequence (int b, int k, int r, int w, int dim) {
init (b, k, r, w, dim);
}
private void init (int b, int k, int r, int w, int dim) {
if (dim < 1)
throw new IllegalArgumentException
("Dimension for FaureSequence must be > 1");
if ((double)k * Math.log ((double)b) > (31.0 * Math.log (2.0)))
throw new IllegalArgumentException
("Trying to construct a FaureSequence with too many points");
if (r < k || w < r)
throw new IllegalArgumentException
("One must have k <= r <= w for FaureSequence");
this.b = b;
numCols = k;
numRows = r;
outDigits = w;
this.dim = dim;
int i, j;
numPoints = b;
for (i=1; i(b, k, w, w, dim)
* with base b equal to the smallest prime larger or equal to dim,
* and with at least n points.
*
* The values of k, r, and w are taken as
*
* k = ceil(logbn) and
*
* r = w = max(k, floor(30/log2b)).
*
* @param n minimal number of points
*
* @param dim dimension of the point set
*
*
*/
public FaureSequence (int n, int dim) {
if ((dim < 1) || (dim > MAXDIM))
throw new IllegalArgumentException
("Dimension for Faure net must be > 1 and < " + MAXDIM);
b = getSmallestPrime (dim);
numCols = (int) Math.ceil (Math.log ((double) n)
/ Math.log ((double) b));
outDigits = (int) Math.floor (Math.log ((double)(1 << (MAXBITS - 1)))
/ Math.log ((double)b));
outDigits = Math.max (outDigits, numCols);
numRows = outDigits;
init (b, numCols, numRows, outDigits, dim);
}
public String toString() {
StringBuffer sb = new StringBuffer ("Faure sequence:" +
PrintfFormat.NEWLINE);
sb.append (super.toString());
return sb.toString();
}
public void extendSequence (int k) {
init (b, k, numRows, outDigits, dim);
}
// Fills up the generator matrices in genMat for a Faure sequence.
// See Glasserman (2004), \cite{fGLA04a}, page 301.
private void initGenMat() {
int j, c, l;
// Initialize C_0 to the identity (for first coordinate).
for (c = 0; c < numCols; c++) {
for (l = 0; l < numRows; l++)
genMat[c][l] = 0;
genMat[c][c] = 1;
}
// Compute C_1, ... ,C_{dim-1}.
for (j = 1; j < dim; j++) {
genMat[j*numCols][0] = 1;
for (c = 1; c < numCols; c++) {
genMat[j*numCols+c][c] = 1;
genMat[j*numCols+c][0] = (j * genMat[j*numCols+c-1][0]) % b;
}
for (c = 2; c < numCols; c++) {
for (l = 1; l < c; l++)
genMat[j*numCols+c][l] = (genMat[j*numCols+c-1][l-1]
+ j * genMat[j*numCols+c-1][l]) % b;
}
for (c = 0; c < numCols; c++)
for (l = c+1; l < numRows; l++)
genMat[j*numCols+c][l] = 0;
}
/*
for (j = 0; j < dim; j++) {
for (l = 0; l < numRows; l++) {
for (c = 0; c < numCols; c++)
System.out.print (" " + genMat[j*numCols+c][l]);
System.out.println ("");
}
System.out.println ("");
}
*/
}
/*
// Fills up the generator matrices in genMat for a Faure net.
// See Glasserman (2004), \cite{fGLA04a}, page 301.
protected void initGenMatNet() {
int j, c, l, start;
// Initialize C_0 to the reflected identity (for first coordinate).
for (c = 0; c < numCols; c++) {
for (l = 0; l < numRows; l++)
genMat[c][l] = 0;
genMat[c][numCols-c-1] = 1;
}
// Initialize C_1 to the identity (for second coordinate).
for (c = 0; c < numCols; c++) {
for (l = 0; l < numRows; l++)
genMat[numCols+c][l] = 0;
genMat[numCols+c][c] = 1;
}
// Compute C_2, ... ,C_{dim-1}.
for (j = 2; j < dim; j++) {
start = j * numCols;
genMat[start][0] = 1;
for (c = 1; c < numCols; c++) {
genMat[start+c][c] = 1;
genMat[start+c][0] = ((j-1) * genMat[start+c-1][0]) % b;
}
for (c = 2; c < numCols; c++) {
for (l = 1; l < c; l++)
genMat[start+c][l] = (genMat[start+c-1][l-1]
+ (j-1) * genMat[start+c-1][l]) % b;
}
for (c = 0; c < numCols; c++)
for (l = c+1; l < numRows; l++)
genMat[start+c][l] = 0;
}
}
*/
// Returns the smallest prime larger or equal to d.
private int getSmallestPrime (int d) {
return primes[d-1];
}
// Gives the appropriate prime base for each dimension.
// Perhaps should be internal to getPrime, and non-static, to avoid
// wasting time and memory when this array is not needed ???
static final int primes[] =
{2,2,3,5,5,7,7,11,11,11,11,13,13,17,17,17,17,19,19,23,
23,23,23,29,29,29,29,29,29,31,31,37,37,37,37,37,37,41,41,41,
41,43,43,47,47,47,47,53,53,53,53,53,53,59,59,59,59,59,59,61,
61,67,67,67,67,67,67,71,71,71,71,73,73,79,79,79,79,79,79,83,
83,83,83,89,89,89,89,89,89,97,97,97,97,97,97,97,97,101,101,101,
101,103,103,107,107,107,107,109,109,113,113,113,113,127,127,127,127,127,127,127,
127,127,127,127,127,127,127,131,131,131,131,137,137,137,137,137,137,139,139,149,
149,149,149,149,149,149,149,149,149,151,151,157,157,157,157,157,157,163,163,163,
163,163,163,167,167,167,167,173,173,173,173,173,173,179,179,179,179,179,179,181,
181,191,191,191,191,191,191,191,191,191,191,193,193,197,197,197,197,199,199,211,
211,211,211,211,211,211,211,211,211,211,211,223,223,223,223,223,223,223,223,223,
223,223,223,227,227,227,227,229,229,233,233,233,233,239,239,239,239,239,239,241,
241,251,251,251,251,251,251,251,251,251,251,257,257,257,257,257,257,263,263,263,
263,263,263,269,269,269,269,269,269,271,271,277,277,277,277,277,277,281,281,281,
281,283,283,293,293,293,293,293,293,293,293,293,293,307,307,307,307,307,307,307,
307,307,307,307,307,307,307,311,311,311,311,313,313,317,317,317,317,331,331,331,
331,331,331,331,331,331,331,331,331,331,331,337,337,337,337,337,337,347,347,347,
347,347,347,347,347,347,347,349,349,353,353,353,353,359,359,359,359,359,359,367,
367,367,367,367,367,367,367,373,373,373,373,373,373,379,379,379,379,379,379,383,
383,383,383,389,389,389,389,389,389,397,397,397,397,397,397,397,397,401,401,401,
401,409,409,409,409,409,409,409,409,419,419,419,419,419,419,419,419,419,419,421,
421,431,431,431,431,431,431,431,431,431,431,433,433,439,439,439,439,439,439,443,
443,443,443,449,449,449,449,449,449,457,457,457,457,457,457,457,457,461,461,461,
461,463,463,467,467,467,467,479,479,479,479,479,479,479,479,479,479,479,479,487,
487,487,487,487,487,487,487,491,491,491,491,499,499,499,499,499,499,499,499,503};
}
Ads help maintain this website.