[MATH-1155] Performance improvement for WELL class random number generators.
This commit is contained in:
parent
c765796382
commit
dc9fcd4140
|
@ -23,22 +23,21 @@ import org.apache.commons.math4.util.FastMath;
|
|||
|
||||
/** This abstract class implements the WELL class of pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public abstract class AbstractWell extends BitsStreamGenerator implements Serializable {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -817701723016583596L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Current index in the bytes pool. */
|
||||
protected int index;
|
||||
|
@ -46,77 +45,34 @@ public abstract class AbstractWell extends BitsStreamGenerator implements Serial
|
|||
/** Bytes pool. */
|
||||
protected final int[] v;
|
||||
|
||||
/** Index indirection table giving for each index its predecessor taking table size into account. */
|
||||
protected final int[] iRm1;
|
||||
|
||||
/** Index indirection table giving for each index its second predecessor taking table size into account. */
|
||||
protected final int[] iRm2;
|
||||
|
||||
/** Index indirection table giving for each index the value index + m1 taking table size into account. */
|
||||
protected final int[] i1;
|
||||
|
||||
/** Index indirection table giving for each index the value index + m2 taking table size into account. */
|
||||
protected final int[] i2;
|
||||
|
||||
/** Index indirection table giving for each index the value index + m3 taking table size into account. */
|
||||
protected final int[] i3;
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time plus the
|
||||
* system identity hash code of this instance as the seed.</p>
|
||||
* @param k number of bits in the pool (not necessarily a multiple of 32)
|
||||
* @param m1 first parameter of the algorithm
|
||||
* @param m2 second parameter of the algorithm
|
||||
* @param m3 third parameter of the algorithm
|
||||
*/
|
||||
protected AbstractWell(final int k, final int m1, final int m2, final int m3) {
|
||||
this(k, m1, m2, m3, null);
|
||||
protected AbstractWell(final int k) {
|
||||
this(k, null);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param k number of bits in the pool (not necessarily a multiple of 32)
|
||||
* @param m1 first parameter of the algorithm
|
||||
* @param m2 second parameter of the algorithm
|
||||
* @param m3 third parameter of the algorithm
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
protected AbstractWell(final int k, final int m1, final int m2, final int m3, final int seed) {
|
||||
this(k, m1, m2, m3, new int[] { seed });
|
||||
protected AbstractWell(final int k, final int seed) {
|
||||
this(k, new int[] { seed });
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
* @param k number of bits in the pool (not necessarily a multiple of 32)
|
||||
* @param m1 first parameter of the algorithm
|
||||
* @param m2 second parameter of the algorithm
|
||||
* @param m3 third parameter of the algorithm
|
||||
* @param seed the initial seed (32 bits integers array), if null
|
||||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
protected AbstractWell(final int k, final int m1, final int m2, final int m3, final int[] seed) {
|
||||
protected AbstractWell(final int k, final int[] seed) {
|
||||
|
||||
// the bits pool contains k bits, k = r w - p where r is the number
|
||||
// of w bits blocks, w is the block size (always 32 in the original paper)
|
||||
// and p is the number of unused bits in the last block
|
||||
final int w = 32;
|
||||
final int r = (k + w - 1) / w;
|
||||
final int r = calculateBlockCount(k);
|
||||
this.v = new int[r];
|
||||
this.index = 0;
|
||||
|
||||
// precompute indirection index tables. These tables are used for optimizing access
|
||||
// they allow saving computations like "(j + r - 2) % r" with costly modulo operations
|
||||
iRm1 = new int[r];
|
||||
iRm2 = new int[r];
|
||||
i1 = new int[r];
|
||||
i2 = new int[r];
|
||||
i3 = new int[r];
|
||||
for (int j = 0; j < r; ++j) {
|
||||
iRm1[j] = (j + r - 1) % r;
|
||||
iRm2[j] = (j + r - 2) % r;
|
||||
i1[j] = (j + m1) % r;
|
||||
i2[j] = (j + m2) % r;
|
||||
i3[j] = (j + m3) % r;
|
||||
}
|
||||
|
||||
// initialize the pool content
|
||||
setSeed(seed);
|
||||
|
||||
|
@ -124,13 +80,10 @@ public abstract class AbstractWell extends BitsStreamGenerator implements Serial
|
|||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param k number of bits in the pool (not necessarily a multiple of 32)
|
||||
* @param m1 first parameter of the algorithm
|
||||
* @param m2 second parameter of the algorithm
|
||||
* @param m3 third parameter of the algorithm
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
protected AbstractWell(final int k, final int m1, final int m2, final int m3, final long seed) {
|
||||
this(k, m1, m2, m3, new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) });
|
||||
protected AbstractWell(final int k, final long seed) {
|
||||
this(k, new int[] { (int) (seed >>> 32), (int) (seed & 0xffffffffl) });
|
||||
}
|
||||
|
||||
/** Reinitialize the generator as if just built with the given int seed.
|
||||
|
@ -184,4 +137,109 @@ public abstract class AbstractWell extends BitsStreamGenerator implements Serial
|
|||
@Override
|
||||
protected abstract int next(final int bits);
|
||||
|
||||
/** Calculate the number of 32-bits blocks.
|
||||
* @param k number of bits in the pool (not necessarily a multiple of 32)
|
||||
* @return the number of 32-bits blocks
|
||||
*/
|
||||
private static int calculateBlockCount(final int k) {
|
||||
// the bits pool contains k bits, k = r w - p where r is the number
|
||||
// of w bits blocks, w is the block size (always 32 in the original paper)
|
||||
// and p is the number of unused bits in the last block
|
||||
final int w = 32;
|
||||
final int r = (k + w - 1) / w;
|
||||
return r;
|
||||
}
|
||||
|
||||
/**
|
||||
* Inner class used to store the indirection index table which is fixed for a given type of WELL class
|
||||
* of pseudo-random number generator.
|
||||
*/
|
||||
protected static final class IndexTable {
|
||||
/** Index indirection table giving for each index its predecessor taking table size into account. */
|
||||
private final int[] iRm1;
|
||||
|
||||
/** Index indirection table giving for each index its second predecessor taking table size into account. */
|
||||
private final int[] iRm2;
|
||||
|
||||
/** Index indirection table giving for each index the value index + m1 taking table size into account. */
|
||||
private final int[] i1;
|
||||
|
||||
/** Index indirection table giving for each index the value index + m2 taking table size into account. */
|
||||
private final int[] i2;
|
||||
|
||||
/** Index indirection table giving for each index the value index + m3 taking table size into account. */
|
||||
private final int[] i3;
|
||||
|
||||
/** Creates a new pre-calculated indirection index table.
|
||||
* @param k number of bits in the pool (not necessarily a multiple of 32)
|
||||
* @param m1 first parameter of the algorithm
|
||||
* @param m2 second parameter of the algorithm
|
||||
* @param m3 third parameter of the algorithm
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public IndexTable(final int k, final int m1, final int m2, final int m3) {
|
||||
|
||||
final int r = calculateBlockCount(k);
|
||||
|
||||
// precompute indirection index tables. These tables are used for optimizing access
|
||||
// they allow saving computations like "(j + r - 2) % r" with costly modulo operations
|
||||
iRm1 = new int[r];
|
||||
iRm2 = new int[r];
|
||||
i1 = new int[r];
|
||||
i2 = new int[r];
|
||||
i3 = new int[r];
|
||||
for (int j = 0; j < r; ++j) {
|
||||
iRm1[j] = (j + r - 1) % r;
|
||||
iRm2[j] = (j + r - 2) % r;
|
||||
i1[j] = (j + m1) % r;
|
||||
i2[j] = (j + m2) % r;
|
||||
i3[j] = (j + m3) % r;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the predecessor of the given index modulo the table size.
|
||||
* @param index the index to look at
|
||||
* @return (index - 1) % table size
|
||||
*/
|
||||
public int getIndexPred(final int index) {
|
||||
return iRm1[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the second predecessor of the given index modulo the table size.
|
||||
* @param index the index to look at
|
||||
* @return (index - 2) % table size
|
||||
*/
|
||||
public int getIndexPred2(final int index) {
|
||||
return iRm2[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index + M1 modulo the table size.
|
||||
* @param index the index to look at
|
||||
* @return (index + M1) % table size
|
||||
*/
|
||||
public int getIndexM1(final int index) {
|
||||
return i1[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index + M2 modulo the table size.
|
||||
* @param index the index to look at
|
||||
* @return (index + M2) % table size
|
||||
*/
|
||||
public int getIndexM2(final int index) {
|
||||
return i2[index];
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns index + M3 modulo the table size.
|
||||
* @param index the index to look at
|
||||
* @return (index + M3) % table size
|
||||
*/
|
||||
public int getIndexM3(final int index) {
|
||||
return i3[index];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,25 +16,23 @@
|
|||
*/
|
||||
package org.apache.commons.math4.random;
|
||||
|
||||
|
||||
/** This class implements the WELL1024a pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public class Well1024a extends AbstractWell {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 5680173464174485492L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Number of bits in the pool. */
|
||||
private static final int K = 1024;
|
||||
|
@ -48,19 +46,22 @@ public class Well1024a extends AbstractWell {
|
|||
/** Third parameter of the algorithm. */
|
||||
private static final int M3 = 10;
|
||||
|
||||
/** The indirection index table. */
|
||||
private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time as the
|
||||
* seed.</p>
|
||||
*/
|
||||
public Well1024a() {
|
||||
super(K, M1, M2, M3);
|
||||
super(K);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
public Well1024a(int seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
|
@ -68,26 +69,26 @@ public class Well1024a extends AbstractWell {
|
|||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
public Well1024a(int[] seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public Well1024a(long seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected int next(final int bits) {
|
||||
|
||||
final int indexRm1 = iRm1[index];
|
||||
final int indexRm1 = TABLE.getIndexPred(index);
|
||||
|
||||
final int v0 = v[index];
|
||||
final int vM1 = v[i1[index]];
|
||||
final int vM2 = v[i2[index]];
|
||||
final int vM3 = v[i3[index]];
|
||||
final int vM1 = v[TABLE.getIndexM1(index)];
|
||||
final int vM2 = v[TABLE.getIndexM2(index)];
|
||||
final int vM3 = v[TABLE.getIndexM3(index)];
|
||||
|
||||
final int z0 = v[indexRm1];
|
||||
final int z1 = v0 ^ (vM1 ^ (vM1 >>> 8));
|
||||
|
@ -102,4 +103,5 @@ public class Well1024a extends AbstractWell {
|
|||
return z4 >>> (32 - bits);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,22 +19,21 @@ package org.apache.commons.math4.random;
|
|||
|
||||
/** This class implements the WELL19937a pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public class Well19937a extends AbstractWell {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -7462102162223815419L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Number of bits in the pool. */
|
||||
private static final int K = 19937;
|
||||
|
@ -48,19 +47,22 @@ public class Well19937a extends AbstractWell {
|
|||
/** Third parameter of the algorithm. */
|
||||
private static final int M3 = 449;
|
||||
|
||||
/** The indirection index table. */
|
||||
private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time as the
|
||||
* seed.</p>
|
||||
*/
|
||||
public Well19937a() {
|
||||
super(K, M1, M2, M3);
|
||||
super(K);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
public Well19937a(int seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
|
@ -68,27 +70,27 @@ public class Well19937a extends AbstractWell {
|
|||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
public Well19937a(int[] seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public Well19937a(long seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected int next(final int bits) {
|
||||
|
||||
final int indexRm1 = iRm1[index];
|
||||
final int indexRm2 = iRm2[index];
|
||||
final int indexRm1 = TABLE.getIndexPred(index);
|
||||
final int indexRm2 = TABLE.getIndexPred2(index);
|
||||
|
||||
final int v0 = v[index];
|
||||
final int vM1 = v[i1[index]];
|
||||
final int vM2 = v[i2[index]];
|
||||
final int vM3 = v[i3[index]];
|
||||
final int vM1 = v[TABLE.getIndexM1(index)];
|
||||
final int vM2 = v[TABLE.getIndexM2(index)];
|
||||
final int vM3 = v[TABLE.getIndexM3(index)];
|
||||
|
||||
final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]);
|
||||
final int z1 = (v0 ^ (v0 << 25)) ^ (vM1 ^ (vM1 >>> 27));
|
||||
|
@ -104,4 +106,5 @@ public class Well19937a extends AbstractWell {
|
|||
return z4 >>> (32 - bits);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -19,22 +19,21 @@ package org.apache.commons.math4.random;
|
|||
|
||||
/** This class implements the WELL19937c pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public class Well19937c extends AbstractWell {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -7203498180754925124L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Number of bits in the pool. */
|
||||
private static final int K = 19937;
|
||||
|
@ -48,19 +47,22 @@ public class Well19937c extends AbstractWell {
|
|||
/** Third parameter of the algorithm. */
|
||||
private static final int M3 = 449;
|
||||
|
||||
/** The indirection index table. */
|
||||
private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time as the
|
||||
* seed.</p>
|
||||
*/
|
||||
public Well19937c() {
|
||||
super(K, M1, M2, M3);
|
||||
super(K);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
public Well19937c(int seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
|
@ -68,27 +70,27 @@ public class Well19937c extends AbstractWell {
|
|||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
public Well19937c(int[] seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public Well19937c(long seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected int next(final int bits) {
|
||||
|
||||
final int indexRm1 = iRm1[index];
|
||||
final int indexRm2 = iRm2[index];
|
||||
final int indexRm1 = TABLE.getIndexPred(index);
|
||||
final int indexRm2 = TABLE.getIndexPred2(index);
|
||||
|
||||
final int v0 = v[index];
|
||||
final int vM1 = v[i1[index]];
|
||||
final int vM2 = v[i2[index]];
|
||||
final int vM3 = v[i3[index]];
|
||||
final int vM1 = v[TABLE.getIndexM1(index)];
|
||||
final int vM2 = v[TABLE.getIndexM2(index)];
|
||||
final int vM3 = v[TABLE.getIndexM3(index)];
|
||||
|
||||
final int z0 = (0x80000000 & v[indexRm1]) ^ (0x7FFFFFFF & v[indexRm2]);
|
||||
final int z1 = (v0 ^ (v0 << 25)) ^ (vM1 ^ (vM1 >>> 27));
|
||||
|
@ -101,7 +103,6 @@ public class Well19937c extends AbstractWell {
|
|||
v[indexRm2] &= 0x80000000;
|
||||
index = indexRm1;
|
||||
|
||||
|
||||
// add Matsumoto-Kurita tempering
|
||||
// to get a maximally-equidistributed generator
|
||||
z4 ^= (z4 << 7) & 0xe46e1700;
|
||||
|
|
|
@ -16,25 +16,23 @@
|
|||
*/
|
||||
package org.apache.commons.math4.random;
|
||||
|
||||
|
||||
/** This class implements the WELL44497a pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public class Well44497a extends AbstractWell {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -3859207588353972099L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Number of bits in the pool. */
|
||||
private static final int K = 44497;
|
||||
|
@ -48,19 +46,22 @@ public class Well44497a extends AbstractWell {
|
|||
/** Third parameter of the algorithm. */
|
||||
private static final int M3 = 229;
|
||||
|
||||
/** The indirection index table. */
|
||||
private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time as the
|
||||
* seed.</p>
|
||||
*/
|
||||
public Well44497a() {
|
||||
super(K, M1, M2, M3);
|
||||
super(K);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
public Well44497a(int seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
|
@ -68,27 +69,27 @@ public class Well44497a extends AbstractWell {
|
|||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
public Well44497a(int[] seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public Well44497a(long seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected int next(final int bits) {
|
||||
|
||||
final int indexRm1 = iRm1[index];
|
||||
final int indexRm2 = iRm2[index];
|
||||
final int indexRm1 = TABLE.getIndexPred(index);
|
||||
final int indexRm2 = TABLE.getIndexPred2(index);
|
||||
|
||||
final int v0 = v[index];
|
||||
final int vM1 = v[i1[index]];
|
||||
final int vM2 = v[i2[index]];
|
||||
final int vM3 = v[i3[index]];
|
||||
final int vM1 = v[TABLE.getIndexM1(index)];
|
||||
final int vM2 = v[TABLE.getIndexM2(index)];
|
||||
final int vM3 = v[TABLE.getIndexM3(index)];
|
||||
|
||||
// the values below include the errata of the original article
|
||||
final int z0 = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]);
|
||||
|
@ -107,4 +108,5 @@ public class Well44497a extends AbstractWell {
|
|||
return z4 >>> (32 - bits);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -16,25 +16,23 @@
|
|||
*/
|
||||
package org.apache.commons.math4.random;
|
||||
|
||||
|
||||
/** This class implements the WELL44497b pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public class Well44497b extends AbstractWell {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = 4032007538246675492L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Number of bits in the pool. */
|
||||
private static final int K = 44497;
|
||||
|
@ -48,19 +46,22 @@ public class Well44497b extends AbstractWell {
|
|||
/** Third parameter of the algorithm. */
|
||||
private static final int M3 = 229;
|
||||
|
||||
/** The indirection index table. */
|
||||
private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time as the
|
||||
* seed.</p>
|
||||
*/
|
||||
public Well44497b() {
|
||||
super(K, M1, M2, M3);
|
||||
super(K);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
public Well44497b(int seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
|
@ -68,14 +69,14 @@ public class Well44497b extends AbstractWell {
|
|||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
public Well44497b(int[] seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public Well44497b(long seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
@ -84,13 +85,13 @@ public class Well44497b extends AbstractWell {
|
|||
|
||||
// compute raw value given by WELL44497a generator
|
||||
// which is NOT maximally-equidistributed
|
||||
final int indexRm1 = iRm1[index];
|
||||
final int indexRm2 = iRm2[index];
|
||||
final int indexRm1 = TABLE.getIndexPred(index);
|
||||
final int indexRm2 = TABLE.getIndexPred2(index);
|
||||
|
||||
final int v0 = v[index];
|
||||
final int vM1 = v[i1[index]];
|
||||
final int vM2 = v[i2[index]];
|
||||
final int vM3 = v[i3[index]];
|
||||
final int vM1 = v[TABLE.getIndexM1(index)];
|
||||
final int vM2 = v[TABLE.getIndexM2(index)];
|
||||
final int vM3 = v[TABLE.getIndexM3(index)];
|
||||
|
||||
// the values below include the errata of the original article
|
||||
final int z0 = (0xFFFF8000 & v[indexRm1]) ^ (0x00007FFF & v[indexRm2]);
|
||||
|
|
|
@ -19,22 +19,21 @@ package org.apache.commons.math4.random;
|
|||
|
||||
/** This class implements the WELL512a pseudo-random number generator
|
||||
* from François Panneton, Pierre L'Ecuyer and Makoto Matsumoto.
|
||||
|
||||
* <p>This generator is described in a paper by François Panneton,
|
||||
* <p>
|
||||
* This generator is described in a paper by François Panneton,
|
||||
* Pierre L'Ecuyer and Makoto Matsumoto <a
|
||||
* href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng.pdf">Improved
|
||||
* Long-Period Generators Based on Linear Recurrences Modulo 2</a> ACM
|
||||
* Transactions on Mathematical Software, 32, 1 (2006). The errata for the paper
|
||||
* are in <a href="http://www.iro.umontreal.ca/~lecuyer/myftp/papers/wellrng-errata.txt">wellrng-errata.txt</a>.</p>
|
||||
|
||||
*
|
||||
* @see <a href="http://www.iro.umontreal.ca/~panneton/WELLRNG.html">WELL Random number generator</a>
|
||||
* @since 2.2
|
||||
|
||||
*/
|
||||
public class Well512a extends AbstractWell {
|
||||
|
||||
/** Serializable version identifier. */
|
||||
private static final long serialVersionUID = -6104179812103820574L;
|
||||
private static final long serialVersionUID = 20150223L;
|
||||
|
||||
/** Number of bits in the pool. */
|
||||
private static final int K = 512;
|
||||
|
@ -48,19 +47,22 @@ public class Well512a extends AbstractWell {
|
|||
/** Third parameter of the algorithm. */
|
||||
private static final int M3 = 5;
|
||||
|
||||
/** The indirection index table. */
|
||||
private static final IndexTable TABLE = new IndexTable(K, M1, M2, M3);
|
||||
|
||||
/** Creates a new random number generator.
|
||||
* <p>The instance is initialized using the current time as the
|
||||
* seed.</p>
|
||||
*/
|
||||
public Well512a() {
|
||||
super(K, M1, M2, M3);
|
||||
super(K);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single int seed.
|
||||
* @param seed the initial seed (32 bits integer)
|
||||
*/
|
||||
public Well512a(int seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using an int array seed.
|
||||
|
@ -68,25 +70,25 @@ public class Well512a extends AbstractWell {
|
|||
* the seed of the generator will be related to the current time
|
||||
*/
|
||||
public Well512a(int[] seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** Creates a new random number generator using a single long seed.
|
||||
* @param seed the initial seed (64 bits integer)
|
||||
*/
|
||||
public Well512a(long seed) {
|
||||
super(K, M1, M2, M3, seed);
|
||||
super(K, seed);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
@Override
|
||||
protected int next(final int bits) {
|
||||
|
||||
final int indexRm1 = iRm1[index];
|
||||
final int indexRm1 = TABLE.getIndexPred(index);
|
||||
|
||||
final int vi = v[index];
|
||||
final int vi1 = v[i1[index]];
|
||||
final int vi2 = v[i2[index]];
|
||||
final int vi1 = v[TABLE.getIndexM1(index)];
|
||||
final int vi2 = v[TABLE.getIndexM2(index)];
|
||||
final int z0 = v[indexRm1];
|
||||
|
||||
// the values below include the errata of the original article
|
||||
|
|
Loading…
Reference in New Issue