http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/Providers64ParametricTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/Providers64ParametricTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/Providers64ParametricTest.java index c710621..79f5e72 100644 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/Providers64ParametricTest.java +++ b/commons-rng-core/src/test/java/org/apache/commons/rng/Providers64ParametricTest.java @@ -34,19 +34,15 @@ public class Providers64ParametricTest { * * @param rng RNG to be tested. */ - public Providers64ParametricTest(ProvidersList.Data data) { - final RandomSource source = data.getSource(); - final Object seed = data.getSeed(); - final Object[] args = data.getArgs(); - generator = RandomSource.create(source, seed, args); + public Providers64ParametricTest(RestorableUniformRandomProvider rng) { + generator = rng; } @Parameters(name = "{index}: data={0}") - public static Iterable<ProvidersList.Data[]> getList() { + public static Iterable<RestorableUniformRandomProvider[]> getList() { return ProvidersList.list64(); } - @Test public void testNextBytesChunks() { final int[] chunkSizes = { 8, 16, 24 };
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersCommonParametricTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersCommonParametricTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersCommonParametricTest.java index 5e0aa02..014574d 100644 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersCommonParametricTest.java +++ b/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersCommonParametricTest.java @@ -42,28 +42,19 @@ import org.apache.commons.rng.internal.RandomProviderDefaultState; @RunWith(value=Parameterized.class) public class ProvidersCommonParametricTest { /** RNG under test. */ - private final UniformRandomProvider generator; - /** RNG specifier. */ - private final RandomSource originalSource; - /** Seed (constructor's first parameter). */ - private final Object originalSeed; - /** Constructor's additional parameters. */ - private final Object[] originalArgs; + private final RestorableUniformRandomProvider generator; /** * Initializes generator instance. * * @param rng RNG to be tested. */ - public ProvidersCommonParametricTest(ProvidersList.Data data) { - originalSource = data.getSource(); - originalSeed = data.getSeed(); - originalArgs = data.getArgs(); - generator = RandomSource.create(originalSource, originalSeed, originalArgs); + public ProvidersCommonParametricTest(RestorableUniformRandomProvider rng) { + generator = rng; } @Parameters(name = "{index}: data={0}") - public static Iterable<ProvidersList.Data[]> getList() { + public static Iterable<RestorableUniformRandomProvider[]> getList() { return ProvidersList.list(); } @@ -234,81 +225,6 @@ public class ProvidersCommonParametricTest { checkRandomWalk(1000, nextMethod); } - // Seeding tests. - - @Test(expected=UnsupportedOperationException.class) - public void testUnsupportedSeedType() { - final byte seed = 123; - RandomSource.create(originalSource, seed, originalArgs); - } - - @Test - public void testAllSeedTypes() { - final Integer intSeed = -12131415; - final Long longSeed = -1213141516171819L; - final int[] intArraySeed = new int[] { 0, 11, -22, 33, -44, 55, -66, 77, -88, 99 }; - final long[] longArraySeed = new long[] { 11111L, -222222L, 3333333L, -44444444L }; - final byte[] byteArraySeed = new byte[] { -128, -91, -45, -32, -1, 0, 11, 23, 54, 88, 127 }; - - final Object[] seeds = new Object[] { null, - intSeed, - longSeed, - intArraySeed, - longArraySeed, - byteArraySeed }; - - int nonNativeSeedCount = 0; - int seedCount = 0; - for (Object s : seeds) { - ++seedCount; - if (!(originalSource.isNativeSeed(s))) { - ++nonNativeSeedCount; - } - - Assert.assertNotEquals(intSeed, originalSeed); - RandomSource.create(originalSource, s, originalArgs); - } - - Assert.assertEquals(6, seedCount); - Assert.assertEquals(5, nonNativeSeedCount); - } - - @Test - public void testEmptyIntArraySeed() { - final int[] empty = new int[0]; - Assume.assumeTrue(originalSource.isNativeSeed(empty)); - - // Exercise the default seeding procedure. - final UniformRandomProvider rng = RandomSource.create(originalSource, empty, originalArgs); - checkNextIntegerInRange(rng, 10, 10000); - } - - @Test - public void testEmptyLongArraySeed() { - final long[] empty = new long[0]; - Assume.assumeTrue(originalSource.isNativeSeed(empty)); - - // Exercise the default seeding procedure. - final UniformRandomProvider rng = RandomSource.create(originalSource, empty, originalArgs); - checkNextIntegerInRange(rng, 10, 10000); - } - - @Ignore@Test - public void testZeroIntArraySeed() { - // Exercise capacity to escape all "zero" state. - final int[] zero = new int[2000]; // Large enough to fill the entire state with zeroes. - final UniformRandomProvider rng = RandomSource.create(originalSource, zero, originalArgs); - checkNextIntegerInRange(rng, 10, 10000); - } - - @Ignore@Test - public void testZeroLongArraySeed() { - // Exercise capacity to escape all "zero" state. - final long[] zero = new long[2000]; // Large enough to fill the entire state with zeroes. - final UniformRandomProvider rng = RandomSource.create(originalSource, zero, originalArgs); - checkNextIntegerInRange(rng, 10, 10000); - } - // State save and restore tests. @Test @@ -317,10 +233,8 @@ public class ProvidersCommonParametricTest { // state is away from its initial settings. final int n = 10000; - // Cast is OK: all instances created by this library inherit from "BaseProvider". - final RestorableUniformRandomProvider restorable = (RestorableUniformRandomProvider) generator; // Save. - final RandomProviderState state = restorable.saveState(); + final RandomProviderState state = generator.saveState(); // Store some values. final List<Number> listOrig = makeList(n); // Discard a few more. @@ -328,7 +242,7 @@ public class ProvidersCommonParametricTest { Assert.assertTrue(listDiscard.size() != 0); Assert.assertFalse(listOrig.equals(listDiscard)); // Reset. - restorable.restoreState(state); + generator.restoreState(state); // Replay. final List<Number> listReplay = makeList(n); Assert.assertFalse(listOrig == listReplay); @@ -336,69 +250,6 @@ public class ProvidersCommonParametricTest { Assert.assertTrue(listOrig.equals(listReplay)); } - @Test - public void testUnrestorable() { - // Create two generators of the same type as the one being tested. - final UniformRandomProvider rng1 = RandomSource.create(originalSource, originalSeed, originalArgs); - final UniformRandomProvider rng2 = RandomSource.unrestorable(RandomSource.create(originalSource, originalSeed, originalArgs)); - - // Ensure that they generate the same values. - RandomAssert.assertProduceSameSequence(rng1, rng2); - - // Cast must work. - final RestorableUniformRandomProvider restorable = (RestorableUniformRandomProvider) rng1; - // Cast must fail. - try { - final RestorableUniformRandomProvider dummy = (RestorableUniformRandomProvider) rng2; - Assert.fail("Cast should have failed"); - } catch (ClassCastException e) { - // Expected. - } - } - - @Test - public void testSerializingState() - throws IOException, - ClassNotFoundException { - // Large "n" is not necessary here as we only test the serialization. - final int n = 100; - - // Cast is OK: all instances created by this library inherit from "BaseProvider". - final RestorableUniformRandomProvider restorable = (RestorableUniformRandomProvider) generator; - - // Save. - final RandomProviderState stateOrig = restorable.saveState(); - // Serialize. - ByteArrayOutputStream bos = new ByteArrayOutputStream(); - ObjectOutputStream oos = new ObjectOutputStream(bos); - oos.writeObject(((RandomProviderDefaultState) stateOrig).getState()); - - // Store some values. - final List<Number> listOrig = makeList(n); - - // Discard a few more. - final List<Number> listDiscard = makeList(n); - Assert.assertTrue(listDiscard.size() != 0); - Assert.assertFalse(listOrig.equals(listDiscard)); - - // Retrieve from serialized stream. - ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray()); - ObjectInputStream ois = new ObjectInputStream(bis); - final RandomProviderState stateNew = new RandomProviderDefaultState((byte[]) ois.readObject()); - - Assert.assertTrue(stateOrig != stateNew); - - // Reset. - restorable.restoreState(stateNew); - - // Replay. - final List<Number> listReplay = makeList(n); - Assert.assertFalse(listOrig == listReplay); - - // Check that the serialized data recreated the orginal state. - Assert.assertTrue(listOrig.equals(listReplay)); - } - @Test(expected=IllegalArgumentException.class) public void testStateWrongSize() { // We don't know what is the state of "java.lang.Random": skipping. @@ -406,12 +257,12 @@ public class ProvidersCommonParametricTest { final RandomProviderState state = new DummyGenerator().saveState(); // Try to restore with an invalid state (wrong size). - ((RestorableUniformRandomProvider) generator).restoreState(state); + generator.restoreState(state); } @Test(expected=IllegalArgumentException.class) public void testRestoreForeignState() { - ((RestorableUniformRandomProvider) generator).restoreState(new RandomProviderState() {}); + generator.restoreState(new RandomProviderState() {}); } http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersList.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersList.java b/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersList.java index 82e646b..c2d76a0 100644 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersList.java +++ b/commons-rng-core/src/test/java/org/apache/commons/rng/ProvidersList.java @@ -21,6 +21,22 @@ import java.util.List; import java.util.ArrayList; import java.util.Collections; +import org.apache.commons.rng.internal.source32.JDKRandom; +import org.apache.commons.rng.internal.source32.Well512a; +import org.apache.commons.rng.internal.source32.Well1024a; +import org.apache.commons.rng.internal.source32.Well19937a; +import org.apache.commons.rng.internal.source32.Well19937c; +import org.apache.commons.rng.internal.source32.Well44497a; +import org.apache.commons.rng.internal.source32.Well44497b; +import org.apache.commons.rng.internal.source32.ISAACRandom; +import org.apache.commons.rng.internal.source32.MersenneTwister; +import org.apache.commons.rng.internal.source32.MultiplyWithCarry256; +import org.apache.commons.rng.internal.source32.KISSRandom; +import org.apache.commons.rng.internal.source64.SplitMix64; +import org.apache.commons.rng.internal.source64.XorShift1024Star; +import org.apache.commons.rng.internal.source64.TwoCmres; +import org.apache.commons.rng.internal.source64.MersenneTwister64; + /** * The purpose of this class is to provide the list of all generators * implemented in the library. @@ -32,34 +48,37 @@ import java.util.Collections; */ public class ProvidersList { /** List of all RNGs implemented in the library. */ - private static final List<Data[]> LIST = new ArrayList<Data[]>(); + private static final List<RestorableUniformRandomProvider[]> LIST = + new ArrayList<RestorableUniformRandomProvider[]>(); /** List of 32-bits based RNGs. */ - private static final List<Data[]> LIST32 = new ArrayList<Data[]>(); + private static final List<RestorableUniformRandomProvider[]> LIST32 = + new ArrayList<RestorableUniformRandomProvider[]>(); /** List of 64-bits based RNGs. */ - private static final List<Data[]> LIST64 = new ArrayList<Data[]>(); + private static final List<RestorableUniformRandomProvider[]> LIST64 = + new ArrayList<RestorableUniformRandomProvider[]>(); static { try { // "int"-based RNGs. - add(LIST32, RandomSource.JDK, -122333444455555L); - add(LIST32, RandomSource.MT, new int[] { -123, -234, -345 }); - add(LIST32, RandomSource.WELL_512_A, new int[] { -23, -34, -45 }); - add(LIST32, RandomSource.WELL_1024_A, new int[] { -1234, -2345, -3456 }); - add(LIST32, RandomSource.WELL_19937_A, new int[] { -2123, -3234, -4345 }); - add(LIST32, RandomSource.WELL_19937_C, new int[] { -123, -234, -345, -456 }); - add(LIST32, RandomSource.WELL_44497_A, new int[] { -12345, -23456, -34567 }); - add(LIST32, RandomSource.WELL_44497_B, new int[] { 123, 234, 345 }); - add(LIST32, RandomSource.ISAAC, new int[] { 123, -234, 345, -456 }); - add(LIST32, RandomSource.MWC_256, new int[] { 12, -1234, -3456, 45678 }); - add(LIST32, RandomSource.KISS, new int[] { 12, 1234, 23456, 345678 }); + add(LIST32, new JDKRandom(-122333444455555L)); + add(LIST32, new MersenneTwister(new int[] { -123, -234, -345 })); + add(LIST32, new Well512a(new int[] { -23, -34, -45 })); + add(LIST32, new Well1024a(new int[] { -1234, -2345, -3456 })); + add(LIST32, new Well19937a(new int[] { -2123, -3234, -4345 })); + add(LIST32, new Well19937c(new int[] { -123, -234, -345, -456 })); + add(LIST32, new Well44497a(new int[] { -12345, -23456, -34567 })); + add(LIST32, new Well44497b(new int[] { 123, 234, 345 })); + add(LIST32, new ISAACRandom(new int[] { 123, -234, 345, -456 })); + add(LIST32, new MultiplyWithCarry256(new int[] { 12, -1234, -3456, 45678 })); + add(LIST32, new KISSRandom(new int[] { 12, 1234, 23456, 345678 })); // ... add more here. // "long"-based RNGs. - add(LIST64, RandomSource.SPLIT_MIX_64, -988777666655555L); - add(LIST64, RandomSource.XOR_SHIFT_1024_S, new long[] { 123456L, 234567L, -345678L }); - add(LIST64, RandomSource.TWO_CMRES, 55443322); - add(LIST64, RandomSource.TWO_CMRES_SELECT, -987654321, 5, 8); - add(LIST64, RandomSource.MT_64, new long[] { 1234567L, 2345678L, -3456789L }); + add(LIST64, new SplitMix64(-988777666655555L)); + add(LIST64, new XorShift1024Star(new long[] { 123456L, 234567L, -345678L })); + add(LIST64, new TwoCmres(55443322)); + add(LIST64, new TwoCmres(-987654321, 5, 8)); + add(LIST64, new MersenneTwister64(new long[] { 1234567L, 2345678L, -3456789L })); // ... add more here. // Do not modify the remaining statements. @@ -82,14 +101,9 @@ public class ProvidersList { * Helper to statisfy Junit requirement that each parameter set contains * the same number of objects. */ - private static void add(List<Data[]> list, - RandomSource source, - Object ... data) { - final RandomSource rng = source; - final Object seed = data.length > 0 ? data[0] : null; - final Object[] args = data.length > 1 ? Arrays.copyOfRange(data, 1, data.length) : null; - - list.add(new Data[] { new Data(rng, seed, args) }); + private static void add(List<RestorableUniformRandomProvider[]> list, + RestorableUniformRandomProvider rng) { + list.add(new RestorableUniformRandomProvider[] { rng }); } /** @@ -98,7 +112,7 @@ public class ProvidersList { * * @return the list of all generators. */ - public static Iterable<Data[]> list() { + public static Iterable<RestorableUniformRandomProvider[]> list() { return Collections.unmodifiableList(LIST); } @@ -108,7 +122,7 @@ public class ProvidersList { * * @return the list of 32-bits based generators. */ - public static Iterable<Data[]> list32() { + public static Iterable<RestorableUniformRandomProvider[]> list32() { return Collections.unmodifiableList(LIST32); } @@ -118,42 +132,7 @@ public class ProvidersList { * * @return the list of 64-bits based generators. */ - public static Iterable<Data[]> list64() { + public static Iterable<RestorableUniformRandomProvider[]> list64() { return Collections.unmodifiableList(LIST64); } - - /** - * Helper. - * Better not to mix Junit assumptions of the usage of "Object[]". - */ - public static class Data { - private final RandomSource source; - private final Object seed; - private final Object[] args; - - public Data(RandomSource source, - Object seed, - Object[] args) { - this.source = source; - this.seed = seed; - this.args = args; - } - - public RandomSource getSource() { - return source; - } - - public Object getSeed() { - return seed; - } - - public Object[] getArgs() { - return args == null ? null : Arrays.copyOf(args, args.length); - } - - @Override - public String toString() { - return source.toString() + " seed=" + seed + " args=" + Arrays.toString(args); - } - } } http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/RandomAssert.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/RandomAssert.java b/commons-rng-core/src/test/java/org/apache/commons/rng/RandomAssert.java index 58a34c4..d62f78b 100644 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/RandomAssert.java +++ b/commons-rng-core/src/test/java/org/apache/commons/rng/RandomAssert.java @@ -33,60 +33,4 @@ public class RandomAssert { Assert.assertEquals("Value at position " + i, expected[i], rng.nextLong()); } } - - /** - * Exercise all methods from the UniformRandomProvider interface, and - * ensure that the two generators produce the same sequence. - * - * @param rng1 RNG. - * @param rng2 RNG. - */ - public static void assertProduceSameSequence(UniformRandomProvider rng1, - UniformRandomProvider rng2) { - for (int i = 0; i < 54; i++) { - Assert.assertTrue(rng1.nextBoolean() == rng2.nextBoolean()); - } - for (int i = 0; i < 23; i++) { - Assert.assertEquals(rng1.nextInt(), rng2.nextInt()); - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 5; j++) { - final int max = 107 * i + 374 * j + 11; - Assert.assertEquals(rng1.nextInt(max), rng2.nextInt(max)); - } - } - for (int i = 0; i < 23; i++) { - Assert.assertEquals(rng1.nextLong(), rng2.nextLong()); - } - for (int i = 0; i < 4; i++) { - for (int j = 0; j < 5; j++) { - final long max = (Long.MAX_VALUE << 2) + 107 * i + 374 * j + 11; - Assert.assertEquals(rng1.nextLong(max), rng2.nextLong(max)); - } - } - for (int i = 0; i < 103; i++) { - Assert.assertEquals(rng1.nextFloat(), rng2.nextFloat(), 0); - } - for (int i = 0; i < 79; i++) { - Assert.assertEquals(rng1.nextDouble(), rng2.nextDouble(), 0); - } - - final int size = 345; - final byte[] a1 = new byte[size]; - final byte[] a2 = new byte[size]; - - for (int i = 0; i < 3; i++) { - rng1.nextBytes(a1); - rng2.nextBytes(a2); - Assert.assertTrue(Arrays.equals(a1, a2)); - } - - for (int i = 0; i < 5; i++) { - final int offset = 200 + i; - final int n = 23 + i; - rng1.nextBytes(a1, offset, n); - rng2.nextBytes(a2, offset, n); - Assert.assertTrue(Arrays.equals(a1, a2)); - } - } } http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/RandomSourceTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/RandomSourceTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/RandomSourceTest.java deleted file mode 100644 index ce24954..0000000 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/RandomSourceTest.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for {@link RandomSource}. - */ -public class RandomSourceTest { - @Test - public void testCreateInt() { - final int n = 4; - for (int i = 0; i < n; i++) { - // Can fail, but unlikely given the range. - Assert.assertNotEquals(RandomSource.createInt(), - RandomSource.createInt()); - } - } - - @Test - public void testCreateLong() { - final int n = 6; - for (int i = 0; i < n; i++) { - // Can fail, but unlikely given the range. - Assert.assertNotEquals(RandomSource.createLong(), - RandomSource.createLong()); - } - } - - @Test - public void testCreateIntArray() { - final int n = 13; - final int[] seed = RandomSource.createIntArray(n); - Assert.assertEquals(n, seed.length); - - for (int i = 1; i < n; i++) { - // Can fail, but unlikely given the range. - Assert.assertNotEquals(seed[i - 1], seed[i]); - } - } - - @Test - public void testCreateLongArray() { - final int n = 9; - final long[] seed = RandomSource.createLongArray(n); - Assert.assertEquals(n, seed.length); - - for (int i = 1; i < n; i++) { - // Can fail, but unlikely given the range. - Assert.assertNotEquals(seed[i - 1], seed[i]); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2IntArrayTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2IntArrayTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2IntArrayTest.java deleted file mode 100644 index e1e1e87..0000000 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2IntArrayTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.internal.util; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for the {@link ByteArray2IntArray} converter. - */ -public class ByteArray2IntArrayTest { - @Test - public void testSeedSizeIsMultipleOfIntSize() { - final byte[] seed = new byte[128]; - final int[] out = new ByteArray2IntArray().convert(seed); - Assert.assertEquals(32, out.length); - } - - @Test - public void testSeedSizeIsNotMultipleOfIntSize() { - final int len = 16; - final ByteArray2IntArray conv = new ByteArray2IntArray(); - for (int i = 1; i < 4; i++) { - final byte[] seed = new byte[len + i]; - final int[] out = conv.convert(seed); - Assert.assertEquals(5, out.length); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2LongArrayTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2LongArrayTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2LongArrayTest.java deleted file mode 100644 index c42a7b9..0000000 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/ByteArray2LongArrayTest.java +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.internal.util; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for the {@link ByteArray2LongArray} converter. - */ -public class ByteArray2LongArrayTest { - @Test - public void testSeedSizeIsMultipleOfLongSize() { - final byte[] seed = new byte[128]; - final long[] out = new ByteArray2LongArray().convert(seed); - Assert.assertEquals(16, out.length); - } - - @Test - public void testSeedSizeIsNotMultipleOfLongSize() { - final int len = 16; - final ByteArray2LongArray conv = new ByteArray2LongArray(); - for (int i = 1; i < 8; i++) { - final byte[] seed = new byte[len + i]; - final long[] out = conv.convert(seed); - Assert.assertEquals(3, out.length); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/IntArray2LongArrayTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/IntArray2LongArrayTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/IntArray2LongArrayTest.java deleted file mode 100644 index 57c2d7e..0000000 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/IntArray2LongArrayTest.java +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.internal.util; - -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for the {@link IntArray2LongArray} converter. - */ -public class IntArray2LongArrayTest { - @Test - public void testSeedSizeIsMultipleOfLongSize() { - final int[] seed = new int[12]; - final long[] out = new IntArray2LongArray().convert(seed); - Assert.assertEquals(6, out.length); - } - - @Test - public void testSeedSizeIsNotMultipleOfLongSize() { - final int[] seed = new int[13]; - final long[] out = new IntArray2LongArray().convert(seed); - Assert.assertEquals(7, out.length); - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/SeedFactoryTest.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/SeedFactoryTest.java b/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/SeedFactoryTest.java deleted file mode 100644 index 43c754b..0000000 --- a/commons-rng-core/src/test/java/org/apache/commons/rng/internal/util/SeedFactoryTest.java +++ /dev/null @@ -1,111 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.internal.util; - -import java.util.Map; -import java.util.HashMap; -import org.junit.Assert; -import org.junit.Test; - -/** - * Tests for {@link SeedFactory}. - */ -public class SeedFactoryTest { - @Test - public void testCreateLong() { - final Map<Long, Integer> values = new HashMap<Long, Integer>(); - - final int n = 100000; - for (int i = 0; i < n; i++) { - final long v = SeedFactory.createLong(); - - Integer count = values.get(v); - if (count == null) { - count = 0; - } - values.put(v, count + 1); - } - - // Check that all seeds are different. - assertDifferentValues(values); - } - - @Test - public void testCreateLongArray() { - final Map<Long, Integer> values = new HashMap<Long, Integer>(); - - final int n = 100000; - final long[] array = SeedFactory.createLongArray(n); - Assert.assertEquals(n, array.length); - - for (long v : array) { - Integer count = values.get(v); - if (count == null) { - count = 0; - } - values.put(v, count + 1); - } - - // Check that all seeds are different. - assertDifferentValues(values); - } - - @Test - public void testCreateIntArray() { - final Map<Long, Integer> values = new HashMap<Long, Integer>(); - - for (int i = 0; i < 50000; i++) { - final int[] a = SeedFactory.createIntArray(2); - final long v = NumberFactory.makeLong(a[0], a[1]); - Integer count = values.get(v); - if (count == null) { - count = 0; - } - values.put(v, count + 1); - } - - // Check that all pairs in are different. - assertDifferentValues(values); - } - - /** - * Asserts that all the keys in given {@code map} have their - * value equal to 1. - * - * @param map Map to counts. - */ - private static <T> void assertDifferentValues(Map<T, Integer> map) { - final StringBuilder sb = new StringBuilder(); - - int duplicates = 0; - for (Map.Entry<T, Integer> entry : map.entrySet()) { - final int count = entry.getValue(); - if (count <= 0) { - throw new IllegalStateException(); - } - - if (count > 1) { - duplicates += count - 1; - sb.append(entry.getKey() + ": " + count + "\n"); - } - } - - if (duplicates > 0) { - Assert.fail(duplicates + " duplicates\n" + sb); - } - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/userguide/c/rng/stdin2testu01.c ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/userguide/c/rng/stdin2testu01.c b/commons-rng-core/src/userguide/c/rng/stdin2testu01.c deleted file mode 100644 index d1a4a6a..0000000 --- a/commons-rng-core/src/userguide/c/rng/stdin2testu01.c +++ /dev/null @@ -1,127 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -/* - * Utility for simple interfacing with the "TestU01" library: - * http://simul.iro.umontreal.ca/testu01/tu01.html - * - * It reads from its standard input an infinite sequence of 32-bits - * integers and runs one of the test suites "SmallCrush", "Crush" or - * "BigCrush". - * "TestU01" writes its report to standard output. - */ - -#include <stdint.h> -#include <unistd.h> -#include <string.h> - -#include <testu01/unif01.h> -#include <testu01/bbattery.h> -#include <testu01/util.h> - -#define TU_S "SmallCrush" -#define TU_C "Crush" -#define TU_B "BigCrush" -#define BUFFER_LENGTH 256 - -typedef struct { - unsigned long buffer[BUFFER_LENGTH]; - uint32_t index; -} StdinReader_state; - -unsigned long nextInt(void *par, - void *sta) { - StdinReader_state *state = (StdinReader_state *) sta; - if (state->index >= BUFFER_LENGTH) { - /* Refill. */ - fread(state->buffer, sizeof(unsigned long), BUFFER_LENGTH, stdin); - state->index = 0; - } - - uint32_t random = state->buffer[state->index]; - ++state->index; /* Next request. */ - - return random; -} - -double nextDouble(void *par, - void *sta) { - return nextInt(par, sta) / 4294967296.0; -} - - -static void dummy(void *sta) { - printf("N/A"); - - return; -} - -unif01_Gen *createStdinReader(void) { - unif01_Gen *gen; - StdinReader_state *state; - size_t len; - char name[60]; - - state = util_Malloc(sizeof(StdinReader_state)); - - gen = util_Malloc(sizeof(unif01_Gen)); - gen->state = state; - gen->param = NULL; - gen->Write = dummy; - gen->GetU01 = nextDouble; - gen->GetBits = nextInt; - - strcpy(name, "stdin"); - len = strlen(name); - gen->name = util_Calloc(len + 1, sizeof (char)); - strncpy(gen->name, name, len); - - // Read binary input. - freopen(NULL, "rb", stdin); - state->index = BUFFER_LENGTH; - - return gen; -} - -void deleteStdinReader(unif01_Gen *gen) { - gen->state = util_Free(gen->state); - gen->name = util_Free(gen->name); - util_Free(gen); -} - -int main(int argc, - char **argv) { - unif01_Gen *gen = createStdinReader(); - char *spec = argv[1]; - - if (argc < 2) { - printf("[ERROR] Specify test suite: '%s', '%s' or '%s'\n", TU_S, TU_C, TU_B); - exit(1); - } else if (strcmp(spec, TU_S) == 0) { - bbattery_SmallCrush(gen); - } else if (strcmp(spec, TU_C) == 0) { - bbattery_Crush(gen); - } else if (strcmp(spec, TU_B) == 0) { - bbattery_BigCrush(gen); - } else { - printf("[ERROR] Unknown specification: '%s'\n", spec); - exit(1); - } - - deleteStdinReader(gen); - return 0; -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java b/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java deleted file mode 100644 index 5c17a7a..0000000 --- a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/ComputePi.java +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.userguide; - -import org.apache.commons.rng.UniformRandomProvider; -import org.apache.commons.rng.RandomSource; - -/** - * Computation of \( \pi \) using Monte-Carlo integration. - * - * The computation estimates the value by computing the probability that - * a point \( p = (x, y) \) will lie in the circle of radius \( r = 1 \) - * inscribed in the square of side \( r = 1 \). - * The probability could be computed by \[ area_{circle} / area_{square} \], - * where \( area_{circle} = \pi * r^2 \) and \( area_{square} = 4 r^2 \). - * Hence, the probability is \( \frac{\pi}{4} \). - * - * The Monte Carlo simulation will produce \( N \) points. - * Defining \( N_c \) as the number of point that satisfy \( x^2 + y^2 <= 1 \), - * we will have \( \frac{N_c}{N} \approx \frac{\pi}{4} \). - */ -public class ComputePi extends MonteCarloIntegration { - /** Domain dimension. */ - private static final int DIMENSION = 2; - - /** - * @param source RNG algorithm. - */ - public ComputePi(RandomSource source) { - super(source, DIMENSION); - } - - /** - * Arguments: - * <ul> - * <li> - * Number of random 2-dimensional points to generate. - * </li> - * <li> - * {@link RandomSource Random source identifier}. - * </li> - * </ul> - */ - public static void main(String[] args) { - if (args.length != 2) { - throw new IllegalStateException("Missing arguments"); - } - - final long numPoints = Long.valueOf(args[0]); - final RandomSource randomSource = RandomSource.valueOf(args[1]); - - final ComputePi piApp = new ComputePi(randomSource); - final double piMC = piApp.compute(numPoints); - - System.out.println("After generating " + (DIMENSION * numPoints) + - " random numbers, the error on ð is " + Math.abs(piMC - Math.PI)); - } - - /** - * @param n Number of random points to generate. - * @return the approximate value of pi. - */ - public double compute(long numPoints) { - return 4 * integrate(numPoints); - } - - /** {@inheritDoc} */ - @Override - protected boolean isInside(double ... rand) { - final double r2 = rand[0] * rand[0] + rand[1] * rand[1]; - return r2 <= 1; - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/GeneratorsList.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/GeneratorsList.java b/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/GeneratorsList.java deleted file mode 100644 index d8e788d..0000000 --- a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/GeneratorsList.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.userguide; - -import java.util.List; -import java.util.ArrayList; -import java.util.Iterator; - -import org.apache.commons.rng.UniformRandomProvider; -import org.apache.commons.rng.RandomSource; - -/** - * List of generators. - */ -public class GeneratorsList implements Iterable<UniformRandomProvider> { - /** List. */ - private final List<UniformRandomProvider> list = new ArrayList<>(); - - /** - * Creates list. - */ - public GeneratorsList() { - list.add(RandomSource.create(RandomSource.JDK)); - list.add(RandomSource.create(RandomSource.MT)); - list.add(RandomSource.create(RandomSource.WELL_512_A)); - list.add(RandomSource.create(RandomSource.WELL_1024_A)); - list.add(RandomSource.create(RandomSource.WELL_19937_A)); - list.add(RandomSource.create(RandomSource.WELL_19937_C)); - list.add(RandomSource.create(RandomSource.WELL_44497_A)); - list.add(RandomSource.create(RandomSource.WELL_44497_B)); - list.add(RandomSource.create(RandomSource.ISAAC)); - list.add(RandomSource.create(RandomSource.MT_64)); - list.add(RandomSource.create(RandomSource.SPLIT_MIX_64)); - list.add(RandomSource.create(RandomSource.XOR_SHIFT_1024_S)); - list.add(RandomSource.create(RandomSource.TWO_CMRES)); - list.add(RandomSource.create(RandomSource.MWC_256)); - list.add(RandomSource.create(RandomSource.KISS)); - } - - /** {@inheritDoc} */ - @Override - public Iterator<UniformRandomProvider> iterator() { - return list.iterator(); - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java b/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java deleted file mode 100644 index e7e17a8..0000000 --- a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/MonteCarloIntegration.java +++ /dev/null @@ -1,90 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package org.apache.commons.rng.userguide; - -import org.apache.commons.rng.UniformRandomProvider; -import org.apache.commons.rng.RandomSource; - -/** - * <a href="https://en.wikipedia.org/wiki/Monte_Carlo_integration">Monte-Carlo method</a> - * for approximating an integral on a n-dimensional unit cube. - */ -public abstract class MonteCarloIntegration { - /** RNG. */ - private final UniformRandomProvider rng; - /** Integration domain dimension. */ - private final int dimension; - - /** - * Simulation constructor. - * - * @param source RNG algorithm. - * @param dimension Integration domain dimension. - */ - public MonteCarloIntegration(RandomSource source, - int dimension) { - this.rng = RandomSource.create(source); - this.dimension = dimension; - } - - /** - * Run the Monte-Carlo integration. - * - * @param n Number of random points to generate. - * @return the integral. - */ - public double integrate(long n) { - double result = 0; - long inside = 0; - long total = 0; - while (total < n) { - if (isInside(generateU01())) { - ++inside; - } - - ++total; - result = inside / (double) total; - } - - return result; - } - - /** - * Indicates whether the given points is inside the region whose - * integral is computed. - * - * @param point Point whose coordinates are random numbers uniformly - * distributed in the unit interval. - * @return {@code true} if the {@code point} is inside. - */ - protected abstract boolean isInside(double ... point); - - /** - * @return a value from a random sequence uniformly distributed - * in the {@code [0, 1)} interval. - */ - private double[] generateU01() { - final double[] rand = new double[dimension]; - - for (int i = 0; i < dimension; i++) { - rand[i] = rng.nextDouble(); - } - - return rand; - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/RandomStressTester.java ---------------------------------------------------------------------- diff --git a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/RandomStressTester.java b/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/RandomStressTester.java deleted file mode 100644 index e12f57a..0000000 --- a/commons-rng-core/src/userguide/java/org/apache/commons/rng/userguide/RandomStressTester.java +++ /dev/null @@ -1,280 +0,0 @@ -/* - * Licensed to the Apache Software Foundation (ASF) under one or more - * contributor license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright ownership. - * The ASF licenses this file to You under the Apache License, Version 2.0 - * (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ -package org.apache.commons.rng.userguide; - -import java.util.List; -import java.util.ArrayList; -import java.util.Arrays; -import java.io.IOException; -import java.io.File; -import java.io.PrintWriter; -import java.io.FileWriter; -import java.io.DataOutputStream; -import java.util.concurrent.ExecutionException; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; - -import org.apache.commons.rng.UniformRandomProvider; - -/** - * Class that can be used for testing a generator by piping the values - * returned by its {@link UniformRandomProvider#nextInt()} method to a - * program that reads {@code int} values from its standard input and - * writes an analysis report to standard output. - * - * <p> - * The <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> - * "dieharder"</a> test suite is such a software. - * <br> - * Example of command line, assuming that "examples.jar" specifies this - * class as the "main" class (see {@link #main(String[]) main} method): - * <pre><code> - * $ java -jar examples.jar \ - * report/dh_ \ - * 4 \ - * org.apache.commons.rng.userguide.GeneratorsList \ - * /usr/bin/dieharder -a -g 200 -Y 1 -k 2 - * </code></pre> - * </p> - */ -public class RandomStressTester { - /** Comment prefix. */ - private static final String C = "# "; - /** New line. */ - private static final String N = "\n"; - /** Command line. */ - private final List<String> cmdLine; - /** Output prefix. */ - private final String fileOutputPrefix; - - /** - * Creates the application. - * - * @param cmd Command line. - * @param outputPrefix Output prefix for file reports. - */ - private RandomStressTester(List<String> cmd, - String outputPrefix) { - final File exec = new File(cmd.get(0)); - if (!exec.exists() || - !exec.canExecute()) { - throw new RuntimeException("Program is not executable: " + exec); - } - - cmdLine = new ArrayList<String>(cmd); - fileOutputPrefix = outputPrefix; - - final File reportDir = new File(fileOutputPrefix).getParentFile(); - if (!reportDir.exists() || - !reportDir.isDirectory() || - !reportDir.canWrite()) { - throw new RuntimeException("Invalid output directory: " + reportDir); - } - } - - /** - * Program's entry point. - * - * @param args Application's arguments. - * The order is as follows: - * <ul> - * <li>Output prefix: Filename prefix where the output of the analysis will - * written to. The appended suffix is the index of the instance within the - * list of generators to be tested.</li> - * <li>Number of threads to use concurrently: One thread will process one of - * the generators to be tested.</li> - * <li>Name of a class that implements {@code Iterable<UniformRandomProvider>} - * (and defines a default constructor): Each generator of the list will be - * tested by one instance of the analyzer program</li> - * <li>Path to the executable: this is the analyzer software that reads 32-bits - * integers from stdin.</li> - * <li>All remaining arguments are passed to the executable.</li> - * </ul> - */ - public static void main(String[] args) throws Exception { - final String output = args[0]; - final int numThreads = Integer.valueOf(args[1]); - - final Iterable<UniformRandomProvider> rngList = createGeneratorsList(args[2]); - - final List<String> cmdLine = new ArrayList<>(); - cmdLine.addAll(Arrays.asList(Arrays.copyOfRange(args, 3, args.length))); - - final RandomStressTester app = new RandomStressTester(cmdLine, output); - app.run(rngList, numThreads); - } - - /** - * Creates the tasks and starts the processes. - * - * @param generators List of generators to be analyzed. - * @param numConcurrentTasks Number of concurrent tasks. - * Twice as many threads will be started: one thread for the RNG and one - * for the analyzer. - */ - private void run(Iterable<UniformRandomProvider> generators, - int numConcurrentTasks) - throws IOException { - // Parallel execution. - final ExecutorService service = Executors.newFixedThreadPool(numConcurrentTasks); - - // Placeholder (output will be "null"). - final List<Future<?>> execOutput = new ArrayList<Future<?>>(); - - // Run tasks. - int count = 0; - for (UniformRandomProvider rng : generators) { - final File output = new File(fileOutputPrefix + (++count)); - final Runnable r = new Task(rng, output); - execOutput.add(service.submit(r)); - } - - // Wait for completion (ignoring return value). - try { - for (Future<?> f : execOutput) { - try { - f.get(); - } catch (ExecutionException e) { - System.err.println(e.getCause().getMessage()); - } - } - } catch (InterruptedException ignored) {} - - // Terminate all threads. - service.shutdown(); - } - - /** - * Creates the list of generators to be tested. - * - * @param name Name of the class that contains the generators to be - * analyzed. - * @return the list of generators. - */ - private static Iterable<UniformRandomProvider> createGeneratorsList(String name) - throws ClassNotFoundException, - InstantiationException, - IllegalAccessException { - return (Iterable<UniformRandomProvider>) Class.forName(name).newInstance(); - } - - /** - * Pipes random numbers to the standard input of an analyzer. - */ - private class Task implements Runnable { - /** Directory for reports of the tester processes. */ - private final File output; - /** RNG to be tested. */ - private final UniformRandomProvider rng; - - /** - * Creates the task. - * - * @param random RNG to be tested. - * @param report Report file. - */ - public Task(UniformRandomProvider random, - File report) { - rng = random; - output = report; - } - - /** {@inheritDoc} */ - @Override - public void run() { - try { - // Write header. - printHeader(output, rng); - - // Start test suite. - final ProcessBuilder builder = new ProcessBuilder(cmdLine); - builder.redirectOutput(ProcessBuilder.Redirect.appendTo(output)); - final Process testingProcess = builder.start(); - final DataOutputStream sink = new DataOutputStream(testingProcess.getOutputStream()); - - final long startTime = System.nanoTime(); - - try { - while (true) { - sink.writeInt(rng.nextInt()); - } - } catch (IOException e) { - // Hopefully getting here when the analyzing software terminates. - } - - final long endTime = System.nanoTime(); - - // Write footer. - printFooter(output, endTime - startTime); - - } catch (IOException e) { - throw new RuntimeException("Failed to start task: " + e.getMessage()); - } - } - } - - /** - * @param output File. - * @param rng Generator being tested. - * @param cmdLine - */ - private void printHeader(File output, - UniformRandomProvider rng) - throws IOException { - final StringBuilder sb = new StringBuilder(); - sb.append(C).append(N); - sb.append(C).append("RNG: ").append(rng.toString()).append(N); - sb.append(C).append(N); - sb.append(C).append("Java: ").append(System.getProperty("java.version")).append(N); - sb.append(C).append("Runtime: ").append(System.getProperty("java.runtime.version", "?")).append(N); - sb.append(C).append("JVM: ").append(System.getProperty("java.vm.name")) - .append(" ").append(System.getProperty("java.vm.version")).append(N); - sb.append(C).append("OS: ").append(System.getProperty("os.name")) - .append(" ").append(System.getProperty("os.version")) - .append(" ").append(System.getProperty("os.arch")).append(N); - sb.append(C).append(N); - - sb.append(C).append("Analyzer: "); - for (String s : cmdLine) { - sb.append(s).append(" "); - } - sb.append(N); - sb.append(C).append(N); - - final PrintWriter w = new PrintWriter(new FileWriter(output, true)); - w.print(sb.toString()); - w.close(); - } - - /** - * @param output File. - * @param nanoTime Duration of the run. - */ - private void printFooter(File output, - long nanoTime) - throws IOException { - final PrintWriter w = new PrintWriter(new FileWriter(output, true)); - w.println(C); - - final double duration = ((double) nanoTime) * 1e-9 / 60; - w.println(C + "Test duration: " + duration + " minutes"); - - w.println(C); - w.close(); - } -} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-examples/pom.xml ---------------------------------------------------------------------- diff --git a/commons-rng-examples/pom.xml b/commons-rng-examples/pom.xml new file mode 100644 index 0000000..d97c9bc --- /dev/null +++ b/commons-rng-examples/pom.xml @@ -0,0 +1,43 @@ +<?xml version="1.0"?> +<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" + xmlns="http://maven.apache.org/POM/4.0.0" + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> + <modelVersion>4.0.0</modelVersion> + + <parent> + <groupId>org.apache.commons</groupId> + <artifactId>commons-rng</artifactId> + <version>1.0-SNAPSHOT</version> + </parent> + + <groupId>org.apache.commons</groupId> + <artifactId>commons-rng-examples</artifactId> + <version>1.0-SNAPSHOT</version> + <name>Apache Commons RNG Examples</name> + <url>http://maven.apache.org</url> + + <inceptionYear>2016</inceptionYear> + <description>The Apache Commons RNG Examples module contains examples + of usage the random numbers generator implementations available + through the "commons-rng-simple" module.</description> + + <properties> + <maven.compiler.source>1.7</maven.compiler.source> + <maven.compiler.target>1.7</maven.compiler.target> + </properties> + + <dependencies> + <dependency> + <groupId>org.apache.commons</groupId> + <artifactId>commons-rng-simple</artifactId> + <version>1.0-SNAPSHOT</version> + </dependency> + </dependencies> + + <scm> + <connection>scm:git:http://git-wip-us.apache.org/repos/asf/commons-rng.git</connection> + <developerConnection>scm:git:https://git-wip-us.apache.org/repos/asf/commons-rng.git</developerConnection> + <url>https://git-wip-us.apache.org/repos/asf?p=commons-rng.git</url> + </scm> + +</project> http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-examples/src/main/c/stdin2testu01.c ---------------------------------------------------------------------- diff --git a/commons-rng-examples/src/main/c/stdin2testu01.c b/commons-rng-examples/src/main/c/stdin2testu01.c new file mode 100644 index 0000000..d1a4a6a --- /dev/null +++ b/commons-rng-examples/src/main/c/stdin2testu01.c @@ -0,0 +1,127 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +/* + * Utility for simple interfacing with the "TestU01" library: + * http://simul.iro.umontreal.ca/testu01/tu01.html + * + * It reads from its standard input an infinite sequence of 32-bits + * integers and runs one of the test suites "SmallCrush", "Crush" or + * "BigCrush". + * "TestU01" writes its report to standard output. + */ + +#include <stdint.h> +#include <unistd.h> +#include <string.h> + +#include <testu01/unif01.h> +#include <testu01/bbattery.h> +#include <testu01/util.h> + +#define TU_S "SmallCrush" +#define TU_C "Crush" +#define TU_B "BigCrush" +#define BUFFER_LENGTH 256 + +typedef struct { + unsigned long buffer[BUFFER_LENGTH]; + uint32_t index; +} StdinReader_state; + +unsigned long nextInt(void *par, + void *sta) { + StdinReader_state *state = (StdinReader_state *) sta; + if (state->index >= BUFFER_LENGTH) { + /* Refill. */ + fread(state->buffer, sizeof(unsigned long), BUFFER_LENGTH, stdin); + state->index = 0; + } + + uint32_t random = state->buffer[state->index]; + ++state->index; /* Next request. */ + + return random; +} + +double nextDouble(void *par, + void *sta) { + return nextInt(par, sta) / 4294967296.0; +} + + +static void dummy(void *sta) { + printf("N/A"); + + return; +} + +unif01_Gen *createStdinReader(void) { + unif01_Gen *gen; + StdinReader_state *state; + size_t len; + char name[60]; + + state = util_Malloc(sizeof(StdinReader_state)); + + gen = util_Malloc(sizeof(unif01_Gen)); + gen->state = state; + gen->param = NULL; + gen->Write = dummy; + gen->GetU01 = nextDouble; + gen->GetBits = nextInt; + + strcpy(name, "stdin"); + len = strlen(name); + gen->name = util_Calloc(len + 1, sizeof (char)); + strncpy(gen->name, name, len); + + // Read binary input. + freopen(NULL, "rb", stdin); + state->index = BUFFER_LENGTH; + + return gen; +} + +void deleteStdinReader(unif01_Gen *gen) { + gen->state = util_Free(gen->state); + gen->name = util_Free(gen->name); + util_Free(gen); +} + +int main(int argc, + char **argv) { + unif01_Gen *gen = createStdinReader(); + char *spec = argv[1]; + + if (argc < 2) { + printf("[ERROR] Specify test suite: '%s', '%s' or '%s'\n", TU_S, TU_C, TU_B); + exit(1); + } else if (strcmp(spec, TU_S) == 0) { + bbattery_SmallCrush(gen); + } else if (strcmp(spec, TU_C) == 0) { + bbattery_Crush(gen); + } else if (strcmp(spec, TU_B) == 0) { + bbattery_BigCrush(gen); + } else { + printf("[ERROR] Unknown specification: '%s'\n", spec); + exit(1); + } + + deleteStdinReader(gen); + return 0; +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/ComputePi.java ---------------------------------------------------------------------- diff --git a/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/ComputePi.java b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/ComputePi.java new file mode 100644 index 0000000..72b4cb1 --- /dev/null +++ b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/ComputePi.java @@ -0,0 +1,87 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.rng.examples.integration; + +import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; + +/** + * Computation of \( \pi \) using Monte-Carlo integration. + * + * The computation estimates the value by computing the probability that + * a point \( p = (x, y) \) will lie in the circle of radius \( r = 1 \) + * inscribed in the square of side \( r = 1 \). + * The probability could be computed by \[ area_{circle} / area_{square} \], + * where \( area_{circle} = \pi * r^2 \) and \( area_{square} = 4 r^2 \). + * Hence, the probability is \( \frac{\pi}{4} \). + * + * The Monte Carlo simulation will produce \( N \) points. + * Defining \( N_c \) as the number of point that satisfy \( x^2 + y^2 <= 1 \), + * we will have \( \frac{N_c}{N} \approx \frac{\pi}{4} \). + */ +public class ComputePi extends MonteCarloIntegration { + /** Domain dimension. */ + private static final int DIMENSION = 2; + + /** + * @param source RNG algorithm. + */ + public ComputePi(RandomSource source) { + super(source, DIMENSION); + } + + /** + * Arguments: + * <ul> + * <li> + * Number of random 2-dimensional points to generate. + * </li> + * <li> + * {@link RandomSource Random source identifier}. + * </li> + * </ul> + */ + public static void main(String[] args) { + if (args.length != 2) { + throw new IllegalStateException("Missing arguments"); + } + + final long numPoints = Long.valueOf(args[0]); + final RandomSource randomSource = RandomSource.valueOf(args[1]); + + final ComputePi piApp = new ComputePi(randomSource); + final double piMC = piApp.compute(numPoints); + + System.out.println("After generating " + (DIMENSION * numPoints) + + " random numbers, the error on ð is " + Math.abs(piMC - Math.PI)); + } + + /** + * @param n Number of random points to generate. + * @return the approximate value of pi. + */ + public double compute(long numPoints) { + return 4 * integrate(numPoints); + } + + /** {@inheritDoc} */ + @Override + protected boolean isInside(double ... rand) { + final double r2 = rand[0] * rand[0] + rand[1] * rand[1]; + return r2 <= 1; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/MonteCarloIntegration.java ---------------------------------------------------------------------- diff --git a/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/MonteCarloIntegration.java b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/MonteCarloIntegration.java new file mode 100644 index 0000000..5e313b3 --- /dev/null +++ b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/integration/MonteCarloIntegration.java @@ -0,0 +1,90 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.commons.rng.examples.integration; + +import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; + +/** + * <a href="https://en.wikipedia.org/wiki/Monte_Carlo_integration">Monte-Carlo method</a> + * for approximating an integral on a n-dimensional unit cube. + */ +public abstract class MonteCarloIntegration { + /** RNG. */ + private final UniformRandomProvider rng; + /** Integration domain dimension. */ + private final int dimension; + + /** + * Simulation constructor. + * + * @param source RNG algorithm. + * @param dimension Integration domain dimension. + */ + public MonteCarloIntegration(RandomSource source, + int dimension) { + this.rng = RandomSource.create(source); + this.dimension = dimension; + } + + /** + * Run the Monte-Carlo integration. + * + * @param n Number of random points to generate. + * @return the integral. + */ + public double integrate(long n) { + double result = 0; + long inside = 0; + long total = 0; + while (total < n) { + if (isInside(generateU01())) { + ++inside; + } + + ++total; + result = inside / (double) total; + } + + return result; + } + + /** + * Indicates whether the given points is inside the region whose + * integral is computed. + * + * @param point Point whose coordinates are random numbers uniformly + * distributed in the unit interval. + * @return {@code true} if the {@code point} is inside. + */ + protected abstract boolean isInside(double ... point); + + /** + * @return a value from a random sequence uniformly distributed + * in the {@code [0, 1)} interval. + */ + private double[] generateU01() { + final double[] rand = new double[dimension]; + + for (int i = 0; i < dimension; i++) { + rand[i] = rng.nextDouble(); + } + + return rand; + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/GeneratorsList.java ---------------------------------------------------------------------- diff --git a/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/GeneratorsList.java b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/GeneratorsList.java new file mode 100644 index 0000000..037f60b --- /dev/null +++ b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/GeneratorsList.java @@ -0,0 +1,59 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.rng.examples.stress; + +import java.util.List; +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.commons.rng.UniformRandomProvider; +import org.apache.commons.rng.simple.RandomSource; + +/** + * List of generators. + */ +public class GeneratorsList implements Iterable<UniformRandomProvider> { + /** List. */ + private final List<UniformRandomProvider> list = new ArrayList<UniformRandomProvider>(); + + /** + * Creates list. + */ + public GeneratorsList() { + list.add(RandomSource.create(RandomSource.JDK)); + list.add(RandomSource.create(RandomSource.MT)); + list.add(RandomSource.create(RandomSource.WELL_512_A)); + list.add(RandomSource.create(RandomSource.WELL_1024_A)); + list.add(RandomSource.create(RandomSource.WELL_19937_A)); + list.add(RandomSource.create(RandomSource.WELL_19937_C)); + list.add(RandomSource.create(RandomSource.WELL_44497_A)); + list.add(RandomSource.create(RandomSource.WELL_44497_B)); + list.add(RandomSource.create(RandomSource.ISAAC)); + list.add(RandomSource.create(RandomSource.MT_64)); + list.add(RandomSource.create(RandomSource.SPLIT_MIX_64)); + list.add(RandomSource.create(RandomSource.XOR_SHIFT_1024_S)); + list.add(RandomSource.create(RandomSource.TWO_CMRES)); + list.add(RandomSource.create(RandomSource.MWC_256)); + list.add(RandomSource.create(RandomSource.KISS)); + } + + /** {@inheritDoc} */ + @Override + public Iterator<UniformRandomProvider> iterator() { + return list.iterator(); + } +} http://git-wip-us.apache.org/repos/asf/commons-rng/blob/651c21da/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java ---------------------------------------------------------------------- diff --git a/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java new file mode 100644 index 0000000..d55a82c --- /dev/null +++ b/commons-rng-examples/src/main/java/org/apache/commons/rng/examples/stress/RandomStressTester.java @@ -0,0 +1,280 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.commons.rng.examples.stress; + +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.io.IOException; +import java.io.File; +import java.io.PrintWriter; +import java.io.FileWriter; +import java.io.DataOutputStream; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +import org.apache.commons.rng.UniformRandomProvider; + +/** + * Class that can be used for testing a generator by piping the values + * returned by its {@link UniformRandomProvider#nextInt()} method to a + * program that reads {@code int} values from its standard input and + * writes an analysis report to standard output. + * + * <p> + * The <a href="http://www.phy.duke.edu/~rgb/General/dieharder.php"> + * "dieharder"</a> test suite is such a software. + * <br> + * Example of command line, assuming that "examples.jar" specifies this + * class as the "main" class (see {@link #main(String[]) main} method): + * <pre><code> + * $ java -jar examples.jar \ + * report/dh_ \ + * 4 \ + * org.apache.commons.rng.userguide.GeneratorsList \ + * /usr/bin/dieharder -a -g 200 -Y 1 -k 2 + * </code></pre> + * </p> + */ +public class RandomStressTester { + /** Comment prefix. */ + private static final String C = "# "; + /** New line. */ + private static final String N = "\n"; + /** Command line. */ + private final List<String> cmdLine; + /** Output prefix. */ + private final String fileOutputPrefix; + + /** + * Creates the application. + * + * @param cmd Command line. + * @param outputPrefix Output prefix for file reports. + */ + private RandomStressTester(List<String> cmd, + String outputPrefix) { + final File exec = new File(cmd.get(0)); + if (!exec.exists() || + !exec.canExecute()) { + throw new RuntimeException("Program is not executable: " + exec); + } + + cmdLine = new ArrayList<String>(cmd); + fileOutputPrefix = outputPrefix; + + final File reportDir = new File(fileOutputPrefix).getParentFile(); + if (!reportDir.exists() || + !reportDir.isDirectory() || + !reportDir.canWrite()) { + throw new RuntimeException("Invalid output directory: " + reportDir); + } + } + + /** + * Program's entry point. + * + * @param args Application's arguments. + * The order is as follows: + * <ul> + * <li>Output prefix: Filename prefix where the output of the analysis will + * written to. The appended suffix is the index of the instance within the + * list of generators to be tested.</li> + * <li>Number of threads to use concurrently: One thread will process one of + * the generators to be tested.</li> + * <li>Name of a class that implements {@code Iterable<UniformRandomProvider>} + * (and defines a default constructor): Each generator of the list will be + * tested by one instance of the analyzer program</li> + * <li>Path to the executable: this is the analyzer software that reads 32-bits + * integers from stdin.</li> + * <li>All remaining arguments are passed to the executable.</li> + * </ul> + */ + public static void main(String[] args) throws Exception { + final String output = args[0]; + final int numThreads = Integer.valueOf(args[1]); + + final Iterable<UniformRandomProvider> rngList = createGeneratorsList(args[2]); + + final List<String> cmdLine = new ArrayList<String>(); + cmdLine.addAll(Arrays.asList(Arrays.copyOfRange(args, 3, args.length))); + + final RandomStressTester app = new RandomStressTester(cmdLine, output); + app.run(rngList, numThreads); + } + + /** + * Creates the tasks and starts the processes. + * + * @param generators List of generators to be analyzed. + * @param numConcurrentTasks Number of concurrent tasks. + * Twice as many threads will be started: one thread for the RNG and one + * for the analyzer. + */ + private void run(Iterable<UniformRandomProvider> generators, + int numConcurrentTasks) + throws IOException { + // Parallel execution. + final ExecutorService service = Executors.newFixedThreadPool(numConcurrentTasks); + + // Placeholder (output will be "null"). + final List<Future<?>> execOutput = new ArrayList<Future<?>>(); + + // Run tasks. + int count = 0; + for (UniformRandomProvider rng : generators) { + final File output = new File(fileOutputPrefix + (++count)); + final Runnable r = new Task(rng, output); + execOutput.add(service.submit(r)); + } + + // Wait for completion (ignoring return value). + try { + for (Future<?> f : execOutput) { + try { + f.get(); + } catch (ExecutionException e) { + System.err.println(e.getCause().getMessage()); + } + } + } catch (InterruptedException ignored) {} + + // Terminate all threads. + service.shutdown(); + } + + /** + * Creates the list of generators to be tested. + * + * @param name Name of the class that contains the generators to be + * analyzed. + * @return the list of generators. + */ + private static Iterable<UniformRandomProvider> createGeneratorsList(String name) + throws ClassNotFoundException, + InstantiationException, + IllegalAccessException { + return (Iterable<UniformRandomProvider>) Class.forName(name).newInstance(); + } + + /** + * Pipes random numbers to the standard input of an analyzer. + */ + private class Task implements Runnable { + /** Directory for reports of the tester processes. */ + private final File output; + /** RNG to be tested. */ + private final UniformRandomProvider rng; + + /** + * Creates the task. + * + * @param random RNG to be tested. + * @param report Report file. + */ + public Task(UniformRandomProvider random, + File report) { + rng = random; + output = report; + } + + /** {@inheritDoc} */ + @Override + public void run() { + try { + // Write header. + printHeader(output, rng); + + // Start test suite. + final ProcessBuilder builder = new ProcessBuilder(cmdLine); + builder.redirectOutput(ProcessBuilder.Redirect.appendTo(output)); + final Process testingProcess = builder.start(); + final DataOutputStream sink = new DataOutputStream(testingProcess.getOutputStream()); + + final long startTime = System.nanoTime(); + + try { + while (true) { + sink.writeInt(rng.nextInt()); + } + } catch (IOException e) { + // Hopefully getting here when the analyzing software terminates. + } + + final long endTime = System.nanoTime(); + + // Write footer. + printFooter(output, endTime - startTime); + + } catch (IOException e) { + throw new RuntimeException("Failed to start task: " + e.getMessage()); + } + } + } + + /** + * @param output File. + * @param rng Generator being tested. + * @param cmdLine + */ + private void printHeader(File output, + UniformRandomProvider rng) + throws IOException { + final StringBuilder sb = new StringBuilder(); + sb.append(C).append(N); + sb.append(C).append("RNG: ").append(rng.toString()).append(N); + sb.append(C).append(N); + sb.append(C).append("Java: ").append(System.getProperty("java.version")).append(N); + sb.append(C).append("Runtime: ").append(System.getProperty("java.runtime.version", "?")).append(N); + sb.append(C).append("JVM: ").append(System.getProperty("java.vm.name")) + .append(" ").append(System.getProperty("java.vm.version")).append(N); + sb.append(C).append("OS: ").append(System.getProperty("os.name")) + .append(" ").append(System.getProperty("os.version")) + .append(" ").append(System.getProperty("os.arch")).append(N); + sb.append(C).append(N); + + sb.append(C).append("Analyzer: "); + for (String s : cmdLine) { + sb.append(s).append(" "); + } + sb.append(N); + sb.append(C).append(N); + + final PrintWriter w = new PrintWriter(new FileWriter(output, true)); + w.print(sb.toString()); + w.close(); + } + + /** + * @param output File. + * @param nanoTime Duration of the run. + */ + private void printFooter(File output, + long nanoTime) + throws IOException { + final PrintWriter w = new PrintWriter(new FileWriter(output, true)); + w.println(C); + + final double duration = ((double) nanoTime) * 1e-9 / 60; + w.println(C + "Test duration: " + duration + " minutes"); + + w.println(C); + w.close(); + } +}