Author: psteitz
Date: Wed Aug 31 23:49:50 2011
New Revision: 1163872
URL: http://svn.apache.org/viewvc?rev=1163872&view=rev
Log:
Enabled reseeding of the random generators used by EmpiricalDistributionImpl
and ValueServer. Modified ValueServer to pass its RandomData instance to
the EmpiricalDistributionImpl that it creates when used in DIGEST_MODE, so
reseeding ValueServer works as expected. Changed EmpiricalDistributionImpl
constructor to take a RandomDataImpl instead of just RandomData (so the
instance member could be reseeded.)
JIRA: MATH-654
Reported by David James
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/ValueServer.java
commons/proper/math/trunk/src/site/xdoc/changes.xml
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/EmpiricalDistributionTest.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/ValueServerTest.java
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java?rev=1163872&r1=1163871&r2=1163872&view=diff
==============================================================================
---
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
(original)
+++
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/EmpiricalDistributionImpl.java
Wed Aug 31 23:49:50 2011
@@ -64,6 +64,9 @@ import org.apache.commons.math.util.Math
*/
public class EmpiricalDistributionImpl implements Serializable,
EmpiricalDistribution {
+ /** Default bin count */
+ public static final int DEFAULT_BIN_COUNT = 1000;
+
/** Serializable version identifier */
private static final long serialVersionUID = 5729073523949762654L;
@@ -91,14 +94,14 @@ public class EmpiricalDistributionImpl i
/** upper bounds of subintervals in (0,1) "belonging" to the bins */
private double[] upperBounds = null;
- /** RandomData instance to use in repeated calls to getNext() */
+ /** RandomDataImpl instance to use in repeated calls to getNext() */
private final RandomDataImpl randomData;
/**
* Creates a new EmpiricalDistribution with the default bin count.
*/
public EmpiricalDistributionImpl() {
- this(1000, null);
+ this(DEFAULT_BIN_COUNT, new RandomDataImpl());
}
/**
@@ -107,7 +110,7 @@ public class EmpiricalDistributionImpl i
* @param binCount number of bins
*/
public EmpiricalDistributionImpl(int binCount) {
- this(binCount, null);
+ this(binCount, new RandomDataImpl());
}
/**
@@ -124,6 +127,42 @@ public class EmpiricalDistributionImpl i
binStats = new ArrayList<SummaryStatistics>();
}
+ /**
+ * Creates a new EmpiricalDistribution with default bin count using the
+ * provided {@link RandomGenerator} as the source of random data.
+ *
+ * @param generator random data generator (may be null, resulting in
default JDK generator)
+ * @since 3.0
+ */
+ public EmpiricalDistributionImpl(RandomGenerator generator) {
+ this(DEFAULT_BIN_COUNT, generator);
+ }
+
+ /**
+ * Creates a new EmpiricalDistribution with the specified bin count using
the
+ * provided {@link RandomDataImpl} instance as the source of random data.
+ *
+ * @param binCount number of bins
+ * @param randomData random data generator (may be null, resulting in
default JDK generator)
+ * @since 3.0
+ */
+ public EmpiricalDistributionImpl(int binCount, RandomDataImpl randomData) {
+ this.binCount = binCount;
+ this.randomData = randomData;
+ binStats = new ArrayList<SummaryStatistics>();
+ }
+
+ /**
+ * Creates a new EmpiricalDistribution with default bin count using the
+ * provided {@link RandomDataImpl} as the source of random data.
+ *
+ * @param randomData random data generator (may be null, resulting in
default JDK generator)
+ * @since 3.0
+ */
+ public EmpiricalDistributionImpl(RandomDataImpl randomData) {
+ this(DEFAULT_BIN_COUNT, randomData);
+ }
+
/**
* Computes the empirical distribution from the provided
* array of numbers.
Modified:
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/ValueServer.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/ValueServer.java?rev=1163872&r1=1163871&r2=1163872&view=diff
==============================================================================
---
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/ValueServer.java
(original)
+++
commons/proper/math/trunk/src/main/java/org/apache/commons/math/random/ValueServer.java
Wed Aug 31 23:49:50 2011
@@ -85,7 +85,7 @@ public class ValueServer {
private BufferedReader filePointer = null;
/** RandomDataImpl to use for random data generation. */
- private final RandomData randomData;
+ private final RandomDataImpl randomData;
// Data generation modes ======================================
@@ -95,13 +95,13 @@ public class ValueServer {
}
/**
- * Construct a ValueServer instance using a RandomData as its source
+ * Construct a ValueServer instance using a RandomDataImpl as its source
* of random data.
*
- * @param randomData the RandomData instance used to source random data
- * @since 1.1
+ * @param randomData the RandomDataImpl instance used to source random data
+ * @since 3.0
*/
- public ValueServer(RandomData randomData) {
+ public ValueServer(RandomDataImpl randomData) {
this.randomData = randomData;
}
@@ -170,8 +170,7 @@ public class ValueServer {
* @throws IOException if an I/O error occurs reading the input file
*/
public void computeDistribution() throws IOException {
- empiricalDistribution = new EmpiricalDistributionImpl();
- empiricalDistribution.load(valuesFileURL);
+ computeDistribution(EmpiricalDistributionImpl.DEFAULT_BIN_COUNT);
}
/**
@@ -190,7 +189,7 @@ public class ValueServer {
*/
public void computeDistribution(int binCount)
throws IOException {
- empiricalDistribution = new EmpiricalDistributionImpl(binCount);
+ empiricalDistribution = new EmpiricalDistributionImpl(binCount,
randomData);
empiricalDistribution.load(valuesFileURL);
mu = empiricalDistribution.getSampleStats().getMean();
sigma = empiricalDistribution.getSampleStats().getStandardDeviation();
@@ -299,6 +298,16 @@ public class ValueServer {
this.sigma = sigma;
}
+ /**
+ * Reseeds the random data generator.
+ *
+ * @param seed Value with which to reseed the {@link RandomDataImpl}
+ * used to generate random data.
+ */
+ public void reSeed(long seed) {
+ randomData.reSeed(seed);
+ }
+
//------------- private methods ---------------------------------
/**
Modified: commons/proper/math/trunk/src/site/xdoc/changes.xml
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/site/xdoc/changes.xml?rev=1163872&r1=1163871&r2=1163872&view=diff
==============================================================================
--- commons/proper/math/trunk/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/trunk/src/site/xdoc/changes.xml Wed Aug 31 23:49:50 2011
@@ -52,6 +52,12 @@ The <action> type attribute can be add,u
If the output is not quite correct, check for invisible trailing spaces!
-->
<release version="3.0" date="TBD" description="TBD">
+ <action dev="psteitz" type="fix" issue="MATH-654">
+ Enabled reseeding of the random generators used by
EmpiricalDistributionImpl
+ and ValueServer. Modified ValueServer to pass its RandomData instance
to
+ the EmpiricalDistributionImpl that it creates when used in
DIGEST_MODE, so
+ reseeding ValueServer works as expected.
+ </action>
<action dev="erans" type="fix" issue="MATH-653">
Renamed "AbstractRealVector" to "RealVector". The interface was
removed
in favour of its unique (abstract) implementation.
Modified:
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/EmpiricalDistributionTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/EmpiricalDistributionTest.java?rev=1163872&r1=1163871&r2=1163872&view=diff
==============================================================================
---
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/EmpiricalDistributionTest.java
(original)
+++
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/EmpiricalDistributionTest.java
Wed Aug 31 23:49:50 2011
@@ -224,7 +224,7 @@ public final class EmpiricalDistribution
}
// Verify no NPE with null generator argument
- dist = new EmpiricalDistributionImpl(5, null);
+ dist = new EmpiricalDistributionImpl(5, (RandomGenerator) null);
dist.load(testData);
dist.getNextValue();
}
Modified:
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/ValueServerTest.java
URL:
http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/ValueServerTest.java?rev=1163872&r1=1163871&r2=1163872&view=diff
==============================================================================
---
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/ValueServerTest.java
(original)
+++
commons/proper/math/trunk/src/test/java/org/apache/commons/math/random/ValueServerTest.java
Wed Aug 31 23:49:50 2011
@@ -18,6 +18,7 @@ package org.apache.commons.math.random;
import java.io.EOFException;
import java.net.URL;
+import java.util.Arrays;
import org.apache.commons.math.RetryRunner;
import org.apache.commons.math.stat.descriptive.SummaryStatistics;
@@ -50,7 +51,7 @@ public final class ValueServerTest {
* these tests will fail even if the code is working as designed.
*/
@Test
- public void testNextDigest() throws Exception{
+ public void testNextDigest() throws Exception {
double next = 0.0;
double tolerance = 0.1;
vs.computeDistribution();
@@ -74,7 +75,40 @@ public final class ValueServerTest {
Assert.assertEquals("mean", 5.069831575018909, stats.getMean(),
tolerance);
Assert.assertEquals("std dev", 1.0173699343977738,
stats.getStandardDeviation(),
tolerance);
-
+ }
+
+ /**
+ * Verify that when provided with fixed seeds, stochastic modes
+ * generate fixed sequences. Verifies the fix for MATH-654.
+ */
+ @Test
+ public void testFixedSeed() throws Exception {
+ ValueServer valueServer = new ValueServer();
+ URL url = getClass().getResource("testData.txt");
+ valueServer.setValuesFileURL(url);
+ valueServer.computeDistribution();
+ checkFixedSeed(valueServer, ValueServer.DIGEST_MODE);
+ checkFixedSeed(valueServer, ValueServer.EXPONENTIAL_MODE);
+ checkFixedSeed(valueServer, ValueServer.GAUSSIAN_MODE);
+ checkFixedSeed(valueServer, ValueServer.UNIFORM_MODE);
+ }
+
+ /**
+ * Do the check for {@link #testFixedSeed()}
+ * @param mode ValueServer mode
+ */
+ private void checkFixedSeed(ValueServer valueServer, int mode) throws
Exception {
+ valueServer.reSeed(1000);
+ valueServer.setMode(mode);
+ double[][] values = new double[2][100];
+ for (int i = 0; i < 100; i++) {
+ values[0][i] = valueServer.getNext();
+ }
+ valueServer.reSeed(1000);
+ for (int i = 0; i < 100; i++) {
+ values[1][i] = valueServer.getNext();
+ }
+ Assert.assertTrue(Arrays.equals(values[0], values[1]));
}
/**