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

* Description:

* Copyright: Copyright (c)

* Company:

* @author * @version 1.0 */ import umontreal.iro.lecuyer.util.PrintfFormat; import umontreal.iro.lecuyer.rng.RandomStream; import cern.colt.list.*; /** * Similar to {@link CycleBasedPointSet}, except that the successive * values in the cycles are stored as integers in the range * * {0,..., 2k -1}, where * 1 <= k <= 31. * The output values ui, j are obtained by dividing these integer * values by 2k. Point sets where the successive coordinates of each * point are obtained via linear recurrences modulo 2 (e.g., linear feedback * shift registers or Korobov-type polynomial lattice rules) * are naturally expressed in this form. * Storing the integers * 2kui, j instead of the ui, j themselves * makes it easier to apply randomizations such as digital random shifts * in base 2, which are applied to the bits before transforming * the value to a real number ui, j. When a random digital shift is * performed, it applies a bitwise exclusive-or of all the points with a single * random point. * */ public abstract class CycleBasedPointSetBase2 extends CycleBasedPointSet { // dim = Integer.MAX_VALUE; // Dimension is infinite. private int[] digitalShift; // Digital shift, initially zero (null). // Entry j is for dimension j. protected int numBits; // Number of bits in stored values. protected double normFactor; // To convert output to (0,1); 1/2^numBits. public double getCoordinate (int i, int j) { // Find cycle that contains point i, then index in cycle. int l = 0; // Length of next cycle. int n = 0; // Total length of cycles added so far. int k; for (k = 0; n <= i; k++) n += l = ((AbstractList) cycles.get (k)).size(); AbstractList curCycle = (AbstractList) cycles.get (k-1); int[] curCycleI = ((IntArrayList) curCycle).elements(); int coordinate = (i - n + l + j) % curCycle.size(); int shift = 0; if (digitalShift != null) { shift = digitalShift[j]; return (shift ^ curCycleI[coordinate]) * normFactor + EpsilonHalf; } else return (shift ^ curCycleI[coordinate]) * normFactor; } public PointSetIterator iterator() { return new CycleBasedPointSetBase2Iterator (); } /** * Adds a random digital shift in base 2 to all the points * of the point set, using stream stream to generate the random numbers, * for coordinates d1 to d2 - 1. * This applies a bitwise exclusive-or of all the points with a single * random point. * * */ public void addRandomShift (int d1, int d2, RandomStream stream) { if (null == stream) throw new IllegalArgumentException ( PrintfFormat.NEWLINE + " Calling addRandomShift with null stream"); if (0 == d2) d2 = Math.max (1, dim); if (digitalShift == null) { digitalShift = new int[d2]; capacityShift = d2; } else if (d2 > capacityShift) { int d3 = Math.max (4, capacityShift); while (d2 > d3) d3 *= 2; int[] temp = new int[d3]; capacityShift = d3; for (int i = 0; i < dimShift; i++) temp[i] = digitalShift[i]; digitalShift = temp; } dimShift = d2; int maxj; if (numBits < 31) { maxj = (1 << numBits) - 1; } else { maxj = 2147483647; } for (int i = d1; i < d2; i++) digitalShift[i] = stream.nextInt (0, maxj); shiftStream = stream; } public void clearRandomShift() { super.clearRandomShift(); digitalShift = null; } public String formatPoints() { StringBuffer sb = new StringBuffer (toString()); for (int c = 0; c < numCycles; c++) { AbstractList curCycle = (AbstractList)cycles.get (c); int[] cycle = ((IntArrayList)curCycle).elements(); sb.append (PrintfFormat.NEWLINE + "Cycle " + c + ": ("); boolean first = true; for (int e = 0; e < curCycle.size(); e++) { if (first) first = false; else sb.append (", "); sb.append (cycle[e]); } sb.append (")"); } return sb.toString(); } // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% public class CycleBasedPointSetBase2Iterator extends CycleBasedPointSetIterator { protected int[] curCycleI; // The array for current cycle public CycleBasedPointSetBase2Iterator () { super (); resetCurCycle (0); } protected void init() { } public void resetCurCycle (int index) { curCycleIndex = index; curCycle = (AbstractList) cycles.get (index); curCycleI = ((IntArrayList) curCycle).elements(); } public double nextCoordinate() { // First, verify if there are still points.... if (curPointIndex >= numPoints) outOfBounds(); int x = curCycleI [curCoordInCycle]; if (digitalShift != null) { if (curCoordIndex >= dimShift) // Extend the shift. addRandomShift (dimShift, curCoordIndex + 1, shiftStream); x ^= digitalShift[curCoordIndex]; } curCoordIndex++; curCoordInCycle++; if (curCoordInCycle >= curCycle.size()) curCoordInCycle = 0; if (digitalShift == null) return x * normFactor; else return x * normFactor + EpsilonHalf; } public void nextCoordinates (double p[], int dim) { // First, verify if there are still points.... if (curPointIndex >= numPoints) outOfBounds(); if (curCoordIndex + dim >= dimShift) addRandomShift (dimShift, curCoordIndex + dim + 1, shiftStream); int j = curCoordInCycle; int maxj = curCycle.size(); int x; for (int i = 0; i < dim; i++) { x = curCycleI [curCoordInCycle++]; if (curCoordInCycle >= maxj) curCoordInCycle = 0; if (digitalShift == null) p[i] = x * normFactor; else p[i] = (digitalShift[curCoordIndex + i] ^ x) * normFactor + EpsilonHalf; } curCoordIndex += dim; } public int nextPoint (double p[], int dim) { if (getCurPointIndex() >= getNumPoints ()) outOfBounds(); curCoordIndex = 0; curCoordInCycle = startPointInCycle; nextCoordinates (p, dim); resetToNextPoint(); return curPointIndex; } } }

Ads help maintain this website.