You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2019/06/11 17:08:25 UTC
[commons-rng] branch master updated: Test generators known to be
non-functional with a zero-byte seed.
This is an automated email from the ASF dual-hosted git repository.
aherbert pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/commons-rng.git
The following commit(s) were added to refs/heads/master by this push:
new aed6da0 Test generators known to be non-functional with a zero-byte seed.
aed6da0 is described below
commit aed6da0f56e53757cb9b27c47faa380baf733261
Author: aherbert <ah...@apache.org>
AuthorDate: Tue Jun 11 17:38:31 2019 +0100
Test generators known to be non-functional with a zero-byte seed.
---
.../org/apache/commons/rng/core/RandomAssert.java | 65 +++++++++++++++++++---
.../core/source32/MultiplyWithCarry256Test.java | 13 +++++
.../commons/rng/core/source32/Well1024aTest.java | 13 +++++
.../commons/rng/core/source32/Well19937aTest.java | 13 +++++
.../commons/rng/core/source32/Well19937cTest.java | 13 +++++
.../commons/rng/core/source32/Well44497aTest.java | 13 +++++
.../commons/rng/core/source32/Well44497bTest.java | 13 +++++
.../commons/rng/core/source32/Well512aTest.java | 13 +++++
8 files changed, 147 insertions(+), 9 deletions(-)
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/RandomAssert.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/RandomAssert.java
index b3743ce..76c5293 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/RandomAssert.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/RandomAssert.java
@@ -214,6 +214,29 @@ public class RandomAssert {
}
/**
+ * Assert that following a set number of warm-up cycles the random generator produces
+ * at least one non-zero output for {@link UniformRandomProvider#nextLong()} over the
+ * given number of test cycles.
+ *
+ * <p>Helper function to add the seed element and bit that was non zero to the fail message.
+ *
+ * @param rng Random generator.
+ * @param warmupCycles Number of warm-up cycles.
+ * @param testCycles Number of test cycles.
+ * @param seedElement Seed element for the message.
+ * @param bit Seed bit for the message.
+ */
+ private static void assertNextLongNonZeroOutputFromSingleBitSeed(
+ UniformRandomProvider rng, int warmupCycles, int testCycles, int seedElement, int bit) {
+ try {
+ assertNextLongNonZeroOutput(rng, warmupCycles, testCycles);
+ } catch (AssertionError ex) {
+ Assert.fail("No non-zero output after " + (warmupCycles + testCycles) + " cycles. " +
+ "Seed element [" + seedElement + "], bit=" + bit);
+ }
+ }
+
+ /**
* Assert that the random generator created using an {@code int[]} seed with a
* single bit set is functional. This is tested using the
* {@link #assertNextLongNonZeroOutput(UniformRandomProvider, int, int)} using
@@ -224,17 +247,41 @@ public class RandomAssert {
*/
public static <T extends UniformRandomProvider> void
assertIntArrayConstructorWithSingleBitSeedIsFunctional(Class<T> type, int size) {
+ assertIntArrayConstructorWithSingleBitInPoolIsFunctional(type, 32 * size);
+ }
+
+ /**
+ * Assert that the random generator created using an {@code int[]} seed with a
+ * single bit set is functional. This is tested using the
+ * {@link #assertNextLongNonZeroOutput(UniformRandomProvider, int, int)} using
+ * two times the seed size as the warm-up and test cycles.
+ *
+ * <p>The seed size is determined from the size of the bit pool. Bits are set for every position
+ * in the pool from most significant first. If the pool size is not a multiple of 32 then the
+ * remaining lower significant bits of the last seed position are not tested.</p>
+ *
+ * @param type Class of the generator.
+ * @param k Number of bits in the pool (not necessarily a multiple of 32).
+ */
+ public static <T extends UniformRandomProvider> void
+ assertIntArrayConstructorWithSingleBitInPoolIsFunctional(Class<T> type, int k) {
try {
// Find the int[] constructor
final Constructor<T> constructor = type.getConstructor(int[].class);
+ final int size = (k + 31) / 32;
final int[] seed = new int[size];
- for (int i = 0; i < size; i++) {
- seed[i] = 1;
+ int remaining = k;
+ for (int i = 0; i < seed.length; i++) {
+ seed[i] = 0x80000000;
for (int j = 0; j < 32; j++) {
final UniformRandomProvider rng = constructor.newInstance(seed);
- RandomAssert.assertNextLongNonZeroOutput(rng, 2 * size, 2 * size);
- // Eventually rolls-over to reset to zero
- seed[i] <<= 1;
+ RandomAssert.assertNextLongNonZeroOutputFromSingleBitSeed(rng, 2 * size, 2 * size, i, 31 - j);
+ // Eventually reset to zero
+ seed[i] >>>= 1;
+ // Terminate when the entire bit pool has been tested
+ if (--remaining == 0) {
+ return;
+ }
}
Assert.assertEquals("Seed element was not reset", 0, seed[i]);
}
@@ -265,12 +312,12 @@ public class RandomAssert {
final Constructor<T> constructor = type.getConstructor(long[].class);
final long[] seed = new long[size];
for (int i = 0; i < size; i++) {
- seed[i] = 1;
+ seed[i] = 0x8000000000000000L;
for (int j = 0; j < 64; j++) {
final UniformRandomProvider rng = constructor.newInstance(seed);
- RandomAssert.assertNextLongNonZeroOutput(rng, 2 * size, 2 * size);
- // Eventually rolls-over to reset to zero
- seed[i] <<= 1;
+ RandomAssert.assertNextLongNonZeroOutputFromSingleBitSeed(rng, 2 * size, 2 * size, i, 63 - j);
+ // Eventually reset to zero
+ seed[i] >>>= 1;
}
Assert.assertEquals("Seed element was not reset", 0L, seed[i]);
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256Test.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256Test.java
index e8f85a6..7db040b 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256Test.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/MultiplyWithCarry256Test.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class MultiplyWithCarry256Test {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 257;
+
@Test
public void testMarsaglia() {
final int[] seed = {
@@ -192,4 +195,14 @@ public class MultiplyWithCarry256Test {
RandomAssert.assertEquals(expectedSequence, new MultiplyWithCarry256(seed));
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new MultiplyWithCarry256(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitSeedIsFunctional(MultiplyWithCarry256.class, SEED_SIZE);
+ }
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well1024aTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well1024aTest.java
index a44fccb..746f096 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well1024aTest.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well1024aTest.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class Well1024aTest {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 32;
+
@Test
public void testReferenceCode() {
final Well1024a rng = new Well1024a(new int[] {
@@ -66,4 +69,14 @@ public class Well1024aTest {
RandomAssert.assertEquals(expectedSequence, rng);
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new Well1024a(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitSeedIsFunctional(Well1024a.class, SEED_SIZE);
+ }
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937aTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937aTest.java
index cbda07e..cc2a509 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937aTest.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937aTest.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class Well19937aTest {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 624;
+
@Test
public void testReferenceCode() {
final int[] base = {
@@ -168,4 +171,14 @@ public class Well19937aTest {
RandomAssert.assertEquals(expectedSequence, rng);
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new Well19937a(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitInPoolIsFunctional(Well19937a.class, 19937);
+ }
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937cTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937cTest.java
index a6625e1..4a28d3b 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937cTest.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well19937cTest.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class Well19937cTest {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 624;
+
@Test
public void testReferenceCode() {
final int[] base = {
@@ -168,4 +171,14 @@ public class Well19937cTest {
RandomAssert.assertEquals(expectedSequence, rng);
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new Well19937c(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitInPoolIsFunctional(Well19937c.class, 19937);
+ }
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497aTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497aTest.java
index 1f8177f..e42f488 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497aTest.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497aTest.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class Well44497aTest {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 1391;
+
@Test
public void testReferenceCode() {
final int[] base = {
@@ -296,4 +299,14 @@ public class Well44497aTest {
RandomAssert.assertEquals(expectedSequence, rng);
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new Well44497a(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitInPoolIsFunctional(Well44497a.class, 44497);
+ }
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497bTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497bTest.java
index de50a40..a7afa55 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497bTest.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well44497bTest.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class Well44497bTest {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 1391;
+
@Test
public void testReferenceCode() {
final int[] base = {
@@ -296,4 +299,14 @@ public class Well44497bTest {
RandomAssert.assertEquals(expectedSequence, rng);
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new Well44497b(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitInPoolIsFunctional(Well44497b.class, 44497);
+ }
}
diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well512aTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well512aTest.java
index dac7bab..5e858be 100644
--- a/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well512aTest.java
+++ b/commons-rng-core/src/test/java/org/apache/commons/rng/core/source32/Well512aTest.java
@@ -20,6 +20,9 @@ import org.apache.commons.rng.core.RandomAssert;
import org.junit.Test;
public class Well512aTest {
+ /** The size of the array seed. */
+ private static final int SEED_SIZE = 16;
+
@Test
public void testReferenceCode() {
final Well512a rng = new Well512a(new int[] {
@@ -64,4 +67,14 @@ public class Well512aTest {
RandomAssert.assertEquals(expectedSequence, rng);
}
+
+ @Test
+ public void testConstructorWithZeroSeedIsNonFunctional() {
+ RandomAssert.assertNextIntZeroOutput(new Well512a(new int[SEED_SIZE]), 2 * SEED_SIZE);
+ }
+
+ @Test
+ public void testConstructorWithSingleBitSeedIsFunctional() {
+ RandomAssert.assertIntArrayConstructorWithSingleBitSeedIsFunctional(Well512a.class, SEED_SIZE);
+ }
}