/* *
 * Title:        

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ package umontreal.iro.lecuyer.hups; import umontreal.iro.lecuyer.util.PrintfFormat; import umontreal.iro.lecuyer.rng.RandomStream; /** * This container class realizes padded point sets, constructed * by taking some coordinates from a point set P1, other coordinates * from a point set P2, and so on. * This can be used to implement latin supercube sampling, for example. * After calling the constructor to create the structure, component * point sets can be padded to it by calling {@link #padPointSet padPointSet} or * {@link #padPointSetPermute padPointSetPermute}. * *

* Only sets with the same number of points can be padded. * Point sets with too many points or coordinates can be trimmed down * by using the class {@link SubsetOfPointSet} before they are padded. * Infinite-dimensional point sets are allowed, but once one is padded, * no additional point set can be padded. * *

* The points of each padded set can be permuted randomly, * independently across the padded sets. * If such a random permutation is desired, the point set should be * padded via {@link #padPointSetPermute padPointSetPermute}. * When calling {@link #randomize randomize}, random permutations are generated for * all point sets that have been padded by {@link #padPointSetPermute padPointSetPermute}. * */ public class PaddedPointSet extends PointSet { protected int curPointSets = 0; // Current number of padded point sets. protected int maxPointSets; // Max. number of padded point sets. protected PointSet pointSet[]; // List of padded point sets protected int startDim[]; // Starting dim. for padded points sets. protected int permutation[][]; // One permutation for each point set. /** * Constructs a structure for padding at most maxPointSets point sets. * This structure is initially empty and will eventually contain the different * point sets that are padded. * * @param maxPointSets maximum number of point sets authorized * by the constructed object * */ public PaddedPointSet (int maxPointSets) { this.maxPointSets = maxPointSets; pointSet = new PointSet[maxPointSets]; startDim = new int[maxPointSets]; permutation = new int[maxPointSets][]; } /** * Pads the point set P to the present structure. * * @param P point set being padded * * */ public void padPointSet (PointSet P) { if (curPointSets == maxPointSets) throw new IllegalArgumentException ("Cannot pad more, increase maxPointSets parameter"); if (dim == Integer.MAX_VALUE) throw new IllegalArgumentException ("Cannot pad more, dimension already infinite"); if (curPointSets > 0 && numPoints != P.getNumPoints()) throw new IllegalArgumentException ("Padded points must have same number of points"); if (curPointSets == 0) numPoints = P.getNumPoints(); if (P.getDimension() == Integer.MAX_VALUE) dim = Integer.MAX_VALUE; else dim += P.getDimension(); pointSet[curPointSets] = P; startDim[curPointSets] = dim; ++curPointSets; } /** * Pads the point set P, which is assumed to be finite. * A random permutation will be * generated (when calling {@link #randomize randomize}) and used to access the * coordinates taken from the points of P (i.e., these points * are randomly permuted). * * @param P point set being padded * * */ public void padPointSetPermute (PointSet P) { if (curPointSets == 0) numPoints = P.getNumPoints(); if (numPoints == Integer.MAX_VALUE) throw new IllegalArgumentException ("Cannot generate infinite permutation"); permutation[curPointSets] = new int[numPoints]; for (int i = 0; i < numPoints; i++) permutation[curPointSets][i] = i; padPointSet (P); } public double getCoordinate (int i, int j) { int set = 0; if (j >= dim) throw new IllegalArgumentException ("Not enough dimensions"); while (j >= startDim[set]) set++; /* if (permutation[set] == null) pointSet[set].resetPoint(i); else pointSet[set].resetPoint(permutation[set][i]); if (set == 0) pointSet[0].resetCoordinate (j); else pointSet[set].resetCoordinate (j - startDim[set - 1]); return pointSet[set].nextCoordinate(); */ if (permutation[set] != null) i = permutation[set][i]; if (set != 0) j = j - startDim[set - 1]; return pointSet[set].getCoordinate (i, j); } public void unrandomize() { for (int set = 0; set < curPointSets; set++) { if (permutation[set] != null) { for (int i = 0; i < numPoints; i++) permutation[set][i] = i; } } } public void randomize (RandomStream stream) { // Executes the randomizations of the list super.randomize (stream); /* can also use lazy permutations */ for (int set = 0; set < curPointSets; set++) if (permutation[set] != null) { for (int i = 0; i < numPoints - 1; i++) { int u = stream.nextInt(0, numPoints - i - 1); int h = permutation[set][i]; permutation[set][i] = permutation[set][i + u]; permutation[set][i + u] = h; } } } public PointSetIterator iterator() { return new PaddedIterator(); } public String toString() { StringBuffer sb = new StringBuffer ("Padded point set" + PrintfFormat.NEWLINE); sb.append ("Maximal number of point sets: " + maxPointSets + PrintfFormat.NEWLINE); sb.append ("Current number of point sets: " + curPointSets + PrintfFormat.NEWLINE); sb.append ("Number of points: " + numPoints + PrintfFormat.NEWLINE); for (int i = 0; i < curPointSets; i++) { if (i != 0) sb.append (PrintfFormat.NEWLINE); if (permutation[i] == null) sb.append ("Point set "); else sb.append ("Permuted point set "); sb.append ( i + " information: {" + PrintfFormat.NEWLINE + pointSet[i].toString() + PrintfFormat.NEWLINE + "}"); } return sb.toString(); } // ************************************************************ private class PaddedIterator extends DefaultPointSetIterator { private PointSetIterator[] pointSetIterators; // One for each padded set. private int currentSet = 0; private double[] temp; public PaddedIterator() { pointSetIterators = new PointSetIterator[curPointSets]; int maxdim = 0; for (int i = 0; i < curPointSets; i++) { pointSetIterators[i] = pointSet[i].iterator(); if (pointSet[i].getDimension() > maxdim) maxdim = pointSet[i].getDimension(); if (permutation[i] != null) pointSetIterators[i].setCurPointIndex (permutation[i][0]); } if (maxdim == Integer.MAX_VALUE) temp = new double[16]; else temp = new double[maxdim]; } public void setCurCoordIndex (int j) { int set = 0; if (j >= dim) throw new IllegalArgumentException ("Not enough dimensions"); while (j >= startDim[set]) set++; currentSet = set; pointSetIterators[currentSet].setCurCoordIndex (set == 0 ? j : j - startDim[set-1]); for (set = currentSet+1; set < pointSetIterators.length; set++) pointSetIterators[set].resetCurCoordIndex(); curCoordIndex = j; } public void resetCurCoordIndex() { currentSet = 0; for (int i = 0; i < pointSetIterators.length; i++) pointSetIterators[i].resetCurCoordIndex(); curCoordIndex = 0; } public double nextCoordinate() { if (curPointIndex >= numPoints || curCoordIndex >= dim) outOfBounds(); if (curCoordIndex >= startDim[currentSet]) currentSet++; double coord = pointSetIterators[currentSet].nextCoordinate(); curCoordIndex++; return coord; } public void nextCoordinates (double[] p, int d) { if (curPointIndex >= numPoints || d > dim) outOfBounds(); int i = 0; while (i < d) { int dimen = pointSet[currentSet].getDimension(); if (dimen == Integer.MAX_VALUE) dimen = d - i; else dimen -= pointSetIterators[currentSet].getCurCoordIndex(); pointSetIterators[currentSet].nextCoordinates (temp, dimen); System.arraycopy (temp, 0, p, i, dimen); i += dimen; curCoordIndex += dimen; if (i < d) currentSet++; } } public void setCurPointIndex (int i) { for (int it = 0; it < pointSetIterators.length; it++) pointSetIterators[it].setCurPointIndex (permutation[it] == null ? i : permutation[it][i]); curPointIndex = i; curCoordIndex = 0; currentSet = 0; } public void resetCurPointIndex() { for (int i = 0; i < pointSetIterators.length; i++) { if (permutation[i] == null) pointSetIterators[i].resetCurPointIndex(); else pointSetIterators[i].setCurPointIndex (permutation[i][0]); } curPointIndex = 0; curCoordIndex = 0; currentSet = 0; } public int resetToNextPoint() { for (int i = 0; i < pointSetIterators.length; i++) { if (permutation[i] == null) pointSetIterators[i].resetToNextPoint(); else pointSetIterators[i].setCurPointIndex (permutation[i][curPointIndex+1]); } currentSet = 0; curCoordIndex = 0; return ++curPointIndex; } public String formatState() { return super.formatState() + PrintfFormat.NEWLINE + "Current padded set: " + currentSet; } } }

Ads help maintain this website.