package umontreal.iro.lecuyer.hups;
/* *
* Title:
* Description:
* Copyright: Copyright (c)
* Company:
* @author
* @version 1.0
*/
import umontreal.iro.lecuyer.util.PrintfFormat;
import cern.colt.list.*;
/**
* Implements a recurrence-based point set defined via a linear
* congruential recurrence of the form
* xi = axi-1mod n
* and
* ui = xi/n. The implementation is done by storing the values
* of ui over the set of all cycles of the recurrence.
*
*/
public class LCGPointSet extends CycleBasedPointSet {
private int a; // Multiplier.
/**
* Constructs and stores the set of cycles for an LCG with
* modulus n and multiplier a.
* If the LCG has full period length n - 1,
* there are two cycles, the first one containing only 0
* and the second one of period length n - 1.
*
* @param n required number of points and modulus of the LCG
*
* @param a generator a of the LCG
*
*
*/
public LCGPointSet (int n, int a) {
this.a = a;
double invn = 1.0 / (double)n; // 1/n
DoubleArrayList c; // Array used to store the current cycle.
long currentState; // The state currently visited.
int i;
boolean stateVisited[] = new boolean[n];
// Indicates which states have been visited so far.
for (i = 0; i < n; i++)
stateVisited[i] = false;
int startState = 0; // First state of the cycle currently considered.
numPoints = 0;
while (startState < n) {
stateVisited[startState] = true;
c = new DoubleArrayList();
c.add (startState * invn);
// We use the fact that a "long" has 64 bits in Java.
currentState = (startState * (long)a) % (long)n;
while (currentState != startState) {
stateVisited[(int)currentState] = true;
c.add (currentState * invn);
currentState = (currentState * (long)a) % (long)n;
}
addCycle (c);
for (i = startState+1; i < n; i++)
if (stateVisited[i] == false)
break;
startState = i;
}
}
/**
* Constructs and stores the set of cycles for an LCG with
* modulus
* n = be + c and multiplier a.
*
*/
public LCGPointSet (int b, int e, int c, int a) {
this (computeModulus (b, e, c), a);
}
private static int computeModulus (int b, int e, int c) {
int n;
int i;
if (b == 2)
n = (1 << e);
else {
for (i = 1, n = b; i < e; i++) n *= b;
}
n += c;
return n;
}
public String toString() {
StringBuffer sb = new StringBuffer ("LCGPointSet:" +
PrintfFormat.NEWLINE);
sb.append (super.toString());
sb.append (PrintfFormat.NEWLINE + "Multiplier a: ");
sb.append (a);
return sb.toString();
}
/**
* Returns the value of the multiplier a.
*
*/
public int geta () {
return a;
}
}
Ads help maintain this website.