diff --git a/src/main/java/org/apache/commons/math4/distribution/AbstractIntegerDistribution.java b/src/main/java/org/apache/commons/math4/distribution/AbstractIntegerDistribution.java
index 95d6f074c..4612b58b0 100644
--- a/src/main/java/org/apache/commons/math4/distribution/AbstractIntegerDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/AbstractIntegerDistribution.java
@@ -19,11 +19,10 @@ package org.apache.commons.math4.distribution;
import java.io.Serializable;
import org.apache.commons.math4.exception.MathInternalError;
-import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.OutOfRangeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
+import org.apache.commons.math4.rng.UniformRandomProvider;
import org.apache.commons.math4.util.FastMath;
/**
@@ -33,23 +32,8 @@ import org.apache.commons.math4.util.FastMath;
*
*/
public abstract class AbstractIntegerDistribution implements IntegerDistribution, Serializable {
-
/** Serializable version identifier */
- private static final long serialVersionUID = -1146319659338487221L;
-
- /**
- * RNG instance used to generate samples from the distribution.
- * @since 3.1
- */
- protected final RandomGenerator random;
-
- /**
- * @param rng Random number generator.
- * @since 3.1
- */
- protected AbstractIntegerDistribution(RandomGenerator rng) {
- random = rng;
- }
+ private static final long serialVersionUID = 20160318L;
/**
* {@inheritDoc}
@@ -159,43 +143,6 @@ public abstract class AbstractIntegerDistribution implements IntegerDistribution
return upper;
}
- /** {@inheritDoc} */
- @Override
- public void reseedRandomGenerator(long seed) {
- random.setSeed(seed);
- }
-
- /**
- * {@inheritDoc}
- *
- * The default implementation uses the
- *
- * inversion method.
- */
- @Override
- public int sample() {
- return inverseCumulativeProbability(random.nextDouble());
- }
-
- /**
- * {@inheritDoc}
- *
- * The default implementation generates the sample by calling
- * {@link #sample()} in a loop.
- */
- @Override
- public int[] sample(int sampleSize) {
- if (sampleSize <= 0) {
- throw new NotStrictlyPositiveException(
- LocalizedFormats.NUMBER_OF_SAMPLES, sampleSize);
- }
- int[] out = new int[sampleSize];
- for (int i = 0; i < sampleSize; i++) {
- out[i] = sample();
- }
- return out;
- }
-
/**
* Computes the cumulative probability function and checks for {@code NaN}
* values returned. Throws {@code MathInternalError} if the value is
@@ -227,4 +174,33 @@ public abstract class AbstractIntegerDistribution implements IntegerDistribution
public double logProbability(int x) {
return FastMath.log(probability(x));
}
+
+ /**
+ * Utility function for allocating an array and filling it with {@code n}
+ * samples generated by the given {@code sampler}.
+ *
+ * @param n Number of samples.
+ * @param sampler Sampler.
+ * @return an array of size {@code n}.
+ */
+ public static int[] sample(int n,
+ IntegerDistribution.Sampler sampler) {
+ final int[] samples = new int[n];
+ for (int i = 0; i < n; i++) {
+ samples[i] = sampler.sample();
+ }
+ return samples;
+ }
+
+ /**{@inheritDoc} */
+ @Override
+ public IntegerDistribution.Sampler createSampler(final UniformRandomProvider rng) {
+ return new IntegerDistribution.Sampler() {
+ /** {@inheritDoc} */
+ @Override
+ public int sample() {
+ return inverseCumulativeProbability(rng.nextDouble());
+ }
+ };
+ }
}
diff --git a/src/main/java/org/apache/commons/math4/distribution/BinomialDistribution.java b/src/main/java/org/apache/commons/math4/distribution/BinomialDistribution.java
index a9e94c664..ffcc1b982 100644
--- a/src/main/java/org/apache/commons/math4/distribution/BinomialDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/BinomialDistribution.java
@@ -19,8 +19,6 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.NotPositiveException;
import org.apache.commons.math4.exception.OutOfRangeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
import org.apache.commons.math4.special.Beta;
import org.apache.commons.math4.util.FastMath;
@@ -38,41 +36,16 @@ public class BinomialDistribution extends AbstractIntegerDistribution {
/** The probability of success. */
private final double probabilityOfSuccess;
- /**
- * Create a binomial distribution with the given number of trials and
- * probability of success.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
- *
- * @param trials Number of trials.
- * @param p Probability of success.
- * @throws NotPositiveException if {@code trials < 0}.
- * @throws OutOfRangeException if {@code p < 0} or {@code p > 1}.
- */
- public BinomialDistribution(int trials, double p) {
- this(new Well19937c(), trials, p);
- }
-
/**
* Creates a binomial distribution.
*
- * @param rng Random number generator.
* @param trials Number of trials.
* @param p Probability of success.
* @throws NotPositiveException if {@code trials < 0}.
* @throws OutOfRangeException if {@code p < 0} or {@code p > 1}.
- * @since 3.1
*/
- public BinomialDistribution(RandomGenerator rng,
- int trials,
+ public BinomialDistribution(int trials,
double p) {
- super(rng);
-
if (trials < 0) {
throw new NotPositiveException(LocalizedFormats.NUMBER_OF_TRIALS,
trials);
diff --git a/src/main/java/org/apache/commons/math4/distribution/EnumeratedDistribution.java b/src/main/java/org/apache/commons/math4/distribution/EnumeratedDistribution.java
index 3f9acc8a7..88ce03782 100644
--- a/src/main/java/org/apache/commons/math4/distribution/EnumeratedDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/EnumeratedDistribution.java
@@ -29,7 +29,6 @@ import org.apache.commons.math4.exception.NotPositiveException;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NullArgumentException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
import org.apache.commons.math4.rng.UniformRandomProvider;
import org.apache.commons.math4.util.MathArrays;
import org.apache.commons.math4.util.Pair;
@@ -52,69 +51,23 @@ import org.apache.commons.math4.util.Pair;
* @since 3.2
*/
public class EnumeratedDistribution implements Serializable {
-
/** Serializable UID. */
- private static final long serialVersionUID = 20123308L;
-
- /**
- * RNG instance used to generate samples from the distribution.
- */
- @Deprecated
- protected RandomGenerator random = null;
-
+ private static final long serialVersionUID = 20160319L;
/**
* List of random variable values.
*/
private final List singletons;
-
/**
* Probabilities of respective random variable values. For i = 0, ..., singletons.size() - 1,
* probability[i] is the probability that a random variable following this distribution takes
* the value singletons[i].
*/
private final double[] probabilities;
-
/**
* Cumulative probabilities, cached to speed up sampling.
*/
private final double[] cumulativeProbabilities;
- /**
- * XXX TODO: remove once "EnumeratedIntegerDistribution" has been changed.
- */
- @Deprecated
- public EnumeratedDistribution(final RandomGenerator rng, final List> pmf)
- throws NotPositiveException, MathArithmeticException, NotFiniteNumberException, NotANumberException {
- random = rng;
- singletons = new ArrayList(pmf.size());
- final double[] probs = new double[pmf.size()];
-
- for (int i = 0; i < pmf.size(); i++) {
- final Pair sample = pmf.get(i);
- singletons.add(sample.getKey());
- final double p = sample.getValue();
- if (p < 0) {
- throw new NotPositiveException(sample.getValue());
- }
- if (Double.isInfinite(p)) {
- throw new NotFiniteNumberException(p);
- }
- if (Double.isNaN(p)) {
- throw new NotANumberException();
- }
- probs[i] = p;
- }
-
- probabilities = MathArrays.normalizeArray(probs, 1.0);
-
- cumulativeProbabilities = new double[probabilities.length];
- double sum = 0;
- for (int i = 0; i < probabilities.length; i++) {
- sum += probabilities[i];
- cumulativeProbabilities[i] = sum;
- }
- }
-
/**
* Create an enumerated distribution using the given random number generator
* and probability mass function enumeration.
@@ -160,16 +113,6 @@ public class EnumeratedDistribution implements Serializable {
}
}
- /**
- * Reseed the random generator used to generate samples.
- *
- * @param seed the new seed
- */
- @Deprecated
- public void reseedRandomGenerator(long seed) {
- random.setSeed(seed);
- }
-
/**
* For a random variable {@code X} whose values are distributed according to
* this distribution, this method returns {@code P(X = x)}. In other words,
@@ -215,97 +158,6 @@ public class EnumeratedDistribution implements Serializable {
return samples;
}
- /**
- * Generate a random value sampled from this distribution.
- *
- * @return a random value.
- */
- @Deprecated
- public T sample() {
- final double randomValue = random.nextDouble();
-
- int index = Arrays.binarySearch(cumulativeProbabilities, randomValue);
- if (index < 0) {
- index = -index-1;
- }
-
- if (index >= 0 &&
- index < probabilities.length &&
- randomValue < cumulativeProbabilities[index]) {
- return singletons.get(index);
- }
-
- /* This should never happen, but it ensures we will return a correct
- * object in case there is some floating point inequality problem
- * wrt the cumulative probabilities. */
- return singletons.get(singletons.size() - 1);
- }
-
- /**
- * Generate a random sample from the distribution.
- *
- * @param sampleSize the number of random values to generate.
- * @return an array representing the random sample.
- * @throws NotStrictlyPositiveException if {@code sampleSize} is not
- * positive.
- */
- @Deprecated
- public Object[] sample(int sampleSize) throws NotStrictlyPositiveException {
- if (sampleSize <= 0) {
- throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_SAMPLES,
- sampleSize);
- }
-
- final Object[] out = new Object[sampleSize];
-
- for (int i = 0; i < sampleSize; i++) {
- out[i] = sample();
- }
-
- return out;
-
- }
-
- /**
- * Generate a random sample from the distribution.
- *
- * If the requested samples fit in the specified array, it is returned
- * therein. Otherwise, a new array is allocated with the runtime type of
- * the specified array and the size of this collection.
- *
- * @param sampleSize the number of random values to generate.
- * @param array the array to populate.
- * @return an array representing the random sample.
- * @throws NotStrictlyPositiveException if {@code sampleSize} is not positive.
- * @throws NullArgumentException if {@code array} is null
- */
- @Deprecated
- public T[] sample(int sampleSize, final T[] array) throws NotStrictlyPositiveException {
- if (sampleSize <= 0) {
- throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_SAMPLES, sampleSize);
- }
-
- if (array == null) {
- throw new NullArgumentException(LocalizedFormats.INPUT_ARRAY);
- }
-
- T[] out;
- if (array.length < sampleSize) {
- @SuppressWarnings("unchecked") // safe as both are of type T
- final T[] unchecked = (T[]) Array.newInstance(array.getClass().getComponentType(), sampleSize);
- out = unchecked;
- } else {
- out = array;
- }
-
- for (int i = 0; i < sampleSize; i++) {
- out[i] = sample();
- }
-
- return out;
-
- }
-
/**
* Creates a {@link Sampler}.
*
diff --git a/src/main/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistribution.java b/src/main/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistribution.java
index af641406f..e8f3ed636 100644
--- a/src/main/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistribution.java
@@ -27,8 +27,7 @@ import org.apache.commons.math4.exception.MathArithmeticException;
import org.apache.commons.math4.exception.NotANumberException;
import org.apache.commons.math4.exception.NotFiniteNumberException;
import org.apache.commons.math4.exception.NotPositiveException;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
+import org.apache.commons.math4.rng.UniformRandomProvider;
import org.apache.commons.math4.util.Pair;
/**
@@ -42,10 +41,8 @@ import org.apache.commons.math4.util.Pair;
* @since 3.2
*/
public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
-
/** Serializable UID. */
private static final long serialVersionUID = 20130308L;
-
/**
* {@link EnumeratedDistribution} instance (using the {@link Integer} wrapper)
* used to generate the pmf.
@@ -53,15 +50,7 @@ public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
protected final EnumeratedDistribution innerDistribution;
/**
- * Create a discrete distribution using the given probability mass function
- * definition.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
+ * Create a discrete distribution.
*
* @param singletons array of random variable values.
* @param probabilities array of probabilities.
@@ -72,45 +61,24 @@ public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
* @throws NotANumberException if any of the probabilities are NaN.
* @throws MathArithmeticException all of the probabilities are 0.
*/
- public EnumeratedIntegerDistribution(final int[] singletons, final double[] probabilities)
- throws DimensionMismatchException, NotPositiveException, MathArithmeticException,
- NotFiniteNumberException, NotANumberException{
- this(new Well19937c(), singletons, probabilities);
+ public EnumeratedIntegerDistribution(final int[] singletons,
+ final double[] probabilities)
+ throws DimensionMismatchException,
+ NotPositiveException,
+ MathArithmeticException,
+ NotFiniteNumberException,
+ NotANumberException {
+ innerDistribution = new EnumeratedDistribution(createDistribution(singletons,
+ probabilities));
}
/**
- * Create a discrete distribution using the given random number generator
- * and probability mass function definition.
+ * Create a discrete integer-valued distribution from the input data.
+ * Values are assigned mass based on their frequency.
*
- * @param rng random number generator.
- * @param singletons array of random variable values.
- * @param probabilities array of probabilities.
- * @throws DimensionMismatchException if
- * {@code singletons.length != probabilities.length}
- * @throws NotPositiveException if any of the probabilities are negative.
- * @throws NotFiniteNumberException if any of the probabilities are infinite.
- * @throws NotANumberException if any of the probabilities are NaN.
- * @throws MathArithmeticException all of the probabilities are 0.
- */
- public EnumeratedIntegerDistribution(final RandomGenerator rng,
- final int[] singletons, final double[] probabilities)
- throws DimensionMismatchException, NotPositiveException, MathArithmeticException,
- NotFiniteNumberException, NotANumberException {
- super(rng);
- innerDistribution = new EnumeratedDistribution(
- rng, createDistribution(singletons, probabilities));
- }
-
- /**
- * Create a discrete integer-valued distribution from the input data. Values are assigned
- * mass based on their frequency.
- *
- * @param rng random number generator used for sampling
* @param data input dataset
- * #since 3.6
*/
- public EnumeratedIntegerDistribution(final RandomGenerator rng, final int[] data) {
- super(rng);
+ public EnumeratedIntegerDistribution(final int[] data) {
final Map dataMap = new HashMap();
for (int value : data) {
Integer count = dataMap.get(value);
@@ -129,19 +97,7 @@ public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
probabilities[index] = entry.getValue().intValue() / denom;
index++;
}
- innerDistribution = new EnumeratedDistribution(rng, createDistribution(values, probabilities));
- }
-
- /**
- * Create a discrete integer-valued distribution from the input data. Values are assigned
- * mass based on their frequency. For example, [0,1,1,2] as input creates a distribution
- * with values 0, 1 and 2 having probability masses 0.25, 0.5 and 0.25 respectively,
- *
- * @param data input dataset
- * @since 3.6
- */
- public EnumeratedIntegerDistribution(final int[] data) {
- this(new Well19937c(), data);
+ innerDistribution = new EnumeratedDistribution(createDistribution(values, probabilities));
}
/**
@@ -162,7 +118,6 @@ public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
samples.add(new Pair(singletons[i], probabilities[i]));
}
return samples;
-
}
/**
@@ -273,11 +228,19 @@ public class EnumeratedIntegerDistribution extends AbstractIntegerDistribution {
return true;
}
- /**
- * {@inheritDoc}
- */
+ /** {@inheritDoc} */
@Override
- public int sample() {
- return innerDistribution.sample();
+ public IntegerDistribution.Sampler createSampler(final UniformRandomProvider rng) {
+ return new IntegerDistribution.Sampler() {
+ /** Delegate. */
+ private final EnumeratedDistribution.Sampler inner =
+ innerDistribution.createSampler(rng);
+
+ /** {@inheritDoc} */
+ @Override
+ public int sample() {
+ return inner.sample();
+ }
+ };
}
}
diff --git a/src/main/java/org/apache/commons/math4/distribution/GeometricDistribution.java b/src/main/java/org/apache/commons/math4/distribution/GeometricDistribution.java
index 55456cc3d..4c3795338 100644
--- a/src/main/java/org/apache/commons/math4/distribution/GeometricDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/GeometricDistribution.java
@@ -18,8 +18,6 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.OutOfRangeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
import org.apache.commons.math4.util.FastMath;
/**
@@ -32,7 +30,7 @@ import org.apache.commons.math4.util.FastMath;
public class GeometricDistribution extends AbstractIntegerDistribution {
/** Serializable version identifier. */
- private static final long serialVersionUID = 20130507L;
+ private static final long serialVersionUID = 20160318L;
/** The probability of success. */
private final double probabilityOfSuccess;
/** {@code log(p)} where p is the probability of success. */
@@ -40,33 +38,13 @@ public class GeometricDistribution extends AbstractIntegerDistribution {
/** {@code log(1 - p)} where p is the probability of success. */
private final double log1mProbabilityOfSuccess;
- /**
- * Create a geometric distribution with the given probability of success.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
- *
- * @param p probability of success.
- * @throws OutOfRangeException if {@code p <= 0} or {@code p > 1}.
- */
- public GeometricDistribution(double p) {
- this(new Well19937c(), p);
- }
-
/**
* Creates a geometric distribution.
*
- * @param rng Random number generator.
* @param p Probability of success.
* @throws OutOfRangeException if {@code p <= 0} or {@code p > 1}.
*/
- public GeometricDistribution(RandomGenerator rng, double p) {
- super(rng);
-
+ public GeometricDistribution(double p) {
if (p <= 0 || p > 1) {
throw new OutOfRangeException(LocalizedFormats.OUT_OF_RANGE_LEFT, p, 0, 1);
}
diff --git a/src/main/java/org/apache/commons/math4/distribution/HypergeometricDistribution.java b/src/main/java/org/apache/commons/math4/distribution/HypergeometricDistribution.java
index cf385f8a7..137738df6 100644
--- a/src/main/java/org/apache/commons/math4/distribution/HypergeometricDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/HypergeometricDistribution.java
@@ -21,8 +21,6 @@ import org.apache.commons.math4.exception.NotPositiveException;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
import org.apache.commons.math4.util.FastMath;
/**
@@ -33,7 +31,7 @@ import org.apache.commons.math4.util.FastMath;
*/
public class HypergeometricDistribution extends AbstractIntegerDistribution {
/** Serializable version identifier. */
- private static final long serialVersionUID = -436928820673516179L;
+ private static final long serialVersionUID = 20160318L;
/** The number of successes in the population. */
private final int numberOfSuccesses;
/** The population size. */
@@ -45,34 +43,9 @@ public class HypergeometricDistribution extends AbstractIntegerDistribution {
/** Whether or not the numerical variance has been calculated */
private boolean numericalVarianceIsCalculated = false;
- /**
- * Construct a new hypergeometric distribution with the specified population
- * size, number of successes in the population, and sample size.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
- *
- * @param populationSize Population size.
- * @param numberOfSuccesses Number of successes in the population.
- * @param sampleSize Sample size.
- * @throws NotPositiveException if {@code numberOfSuccesses < 0}.
- * @throws NotStrictlyPositiveException if {@code populationSize <= 0}.
- * @throws NumberIsTooLargeException if {@code numberOfSuccesses > populationSize},
- * or {@code sampleSize > populationSize}.
- */
- public HypergeometricDistribution(int populationSize, int numberOfSuccesses, int sampleSize)
- throws NotPositiveException, NotStrictlyPositiveException, NumberIsTooLargeException {
- this(new Well19937c(), populationSize, numberOfSuccesses, sampleSize);
- }
-
/**
* Creates a new hypergeometric distribution.
*
- * @param rng Random number generator.
* @param populationSize Population size.
* @param numberOfSuccesses Number of successes in the population.
* @param sampleSize Sample size.
@@ -80,15 +53,13 @@ public class HypergeometricDistribution extends AbstractIntegerDistribution {
* @throws NotStrictlyPositiveException if {@code populationSize <= 0}.
* @throws NumberIsTooLargeException if {@code numberOfSuccesses > populationSize},
* or {@code sampleSize > populationSize}.
- * @since 3.1
*/
- public HypergeometricDistribution(RandomGenerator rng,
- int populationSize,
+ public HypergeometricDistribution(int populationSize,
int numberOfSuccesses,
int sampleSize)
- throws NotPositiveException, NotStrictlyPositiveException, NumberIsTooLargeException {
- super(rng);
-
+ throws NotPositiveException,
+ NotStrictlyPositiveException,
+ NumberIsTooLargeException {
if (populationSize <= 0) {
throw new NotStrictlyPositiveException(LocalizedFormats.POPULATION_SIZE,
populationSize);
diff --git a/src/main/java/org/apache/commons/math4/distribution/IntegerDistribution.java b/src/main/java/org/apache/commons/math4/distribution/IntegerDistribution.java
index 2a3e90552..aed97aba2 100644
--- a/src/main/java/org/apache/commons/math4/distribution/IntegerDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/IntegerDistribution.java
@@ -18,6 +18,7 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.OutOfRangeException;
+import org.apache.commons.math4.rng.UniformRandomProvider;
/**
* Interface for distributions on the integers.
@@ -145,29 +146,23 @@ public interface IntegerDistribution {
boolean isSupportConnected();
/**
- * Reseed the random generator used to generate samples.
+ * Creates a sampler.
*
- * @param seed the new seed
- * @since 3.0
+ * @param rng Generator of uniformly distributed numbers.
+ * @return a sampler that produces random numbers according this
+ * distribution.
*/
- void reseedRandomGenerator(long seed);
+ Sampler createSampler(UniformRandomProvider rng);
/**
- * Generate a random value sampled from this distribution.
- *
- * @return a random value
- * @since 3.0
+ * Sampling functionality.
*/
- int sample();
-
- /**
- * Generate a random sample from the distribution.
- *
- * @param sampleSize the number of random values to generate
- * @return an array representing the random sample
- * @throws org.apache.commons.math4.exception.NotStrictlyPositiveException
- * if {@code sampleSize} is not positive
- * @since 3.0
- */
- int[] sample(int sampleSize);
+ interface Sampler {
+ /**
+ * Generates a random value sampled from this distribution.
+ *
+ * @return a random value.
+ */
+ int sample();
+ }
}
diff --git a/src/main/java/org/apache/commons/math4/distribution/PascalDistribution.java b/src/main/java/org/apache/commons/math4/distribution/PascalDistribution.java
index f11d0bfd6..b8f246443 100644
--- a/src/main/java/org/apache/commons/math4/distribution/PascalDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/PascalDistribution.java
@@ -19,8 +19,6 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.OutOfRangeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
import org.apache.commons.math4.special.Beta;
import org.apache.commons.math4.util.CombinatoricsUtils;
import org.apache.commons.math4.util.FastMath;
@@ -77,13 +75,6 @@ public class PascalDistribution extends AbstractIntegerDistribution {
/**
* Create a Pascal distribution with the given number of successes and
* probability of success.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
*
* @param r Number of successes.
* @param p Probability of success.
@@ -91,29 +82,10 @@ public class PascalDistribution extends AbstractIntegerDistribution {
* @throws OutOfRangeException if the probability of success is not in the
* range {@code [0, 1]}.
*/
- public PascalDistribution(int r, double p)
- throws NotStrictlyPositiveException, OutOfRangeException {
- this(new Well19937c(), r, p);
- }
-
- /**
- * Create a Pascal distribution with the given number of successes and
- * probability of success.
- *
- * @param rng Random number generator.
- * @param r Number of successes.
- * @param p Probability of success.
- * @throws NotStrictlyPositiveException if the number of successes is not positive
- * @throws OutOfRangeException if the probability of success is not in the
- * range {@code [0, 1]}.
- * @since 3.1
- */
- public PascalDistribution(RandomGenerator rng,
- int r,
+ public PascalDistribution(int r,
double p)
- throws NotStrictlyPositiveException, OutOfRangeException {
- super(rng);
-
+ throws NotStrictlyPositiveException,
+ OutOfRangeException {
if (r <= 0) {
throw new NotStrictlyPositiveException(LocalizedFormats.NUMBER_OF_SUCCESSES,
r);
diff --git a/src/main/java/org/apache/commons/math4/distribution/PoissonDistribution.java b/src/main/java/org/apache/commons/math4/distribution/PoissonDistribution.java
index 6cb0129c0..49a08dae3 100644
--- a/src/main/java/org/apache/commons/math4/distribution/PoissonDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/PoissonDistribution.java
@@ -18,13 +18,11 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
import org.apache.commons.math4.special.Gamma;
import org.apache.commons.math4.util.CombinatoricsUtils;
import org.apache.commons.math4.util.FastMath;
import org.apache.commons.math4.util.MathUtils;
-import org.apache.commons.math4.rng.RandomSource;
+import org.apache.commons.math4.rng.UniformRandomProvider;
/**
* Implementation of the Poisson distribution.
@@ -47,8 +45,6 @@ public class PoissonDistribution extends AbstractIntegerDistribution {
private static final long serialVersionUID = -3349935121172596109L;
/** Distribution used to compute normal approximation. */
private final NormalDistribution normal;
- /** Distribution needed for the {@link #sample()} method. */
- private final RealDistribution.Sampler exponentialSampler;
/** Mean of the distribution. */
private final double mean;
@@ -66,31 +62,18 @@ public class PoissonDistribution extends AbstractIntegerDistribution {
/**
* Creates a new Poisson distribution with specified mean.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
*
* @param p the Poisson mean
* @throws NotStrictlyPositiveException if {@code p <= 0}.
*/
- public PoissonDistribution(double p) throws NotStrictlyPositiveException {
+ public PoissonDistribution(double p)
+ throws NotStrictlyPositiveException {
this(p, DEFAULT_EPSILON, DEFAULT_MAX_ITERATIONS);
}
/**
* Creates a new Poisson distribution with specified mean, convergence
* criterion and maximum number of iterations.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
*
* @param p Poisson mean.
* @param epsilon Convergence criterion for cumulative probabilities.
@@ -99,30 +82,10 @@ public class PoissonDistribution extends AbstractIntegerDistribution {
* @throws NotStrictlyPositiveException if {@code p <= 0}.
* @since 2.1
*/
- public PoissonDistribution(double p, double epsilon, int maxIterations)
- throws NotStrictlyPositiveException {
- this(new Well19937c(), p, epsilon, maxIterations);
- }
-
- /**
- * Creates a new Poisson distribution with specified mean, convergence
- * criterion and maximum number of iterations.
- *
- * @param rng Random number generator.
- * @param p Poisson mean.
- * @param epsilon Convergence criterion for cumulative probabilities.
- * @param maxIterations the maximum number of iterations for cumulative
- * probabilities.
- * @throws NotStrictlyPositiveException if {@code p <= 0}.
- * @since 3.1
- */
- public PoissonDistribution(RandomGenerator rng,
- double p,
+ public PoissonDistribution(double p,
double epsilon,
int maxIterations)
- throws NotStrictlyPositiveException {
- super(rng);
-
+ throws NotStrictlyPositiveException {
if (p <= 0) {
throw new NotStrictlyPositiveException(LocalizedFormats.MEAN, p);
}
@@ -130,12 +93,8 @@ public class PoissonDistribution extends AbstractIntegerDistribution {
this.epsilon = epsilon;
this.maxIterations = maxIterations;
- // Use the same RNG instance as the parent class.
normal = new NormalDistribution(p, FastMath.sqrt(p),
NormalDistribution.DEFAULT_INVERSE_ABSOLUTE_ACCURACY);
-
- // XXX TODO: RNG source should not be hard-coded.
- exponentialSampler = new ExponentialDistribution(1).createSampler(RandomSource.create(RandomSource.WELL_19937_C));
}
/**
@@ -148,7 +107,7 @@ public class PoissonDistribution extends AbstractIntegerDistribution {
* @since 2.1
*/
public PoissonDistribution(double p, double epsilon)
- throws NotStrictlyPositiveException {
+ throws NotStrictlyPositiveException {
this(p, epsilon, DEFAULT_MAX_ITERATIONS);
}
@@ -285,120 +244,113 @@ public class PoissonDistribution extends AbstractIntegerDistribution {
return true;
}
- /**
- * {@inheritDoc}
- *
- * Algorithm Description:
- *
- * - For small means, uses simulation of a Poisson process
- * using Uniform deviates, as described
- * here.
- * The Poisson process (and hence value returned) is bounded by 1000 * mean.
- *
- * - For large means, uses the rejection algorithm described in
- *
- * Devroye, Luc. (1981).The Computer Generation of Poisson Random Variables
- * Computing vol. 26 pp. 197-207.
- *
- *
- *
- *
- *
- * @return a random value.
- * @since 2.2
- */
+ /**{@inheritDoc} */
@Override
- public int sample() {
- return (int) FastMath.min(nextPoisson(mean), Integer.MAX_VALUE);
- }
+ public IntegerDistribution.Sampler createSampler(final UniformRandomProvider rng) {
+ return new IntegerDistribution.Sampler() {
+ /** Exponential distribution. */
+ private final RealDistribution.Sampler exponentialSampler
+ = new ExponentialDistribution(1).createSampler(rng);
+ /** Gaussian distribution. */
+ private final RealDistribution.Sampler gaussianSampler
+ = new NormalDistribution().createSampler(rng);
- /**
- * @param meanPoisson Mean of the Poisson distribution.
- * @return the next sample.
- */
- private long nextPoisson(double meanPoisson) {
- final double pivot = 40.0d;
- if (meanPoisson < pivot) {
- double p = FastMath.exp(-meanPoisson);
- long n = 0;
- double r = 1.0d;
- double rnd = 1.0d;
+ /** {@inheritDoc} */
+ @Override
+ public int sample() {
+ return (int) FastMath.min(nextPoisson(mean),
+ Integer.MAX_VALUE);
+ }
- while (n < 1000 * meanPoisson) {
- rnd = random.nextDouble();
- r *= rnd;
- if (r >= p) {
- n++;
- } else {
+ /**
+ * @param meanPoisson Mean of the Poisson distribution.
+ * @return the next sample.
+ */
+ private long nextPoisson(double meanPoisson) {
+ final double pivot = 40.0d;
+ if (meanPoisson < pivot) {
+ double p = FastMath.exp(-meanPoisson);
+ long n = 0;
+ double r = 1.0d;
+ double rnd = 1.0d;
+
+ while (n < 1000 * meanPoisson) {
+ rnd = rng.nextDouble();
+ r *= rnd;
+ if (r >= p) {
+ n++;
+ } else {
+ return n;
+ }
+ }
return n;
- }
- }
- return n;
- } else {
- final double lambda = FastMath.floor(meanPoisson);
- final double lambdaFractional = meanPoisson - lambda;
- final double logLambda = FastMath.log(lambda);
- final double logLambdaFactorial = CombinatoricsUtils.factorialLog((int) lambda);
- final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional);
- final double delta = FastMath.sqrt(lambda * FastMath.log(32 * lambda / FastMath.PI + 1));
- final double halfDelta = delta / 2;
- final double twolpd = 2 * lambda + delta;
- final double a1 = FastMath.sqrt(FastMath.PI * twolpd) * FastMath.exp(1 / (8 * lambda));
- final double a2 = (twolpd / delta) * FastMath.exp(-delta * (1 + delta) / twolpd);
- final double aSum = a1 + a2 + 1;
- final double p1 = a1 / aSum;
- final double p2 = a2 / aSum;
- final double c1 = 1 / (8 * lambda);
-
- double x = 0;
- double y = 0;
- double v = 0;
- int a = 0;
- double t = 0;
- double qr = 0;
- double qa = 0;
- for (;;) {
- final double u = random.nextDouble();
- if (u <= p1) {
- final double n = random.nextGaussian();
- x = n * FastMath.sqrt(lambda + halfDelta) - 0.5d;
- if (x > delta || x < -lambda) {
- continue;
- }
- y = x < 0 ? FastMath.floor(x) : FastMath.ceil(x);
- final double e = exponentialSampler.sample();
- v = -e - (n * n / 2) + c1;
} else {
- if (u > p1 + p2) {
- y = lambda;
- break;
- } else {
- x = delta + (twolpd / delta) * exponentialSampler.sample();
- y = FastMath.ceil(x);
- v = -exponentialSampler.sample() - delta * (x + 1) / twolpd;
+ final double lambda = FastMath.floor(meanPoisson);
+ final double lambdaFractional = meanPoisson - lambda;
+ final double logLambda = FastMath.log(lambda);
+ final double logLambdaFactorial = CombinatoricsUtils.factorialLog((int) lambda);
+ final long y2 = lambdaFractional < Double.MIN_VALUE ? 0 : nextPoisson(lambdaFractional);
+ final double delta = FastMath.sqrt(lambda * FastMath.log(32 * lambda / FastMath.PI + 1));
+ final double halfDelta = delta / 2;
+ final double twolpd = 2 * lambda + delta;
+ final double a1 = FastMath.sqrt(FastMath.PI * twolpd) * FastMath.exp(1 / (8 * lambda));
+ final double a2 = (twolpd / delta) * FastMath.exp(-delta * (1 + delta) / twolpd);
+ final double aSum = a1 + a2 + 1;
+ final double p1 = a1 / aSum;
+ final double p2 = a2 / aSum;
+ final double c1 = 1 / (8 * lambda);
+
+ double x = 0;
+ double y = 0;
+ double v = 0;
+ int a = 0;
+ double t = 0;
+ double qr = 0;
+ double qa = 0;
+ while (true) {
+ final double u = rng.nextDouble();
+ if (u <= p1) {
+ final double n = gaussianSampler.sample();
+ x = n * FastMath.sqrt(lambda + halfDelta) - 0.5d;
+ if (x > delta || x < -lambda) {
+ continue;
+ }
+ y = x < 0 ? FastMath.floor(x) : FastMath.ceil(x);
+ final double e = exponentialSampler.sample();
+ v = -e - (n * n / 2) + c1;
+ } else {
+ if (u > p1 + p2) {
+ y = lambda;
+ break;
+ } else {
+ x = delta + (twolpd / delta) * exponentialSampler.sample();
+ y = FastMath.ceil(x);
+ v = -exponentialSampler.sample() - delta * (x + 1) / twolpd;
+ }
+ }
+ a = x < 0 ? 1 : 0;
+ t = y * (y + 1) / (2 * lambda);
+ if (v < -t && a == 0) {
+ y = lambda + y;
+ break;
+ }
+ qr = t * ((2 * y + 1) / (6 * lambda) - 1);
+ qa = qr - (t * t) / (3 * (lambda + a * (y + 1)));
+ if (v < qa) {
+ y = lambda + y;
+ break;
+ }
+ if (v > qr) {
+ continue;
+ }
+ if (v < y * logLambda - CombinatoricsUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) {
+ y = lambda + y;
+ break;
+ }
}
- }
- a = x < 0 ? 1 : 0;
- t = y * (y + 1) / (2 * lambda);
- if (v < -t && a == 0) {
- y = lambda + y;
- break;
- }
- qr = t * ((2 * y + 1) / (6 * lambda) - 1);
- qa = qr - (t * t) / (3 * (lambda + a * (y + 1)));
- if (v < qa) {
- y = lambda + y;
- break;
- }
- if (v > qr) {
- continue;
- }
- if (v < y * logLambda - CombinatoricsUtils.factorialLog((int) (y + lambda)) + logLambdaFactorial) {
- y = lambda + y;
- break;
+ return y2 + (long) y;
}
}
- return y2 + (long) y;
- }
+ };
}
}
diff --git a/src/main/java/org/apache/commons/math4/distribution/UniformIntegerDistribution.java b/src/main/java/org/apache/commons/math4/distribution/UniformIntegerDistribution.java
index 6cd21b0fa..d1489d30f 100644
--- a/src/main/java/org/apache/commons/math4/distribution/UniformIntegerDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/UniformIntegerDistribution.java
@@ -19,8 +19,7 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
+import org.apache.commons.math4.rng.UniformRandomProvider;
/**
* Implementation of the uniform integer distribution.
@@ -32,7 +31,7 @@ import org.apache.commons.math4.random.Well19937c;
*/
public class UniformIntegerDistribution extends AbstractIntegerDistribution {
/** Serializable version identifier. */
- private static final long serialVersionUID = 20120109L;
+ private static final long serialVersionUID = 20160308L;
/** Lower bound (inclusive) of this distribution. */
private final int lower;
/** Upper bound (inclusive) of this distribution. */
@@ -41,39 +40,14 @@ public class UniformIntegerDistribution extends AbstractIntegerDistribution {
/**
* Creates a new uniform integer distribution using the given lower and
* upper bounds (both inclusive).
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
*
* @param lower Lower bound (inclusive) of this distribution.
* @param upper Upper bound (inclusive) of this distribution.
- * @throws NumberIsTooLargeException if {@code lower >= upper}.
- */
- public UniformIntegerDistribution(int lower, int upper)
- throws NumberIsTooLargeException {
- this(new Well19937c(), lower, upper);
- }
-
- /**
- * Creates a new uniform integer distribution using the given lower and
- * upper bounds (both inclusive).
- *
- * @param rng Random number generator.
- * @param lower Lower bound (inclusive) of this distribution.
- * @param upper Upper bound (inclusive) of this distribution.
* @throws NumberIsTooLargeException if {@code lower > upper}.
- * @since 3.1
*/
- public UniformIntegerDistribution(RandomGenerator rng,
- int lower,
+ public UniformIntegerDistribution(int lower,
int upper)
throws NumberIsTooLargeException {
- super(rng);
-
if (lower > upper) {
throw new NumberIsTooLargeException(
LocalizedFormats.LOWER_BOUND_NOT_BELOW_UPPER_BOUND,
@@ -165,24 +139,30 @@ public class UniformIntegerDistribution extends AbstractIntegerDistribution {
return true;
}
- /** {@inheritDoc} */
+ /**{@inheritDoc} */
@Override
- public int sample() {
- final int max = (upper - lower) + 1;
- if (max <= 0) {
- // The range is too wide to fit in a positive int (larger
- // than 2^31); as it covers more than half the integer range,
- // we use a simple rejection method.
- while (true) {
- final int r = random.nextInt();
- if (r >= lower &&
- r <= upper) {
- return r;
+ public IntegerDistribution.Sampler createSampler(final UniformRandomProvider rng) {
+ return new IntegerDistribution.Sampler() {
+ /** {@inheritDoc} */
+ @Override
+ public int sample() {
+ final int max = (upper - lower) + 1;
+ if (max <= 0) {
+ // The range is too wide to fit in a positive int (larger
+ // than 2^31); as it covers more than half the integer range,
+ // we use a simple rejection method.
+ while (true) {
+ final int r = rng.nextInt();
+ if (r >= lower &&
+ r <= upper) {
+ return r;
+ }
+ }
+ } else {
+ // We can shift the range and directly generate a positive int.
+ return lower + rng.nextInt(max);
}
}
- } else {
- // We can shift the range and directly generate a positive int.
- return lower + random.nextInt(max);
- }
+ };
}
}
diff --git a/src/main/java/org/apache/commons/math4/distribution/ZipfDistribution.java b/src/main/java/org/apache/commons/math4/distribution/ZipfDistribution.java
index 80da61d02..82e9fb3bf 100644
--- a/src/main/java/org/apache/commons/math4/distribution/ZipfDistribution.java
+++ b/src/main/java/org/apache/commons/math4/distribution/ZipfDistribution.java
@@ -19,8 +19,7 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
+import org.apache.commons.math4.rng.UniformRandomProvider;
import org.apache.commons.math4.util.FastMath;
/**
@@ -59,45 +58,18 @@ public class ZipfDistribution extends AbstractIntegerDistribution {
private double numericalVariance = Double.NaN;
/** Whether or not the numerical variance has been calculated */
private boolean numericalVarianceIsCalculated = false;
- /** The sampler to be used for the sample() method */
- private transient ZipfRejectionInversionSampler sampler;
/**
- * Create a new Zipf distribution with the given number of elements and
- * exponent.
- *
- * Note: this constructor will implicitly create an instance of
- * {@link Well19937c} as random generator to be used for sampling only (see
- * {@link #sample()} and {@link #sample(int)}). In case no sampling is
- * needed for the created distribution, it is advised to pass {@code null}
- * as random generator via the appropriate constructors to avoid the
- * additional initialisation overhead.
+ * Creates a distribution.
*
* @param numberOfElements Number of elements.
* @param exponent Exponent.
* @exception NotStrictlyPositiveException if {@code numberOfElements <= 0}
* or {@code exponent <= 0}.
*/
- public ZipfDistribution(final int numberOfElements, final double exponent) {
- this(new Well19937c(), numberOfElements, exponent);
- }
-
- /**
- * Creates a Zipf distribution.
- *
- * @param rng Random number generator.
- * @param numberOfElements Number of elements.
- * @param exponent Exponent.
- * @exception NotStrictlyPositiveException if {@code numberOfElements <= 0}
- * or {@code exponent <= 0}.
- * @since 3.1
- */
- public ZipfDistribution(RandomGenerator rng,
- int numberOfElements,
+ public ZipfDistribution(int numberOfElements,
double exponent)
throws NotStrictlyPositiveException {
- super(rng);
-
if (numberOfElements <= 0) {
throw new NotStrictlyPositiveException(LocalizedFormats.DIMENSION,
numberOfElements);
@@ -285,13 +257,20 @@ public class ZipfDistribution extends AbstractIntegerDistribution {
return true;
}
- /** {@inheritDoc} */
+ /**{@inheritDoc} */
@Override
- public int sample() {
- if (sampler == null) {
- sampler = new ZipfRejectionInversionSampler(numberOfElements, exponent);
- }
- return sampler.sample(random);
+ public IntegerDistribution.Sampler createSampler(final UniformRandomProvider rng) {
+ return new IntegerDistribution.Sampler() {
+ /** Helper. */
+ private final ZipfRejectionInversionSampler sampler =
+ new ZipfRejectionInversionSampler(numberOfElements, exponent);
+
+ /** {@inheritDoc} */
+ @Override
+ public int sample() {
+ return sampler.sample(rng);
+ }
+ };
}
/**
@@ -318,8 +297,7 @@ public class ZipfDistribution extends AbstractIntegerDistribution {
*
* @since 3.6
*/
- static final class ZipfRejectionInversionSampler {
-
+ static class ZipfRejectionInversionSampler {
/** Exponent parameter of the distribution. */
private final double exponent;
/** Number of elements. */
@@ -331,7 +309,7 @@ public class ZipfDistribution extends AbstractIntegerDistribution {
/** Constant equal to {@code 2 - hIntegralInverse(hIntegral(2.5) - h(2)}. */
private final double s;
- /** Simple constructor.
+ /**
* @param numberOfElements number of elements
* @param exponent exponent parameter of the distribution
*/
@@ -343,18 +321,18 @@ public class ZipfDistribution extends AbstractIntegerDistribution {
this.s = 2d - hIntegralInverse(hIntegral(2.5) - h(2));
}
- /** Generate one integral number in the range [1, numberOfElements].
+ /**
+ * Generates one integer in the range [1, numberOfElements].
+ *
* @param random random generator to use
* @return generated integral number in the range [1, numberOfElements]
*/
- int sample(final RandomGenerator random) {
+ int sample(final UniformRandomProvider random) {
while(true) {
-
final double u = hIntegralNumberOfElements + random.nextDouble() * (hIntegralX1 - hIntegralNumberOfElements);
// u is uniformly distributed in (hIntegralX1, hIntegralNumberOfElements]
double x = hIntegralInverse(u);
-
int k = (int)(x + 0.5);
// Limit k to the range [1, numberOfElements]
diff --git a/src/main/java/org/apache/commons/math4/random/RandomDataGenerator.java b/src/main/java/org/apache/commons/math4/random/RandomDataGenerator.java
index d66808dc8..e19b1368a 100644
--- a/src/main/java/org/apache/commons/math4/random/RandomDataGenerator.java
+++ b/src/main/java/org/apache/commons/math4/random/RandomDataGenerator.java
@@ -18,9 +18,6 @@
package org.apache.commons.math4.random;
import java.io.Serializable;
-import java.io.IOException;
-import java.io.ObjectOutputStream;
-import java.io.ObjectInputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
@@ -49,7 +46,6 @@ import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.OutOfRangeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.rng.RandomSource;
import org.apache.commons.math4.rng.UniformRandomProvider;
import org.apache.commons.math4.util.MathArrays;
@@ -120,13 +116,7 @@ public class RandomDataGenerator implements Serializable {
private static final long serialVersionUID = -626730818244969716L;
/** underlying random number generator */
- @Deprecated
- private RandomGenerator rand = null;
-
- /** Underlying random number generator. */
- private transient UniformRandomProvider randomProvider = null;
- /** Underlying source of randomness. */
- private final RandomSource randomSource;
+ private RandomGenerator rand;
/** underlying secure random number generator */
private RandomGenerator secRand = null;
@@ -140,7 +130,7 @@ public class RandomDataGenerator implements Serializable {
* The generator is initialized and seeded on first use.
*/
public RandomDataGenerator() {
- randomSource = RandomSource.WELL_19937_C;
+ rand = new Well19937c();
}
/**
@@ -150,20 +140,8 @@ public class RandomDataGenerator implements Serializable {
* @param rand the source of (non-secure) random data
* (may be null, resulting in the default generator)
*/
- @Deprecated
public RandomDataGenerator(RandomGenerator rand) {
this.rand = rand;
- randomSource = RandomSource.WELL_19937_C;
- }
-
- /**
- * Creates a new instance.
- *
- * @param source Source of (non-secure) random data.
- * If {@code null}, {@link RandomSource#WELL_19937_C} will be used.
- */
- public RandomDataGenerator(RandomSource source) {
- randomSource = source == null ? RandomSource.WELL_19937_C : source;
}
/**
@@ -235,7 +213,7 @@ public class RandomDataGenerator implements Serializable {
* @throws NumberIsTooLargeException if {@code lower >= upper}
*/
public int nextInt(final int lower, final int upper) throws NumberIsTooLargeException {
- return new UniformIntegerDistribution(getRandomGenerator(), lower, upper).sample();
+ return new UniformIntegerDistribution(lower, upper).createSampler(getRandomProvider()).sample();
}
/** Generates a uniformly distributed random long integer between {@code lower}
@@ -400,7 +378,7 @@ public class RandomDataGenerator implements Serializable {
* @throws NumberIsTooLargeException if {@code lower >= upper}.
*/
public int nextSecureInt(final int lower, final int upper) throws NumberIsTooLargeException {
- return new UniformIntegerDistribution(getSecRan(), lower, upper).sample();
+ return new UniformIntegerDistribution(lower, upper).createSampler(getSecureRandomProvider()).sample();
}
/**
@@ -470,9 +448,9 @@ public class RandomDataGenerator implements Serializable {
* @throws NotStrictlyPositiveException if {@code mean <= 0}.
*/
public long nextPoisson(double mean) throws NotStrictlyPositiveException {
- return new PoissonDistribution(getRandomGenerator(), mean,
+ return new PoissonDistribution(mean,
PoissonDistribution.DEFAULT_EPSILON,
- PoissonDistribution.DEFAULT_MAX_ITERATIONS).sample();
+ PoissonDistribution.DEFAULT_MAX_ITERATIONS).createSampler(getRandomProvider()).sample();
}
/**
@@ -557,7 +535,7 @@ public class RandomDataGenerator implements Serializable {
* @throws NotPositiveException if {@code numberOfSuccesses < 0}.
*/
public int nextHypergeometric(int populationSize, int numberOfSuccesses, int sampleSize) throws NotPositiveException, NotStrictlyPositiveException, NumberIsTooLargeException {
- return new HypergeometricDistribution(getRandomGenerator(), populationSize, numberOfSuccesses, sampleSize).sample();
+ return new HypergeometricDistribution(populationSize, numberOfSuccesses, sampleSize).createSampler(getRandomProvider()).sample();
}
/**
@@ -571,7 +549,7 @@ public class RandomDataGenerator implements Serializable {
* range {@code [0, 1]}.
*/
public int nextPascal(int r, double p) throws NotStrictlyPositiveException, OutOfRangeException {
- return new PascalDistribution(getRandomGenerator(), r, p).sample();
+ return new PascalDistribution(r, p).createSampler(getRandomProvider()).sample();
}
/**
@@ -608,7 +586,7 @@ public class RandomDataGenerator implements Serializable {
* or {@code exponent <= 0}.
*/
public int nextZipf(int numberOfElements, double exponent) throws NotStrictlyPositiveException {
- return new ZipfDistribution(getRandomGenerator(), numberOfElements, exponent).sample();
+ return new ZipfDistribution(numberOfElements, exponent).createSampler(getRandomProvider()).sample();
}
/**
@@ -630,7 +608,7 @@ public class RandomDataGenerator implements Serializable {
* @return random value sampled from the Binomial(numberOfTrials, probabilityOfSuccess) distribution
*/
public int nextBinomial(int numberOfTrials, double probabilityOfSuccess) {
- return new BinomialDistribution(getRandomGenerator(), numberOfTrials, probabilityOfSuccess).sample();
+ return new BinomialDistribution(numberOfTrials, probabilityOfSuccess).createSampler(getRandomProvider()).sample();
}
/**
@@ -764,7 +742,7 @@ public class RandomDataGenerator implements Serializable {
*
* Generated arrays represent permutations of {@code n} taken {@code k} at a
* time.
- * This method calls {@link MathArrays#shuffle(int[],RandomGenerator)
+ * This method calls {@link MathArrays#shuffle(int[],UniformRandomProvider)
* MathArrays.shuffle} in order to create a random shuffle of the set
* of natural numbers {@code { 0, 1, ..., n - 1 }}.
*
@@ -788,7 +766,7 @@ public class RandomDataGenerator implements Serializable {
}
int[] index = MathArrays.natural(n);
- MathArrays.shuffle(index, getRandomGenerator());
+ MathArrays.shuffle(index, getRandomProvider());
// Return a new array containing the first "k" entries of "index".
return MathArrays.copyOf(index, k);
@@ -845,7 +823,6 @@ public class RandomDataGenerator implements Serializable {
* @param seed the seed value to use
*/
public void reSeed(long seed) {
- randomProvider = RandomSource.create(randomSource, seed);
getRandomGenerator().setSeed(seed);
}
@@ -912,7 +889,6 @@ public class RandomDataGenerator implements Serializable {
* @return the Random used to generate random data
* @since 3.2
*/
- @Deprecated
public RandomGenerator getRandomGenerator() {
if (rand == null) {
initRan();
@@ -920,6 +896,77 @@ public class RandomDataGenerator implements Serializable {
return rand;
}
+ /**
+ * @param rng {@link RandomGenerator} instance.
+ * @return a {@link UniformRandomProvider} instance.
+ */
+ private UniformRandomProvider wrapRandomGenerator(final RandomGenerator rng) {
+ return new UniformRandomProvider() {
+ /** {@inheritDoc} */
+ @Override
+ public void nextBytes(byte[] bytes) {
+ rng.nextBytes(bytes);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public void nextBytes(byte[] bytes,
+ int start,
+ int len) {
+ throw new MathInternalError();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int nextInt() {
+ return rng.nextInt();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public int nextInt(int n) {
+ return rng.nextInt(n);
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public long nextLong() {
+ return rng.nextLong();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public long nextLong(long n) {
+ throw new MathInternalError();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public boolean nextBoolean() {
+ return rng.nextBoolean();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public float nextFloat() {
+ return rng.nextFloat();
+ }
+
+ /** {@inheritDoc} */
+ @Override
+ public double nextDouble() {
+ return rng.nextDouble();
+ }
+ };
+ }
+
+ /**
+ * @return the generator used to generate secure random data.
+ */
+ private UniformRandomProvider getSecureRandomProvider() {
+ return wrapRandomGenerator(getSecRan());
+ }
+
/**
* @return the generator used to generate non-secure random data.
*
@@ -927,17 +974,13 @@ public class RandomDataGenerator implements Serializable {
* "ValueServer" should be fixed to not use the internals of another class!
*/
UniformRandomProvider getRandomProvider() {
- if (randomProvider == null) {
- randomProvider = RandomSource.create(randomSource);
- }
- return randomProvider;
+ return wrapRandomGenerator(getRandomGenerator());
}
/**
* Sets the default generator to a {@link Well19937c} generator seeded with
* {@code System.currentTimeMillis() + System.identityHashCode(this))}.
*/
- @Deprecated
private void initRan() {
rand = new Well19937c(System.currentTimeMillis() + System.identityHashCode(this));
}
@@ -959,42 +1002,4 @@ public class RandomDataGenerator implements Serializable {
}
return secRand;
}
-
- /**
- * @param out Output stream.
- * @throws IOException if an error occurs.
- */
- private void writeObject(ObjectOutputStream out)
- throws IOException {
- // Write non-transient fields.
- out.defaultWriteObject();
-
- if (randomProvider != null) {
- // Save state of "randomProvider".
- out.writeObject(RandomSource.saveState(randomProvider));
- } else {
- out.writeObject(null);
- }
- }
-
- /**
- * @param in Input stream.
- * @throws IOException if an error occurs.
- * @throws ClassNotFoundException if an error occurs.
- */
- private void readObject(ObjectInputStream in)
- throws IOException,
- ClassNotFoundException {
- // Read non-transient fields.
- in.defaultReadObject();
-
- // Read "randomProvider" state (can be null).
- final Object state = in.readObject();
- if (state != null) {
- // Recreate "randomProvider" from serialized info.
- randomProvider = RandomSource.create(randomSource);
- // And restore its state.
- RandomSource.restoreState(randomProvider, (RandomSource.State) state);
- }
- }
}
diff --git a/src/main/java/org/apache/commons/math4/stat/inference/BinomialTest.java b/src/main/java/org/apache/commons/math4/stat/inference/BinomialTest.java
index 7b6ca26eb..d5003117c 100644
--- a/src/main/java/org/apache/commons/math4/stat/inference/BinomialTest.java
+++ b/src/main/java/org/apache/commons/math4/stat/inference/BinomialTest.java
@@ -119,8 +119,7 @@ public class BinomialTest {
throw new NullArgumentException();
}
- // pass a null rng to avoid unneeded overhead as we will not sample from this distribution
- final BinomialDistribution distribution = new BinomialDistribution(null, numberOfTrials, probability);
+ final BinomialDistribution distribution = new BinomialDistribution(numberOfTrials, probability);
switch (alternativeHypothesis) {
case GREATER_THAN:
return 1 - distribution.cumulativeProbability(numberOfSuccesses - 1);
diff --git a/src/main/java/org/apache/commons/math4/util/MathArrays.java b/src/main/java/org/apache/commons/math4/util/MathArrays.java
index c50f44c25..bc629a0eb 100644
--- a/src/main/java/org/apache/commons/math4/util/MathArrays.java
+++ b/src/main/java/org/apache/commons/math4/util/MathArrays.java
@@ -40,8 +40,8 @@ import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NullArgumentException;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
+import org.apache.commons.math4.rng.RandomSource;
+import org.apache.commons.math4.rng.UniformRandomProvider;
/**
* Arrays utilities.
@@ -1578,7 +1578,7 @@ public class MathArrays {
* The {@code start} and {@code pos} parameters select which portion
* of the array is randomized and which is left untouched.
*
- * @see #shuffle(int[],int,Position,RandomGenerator)
+ * @see #shuffle(int[],int,Position,UniformRandomProvider)
*
* @param list Array whose entries will be shuffled (in-place).
* @param start Index at which shuffling begins.
@@ -1589,7 +1589,7 @@ public class MathArrays {
public static void shuffle(int[] list,
int start,
Position pos) {
- shuffle(list, start, pos, new Well19937c());
+ shuffle(list, start, pos, RandomSource.create(RandomSource.WELL_19937_C));
}
/**
@@ -1609,7 +1609,7 @@ public class MathArrays {
public static void shuffle(int[] list,
int start,
Position pos,
- RandomGenerator rng) {
+ UniformRandomProvider rng) {
switch (pos) {
case TAIL: {
for (int i = list.length - 1; i >= start; i--) {
@@ -1618,7 +1618,7 @@ public class MathArrays {
target = start;
} else {
// NumberIsTooLargeException cannot occur.
- target = new UniformIntegerDistribution(rng, start, i).sample();
+ target = new UniformIntegerDistribution(start, i).createSampler(rng).sample();
}
final int temp = list[target];
list[target] = list[i];
@@ -1633,7 +1633,7 @@ public class MathArrays {
target = start;
} else {
// NumberIsTooLargeException cannot occur.
- target = new UniformIntegerDistribution(rng, i, start).sample();
+ target = new UniformIntegerDistribution(i, start).createSampler(rng).sample();
}
final int temp = list[target];
list[target] = list[i];
@@ -1649,25 +1649,25 @@ public class MathArrays {
/**
* Shuffle the entries of the given array.
*
- * @see #shuffle(int[],int,Position,RandomGenerator)
+ * @see #shuffle(int[],int,Position,UniformRandomProvider)
*
* @param list Array whose entries will be shuffled (in-place).
* @param rng Random number generator.
*/
public static void shuffle(int[] list,
- RandomGenerator rng) {
+ UniformRandomProvider rng) {
shuffle(list, 0, Position.TAIL, rng);
}
/**
* Shuffle the entries of the given array.
*
- * @see #shuffle(int[],int,Position,RandomGenerator)
+ * @see #shuffle(int[],int,Position,UniformRandomProvider)
*
* @param list Array whose entries will be shuffled (in-place).
*/
public static void shuffle(int[] list) {
- shuffle(list, new Well19937c());
+ shuffle(list, RandomSource.create(RandomSource.WELL_19937_C));
}
/**
diff --git a/src/test/java/org/apache/commons/math4/PerfTestUtils.java b/src/test/java/org/apache/commons/math4/PerfTestUtils.java
index 2064f534a..622502ecb 100644
--- a/src/test/java/org/apache/commons/math4/PerfTestUtils.java
+++ b/src/test/java/org/apache/commons/math4/PerfTestUtils.java
@@ -22,8 +22,8 @@ import java.util.regex.MatchResult;
import java.util.concurrent.Callable;
import org.apache.commons.math4.util.MathArrays;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well19937c;
+import org.apache.commons.math4.rng.UniformRandomProvider;
+import org.apache.commons.math4.rng.RandomSource;
import org.apache.commons.math4.exception.MathIllegalStateException;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.exception.util.LocalizedFormats;
@@ -53,7 +53,7 @@ public class PerfTestUtils {
/** Default number of code repeats for computing the average run time. */
private static final int DEFAULT_REPEAT_STAT = 10000;
/** RNG. */
- private static RandomGenerator rng = new Well19937c();
+ private static UniformRandomProvider rng = RandomSource.create(RandomSource.WELL_19937_C);
/**
* Timing.
diff --git a/src/test/java/org/apache/commons/math4/distribution/AbstractIntegerDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/AbstractIntegerDistributionTest.java
index e83403f4a..32e597648 100644
--- a/src/test/java/org/apache/commons/math4/distribution/AbstractIntegerDistributionTest.java
+++ b/src/test/java/org/apache/commons/math4/distribution/AbstractIntegerDistributionTest.java
@@ -83,10 +83,6 @@ public class AbstractIntegerDistributionTest {
private final double p = 1d/6d;
- public DiceDistribution() {
- super(null);
- }
-
public double probability(int x) {
if (x < 1 || x > 6) {
return 0;
diff --git a/src/test/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistributionTest.java
index 2a66f9554..d1f3afca7 100644
--- a/src/test/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistributionTest.java
+++ b/src/test/java/org/apache/commons/math4/distribution/EnumeratedIntegerDistributionTest.java
@@ -25,6 +25,7 @@ import org.apache.commons.math4.exception.NotANumberException;
import org.apache.commons.math4.exception.NotFiniteNumberException;
import org.apache.commons.math4.exception.NotPositiveException;
import org.apache.commons.math4.util.FastMath;
+import org.apache.commons.math4.rng.RandomSource;
import org.junit.Assert;
import org.junit.Test;
@@ -157,8 +158,10 @@ public class EnumeratedIntegerDistributionTest {
@Test
public void testSample() {
final int n = 1000000;
- testDistribution.reseedRandomGenerator(-334759360); // fixed seed
- final int[] samples = testDistribution.sample(n);
+ final IntegerDistribution.Sampler sampler
+ = testDistribution.createSampler(RandomSource.create(RandomSource.WELL_19937_C,
+ -334759360)); // fixed seed
+ final int[] samples = AbstractIntegerDistribution.sample(n, sampler);
Assert.assertEquals(n, samples.length);
double sum = 0;
double sumOfSquares = 0;
diff --git a/src/test/java/org/apache/commons/math4/distribution/HypergeometricDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/HypergeometricDistributionTest.java
index b2d11f439..e12c5b42c 100644
--- a/src/test/java/org/apache/commons/math4/distribution/HypergeometricDistributionTest.java
+++ b/src/test/java/org/apache/commons/math4/distribution/HypergeometricDistributionTest.java
@@ -24,6 +24,7 @@ import org.apache.commons.math4.exception.NotPositiveException;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NumberIsTooLargeException;
import org.apache.commons.math4.util.Precision;
+import org.apache.commons.math4.rng.RandomSource;
import org.junit.Assert;
import org.junit.Test;
@@ -315,7 +316,8 @@ public class HypergeometricDistributionTest extends IntegerDistributionAbstractT
final int N = 43130568;
final int m = 42976365;
final int n = 50;
- final HypergeometricDistribution dist = new HypergeometricDistribution(N, m, n);
+ final IntegerDistribution.Sampler dist =
+ new HypergeometricDistribution(N, m, n).createSampler(RandomSource.create(RandomSource.WELL_512_A));
for (int i = 0; i < 100; i++) {
final int sample = dist.sample();
diff --git a/src/test/java/org/apache/commons/math4/distribution/IntegerDistributionAbstractTest.java b/src/test/java/org/apache/commons/math4/distribution/IntegerDistributionAbstractTest.java
index 8f09b13bc..dbf8062e3 100644
--- a/src/test/java/org/apache/commons/math4/distribution/IntegerDistributionAbstractTest.java
+++ b/src/test/java/org/apache/commons/math4/distribution/IntegerDistributionAbstractTest.java
@@ -20,6 +20,7 @@ import org.apache.commons.math4.TestUtils;
import org.apache.commons.math4.distribution.AbstractIntegerDistribution;
import org.apache.commons.math4.distribution.IntegerDistribution;
import org.apache.commons.math4.exception.MathIllegalArgumentException;
+import org.apache.commons.math4.rng.RandomSource;
import org.apache.commons.math4.util.FastMath;
import org.junit.After;
import org.junit.Assert;
@@ -296,8 +297,11 @@ public abstract class IntegerDistributionAbstractTest {
for (int i = 0; i < length; i++) {
expectedCounts[i] = sampleSize * densityValues[i];
}
- distribution.reseedRandomGenerator(1000); // Use fixed seed
- int[] sample = distribution.sample(sampleSize);
+ // Use fixed seed.
+ final IntegerDistribution.Sampler sampler =
+ distribution.createSampler(RandomSource.create(RandomSource.WELL_512_A,
+ 1000));
+ int[] sample = AbstractIntegerDistribution.sample(sampleSize, sampler);
for (int i = 0; i < sampleSize; i++) {
for (int j = 0; j < length; j++) {
if (sample[i] == densityPoints[j]) {
diff --git a/src/test/java/org/apache/commons/math4/distribution/ZipfDistributionTest.java b/src/test/java/org/apache/commons/math4/distribution/ZipfDistributionTest.java
index eeae81ff6..de23a2685 100644
--- a/src/test/java/org/apache/commons/math4/distribution/ZipfDistributionTest.java
+++ b/src/test/java/org/apache/commons/math4/distribution/ZipfDistributionTest.java
@@ -20,9 +20,7 @@ package org.apache.commons.math4.distribution;
import org.apache.commons.math4.TestUtils;
import org.apache.commons.math4.distribution.ZipfDistribution.ZipfRejectionInversionSampler;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
-import org.apache.commons.math4.random.AbstractRandomGenerator;
-import org.apache.commons.math4.random.RandomGenerator;
-import org.apache.commons.math4.random.Well1024a;
+import org.apache.commons.math4.rng.RandomSource;
import org.apache.commons.math4.util.FastMath;
import org.junit.Assert;
import org.junit.Ignore;
@@ -150,15 +148,18 @@ public class ZipfDistributionTest extends IntegerDistributionAbstractTest {
weightSum += weights[i-1];
}
- ZipfDistribution distribution = new ZipfDistribution(numPoints, exponent);
- distribution.reseedRandomGenerator(6); // use fixed seed, the test is expected to fail for more than 50% of all seeds because each test case can fail with probability 0.001, the chance that all test cases do not fail is 0.999^(32*22) = 0.49442874426
+ // Use fixed seed, the test is expected to fail for more than 50% of all
+ // seeds because each test case can fail with probability 0.001, the chance
+ // that all test cases do not fail is 0.999^(32*22) = 0.49442874426
+ IntegerDistribution.Sampler distribution =
+ new ZipfDistribution(numPoints, exponent).createSampler(RandomSource.create(RandomSource.WELL_19937_C, 6));
double[] expectedCounts = new double[numPoints];
long[] observedCounts = new long[numPoints];
for (int i = 0; i < numPoints; i++) {
expectedCounts[i] = sampleSize * (weights[i]/weightSum);
}
- int[] sample = distribution.sample(sampleSize);
+ int[] sample = AbstractIntegerDistribution.sample(sampleSize, distribution);
for (int s : sample) {
observedCounts[s-1]++;
}
@@ -177,11 +178,11 @@ public class ZipfDistributionTest extends IntegerDistributionAbstractTest {
};
for (final double testValue : testValues) {
final double expected = FastMath.log1p(testValue);
- TestUtils.assertRelativelyEquals(expected, ZipfRejectionInversionSampler.helper1(testValue)*testValue, tol);
+ final double actual = ZipfRejectionInversionSampler.helper1(testValue) * testValue;
+ TestUtils.assertRelativelyEquals(expected, actual, tol);
}
}
-
@Test
public void testSamplerHelper1Minus1() {
Assert.assertEquals(Double.POSITIVE_INFINITY, ZipfRejectionInversionSampler.helper1(-1d), 0d);
@@ -197,7 +198,8 @@ public class ZipfDistributionTest extends IntegerDistributionAbstractTest {
};
for (double testValue : testValues) {
final double expected = FastMath.expm1(testValue);
- TestUtils.assertRelativelyEquals(expected, ZipfRejectionInversionSampler.helper2(testValue)*testValue, tol);
+ final double actual = ZipfRejectionInversionSampler.helper2(testValue) * testValue;
+ TestUtils.assertRelativelyEquals(expected, actual, tol);
}
}
@@ -215,22 +217,8 @@ public class ZipfDistributionTest extends IntegerDistributionAbstractTest {
long start = System.currentTimeMillis();
final int[] randomNumberCounter = new int[1];
- RandomGenerator randomGenerator = new AbstractRandomGenerator() {
-
- private final RandomGenerator r = new Well1024a(0L);
-
- @Override
- public void setSeed(long seed) {
- }
-
- @Override
- public double nextDouble() {
- randomNumberCounter[0]+=1;
- return r.nextDouble();
- }
- };
-
- final ZipfDistribution distribution = new ZipfDistribution(randomGenerator, numPoints, exponent);
+ final IntegerDistribution.Sampler distribution =
+ new ZipfDistribution(numPoints, exponent).createSampler(RandomSource.create(RandomSource.WELL_1024_A));
for (int i = 0; i < numGeneratedSamples; ++i) {
sum += distribution.sample();
}
diff --git a/src/test/java/org/apache/commons/math4/random/RandomDataGeneratorTest.java b/src/test/java/org/apache/commons/math4/random/RandomDataGeneratorTest.java
index 2982efb35..d7c490666 100644
--- a/src/test/java/org/apache/commons/math4/random/RandomDataGeneratorTest.java
+++ b/src/test/java/org/apache/commons/math4/random/RandomDataGeneratorTest.java
@@ -1209,18 +1209,4 @@ public class RandomDataGeneratorTest {
}
TestUtils.assertChiSquareAccept(densityPoints, expectedCounts, observedCounts, .001);
}
-
- @Test
- /**
- * MATH-720
- */
- public void testReseed() {
- PoissonDistribution x = new PoissonDistribution(3.0);
- x.reseedRandomGenerator(0);
- final double u = x.sample();
- PoissonDistribution y = new PoissonDistribution(3.0);
- y.reseedRandomGenerator(0);
- Assert.assertEquals(u, y.sample(), 0);
- }
-
}
diff --git a/src/test/java/org/apache/commons/math4/stat/descriptive/AggregateSummaryStatisticsTest.java b/src/test/java/org/apache/commons/math4/stat/descriptive/AggregateSummaryStatisticsTest.java
index 139a06023..43ca593a2 100644
--- a/src/test/java/org/apache/commons/math4/stat/descriptive/AggregateSummaryStatisticsTest.java
+++ b/src/test/java/org/apache/commons/math4/stat/descriptive/AggregateSummaryStatisticsTest.java
@@ -282,7 +282,9 @@ public class AggregateSummaryStatisticsTest {
* @return array of random double values
*/
private double[] generateSample() {
- final IntegerDistribution size = new UniformIntegerDistribution(10, 100);
+ final IntegerDistribution.Sampler size =
+ new UniformIntegerDistribution(10, 100).createSampler(RandomSource.create(RandomSource.WELL_512_A,
+ 327652));
final RealDistribution.Sampler randomData
= new UniformRealDistribution(-100, 100).createSampler(RandomSource.create(RandomSource.WELL_512_A,
64925784252L));;
@@ -312,7 +314,9 @@ public class AggregateSummaryStatisticsTest {
if (i == 4 || cur == length - 1) {
next = length - 1;
} else {
- next = (new UniformIntegerDistribution(cur, length - 1)).sample();
+ final IntegerDistribution.Sampler sampler =
+ new UniformIntegerDistribution(cur, length - 1).createSampler(RandomSource.create(RandomSource.WELL_512_A));
+ next = sampler.sample();
}
final int subLength = next - cur + 1;
out[i] = new double[subLength];
diff --git a/src/test/java/org/apache/commons/math4/stat/descriptive/UnivariateStatisticAbstractTest.java b/src/test/java/org/apache/commons/math4/stat/descriptive/UnivariateStatisticAbstractTest.java
index cd5be562f..38e844dd5 100644
--- a/src/test/java/org/apache/commons/math4/stat/descriptive/UnivariateStatisticAbstractTest.java
+++ b/src/test/java/org/apache/commons/math4/stat/descriptive/UnivariateStatisticAbstractTest.java
@@ -179,7 +179,9 @@ public abstract class UnivariateStatisticAbstractTest {
// Fill weights array with random int values between 1 and 5
int[] intWeights = new int[len];
- final IntegerDistribution weightDist = new UniformIntegerDistribution(1, 5);
+ final IntegerDistribution.Sampler weightDist =
+ new UniformIntegerDistribution(1, 5).createSampler(RandomSource.create(RandomSource.WELL_512_A,
+ 234878544L));
for (int i = 0; i < len; i++) {
intWeights[i] = weightDist.sample();
weights[i] = intWeights[i];
@@ -188,9 +190,9 @@ public abstract class UnivariateStatisticAbstractTest {
// Fill values array with random data from N(mu, sigma)
// and fill valuesList with values from values array with
// values[i] repeated weights[i] times, each i
- final RealDistribution.Sampler valueDist
- = new NormalDistribution(mu, sigma).createSampler(RandomSource.create(RandomSource.WELL_512_A,
- 64925784252L));
+ final RealDistribution.Sampler valueDist =
+ new NormalDistribution(mu, sigma).createSampler(RandomSource.create(RandomSource.WELL_512_A,
+ 64925784252L));
List valuesList = new ArrayList();
for (int i = 0; i < len; i++) {
double value = valueDist.sample();
diff --git a/src/test/java/org/apache/commons/math4/util/MathArraysTest.java b/src/test/java/org/apache/commons/math4/util/MathArraysTest.java
index a6cc7649e..e4862fa5e 100644
--- a/src/test/java/org/apache/commons/math4/util/MathArraysTest.java
+++ b/src/test/java/org/apache/commons/math4/util/MathArraysTest.java
@@ -25,6 +25,7 @@ import org.apache.commons.math4.exception.NotANumberException;
import org.apache.commons.math4.exception.NotPositiveException;
import org.apache.commons.math4.exception.NotStrictlyPositiveException;
import org.apache.commons.math4.exception.NullArgumentException;
+import org.apache.commons.math4.rng.RandomSource;
import org.apache.commons.math4.random.Well1024a;
import org.apache.commons.math4.util.FastMath;
import org.apache.commons.math4.util.MathArrays;
@@ -1111,7 +1112,8 @@ public class MathArraysTest {
final int[] orig = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
final int[] list = orig.clone();
final int start = 4;
- MathArrays.shuffle(list, start, MathArrays.Position.TAIL, new Well1024a(7654321L));
+ MathArrays.shuffle(list, start, MathArrays.Position.TAIL,
+ RandomSource.create(RandomSource.WELL_19937_C, 7654321L));
// Ensure that all entries below index "start" did not move.
for (int i = 0; i < start; i++) {
@@ -1134,7 +1136,8 @@ public class MathArraysTest {
final int[] orig = new int[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
final int[] list = orig.clone();
final int start = 4;
- MathArrays.shuffle(list, start, MathArrays.Position.HEAD, new Well1024a(1234567L));
+ MathArrays.shuffle(list, start, MathArrays.Position.HEAD,
+ RandomSource.create(RandomSource.WELL_19937_C, 1234567L));
// Ensure that all entries above index "start" did not move.
for (int i = start + 1; i < orig.length; i++) {
diff --git a/src/test/java/org/apache/commons/math4/util/ResizableDoubleArrayTest.java b/src/test/java/org/apache/commons/math4/util/ResizableDoubleArrayTest.java
index be897a5a7..bf87c3ba6 100644
--- a/src/test/java/org/apache/commons/math4/util/ResizableDoubleArrayTest.java
+++ b/src/test/java/org/apache/commons/math4/util/ResizableDoubleArrayTest.java
@@ -20,6 +20,7 @@ import org.apache.commons.math4.distribution.IntegerDistribution;
import org.apache.commons.math4.distribution.UniformIntegerDistribution;
import org.apache.commons.math4.exception.MathIllegalArgumentException;
import org.apache.commons.math4.exception.NullArgumentException;
+import org.apache.commons.math4.rng.RandomSource;
import org.apache.commons.math4.util.ResizableDoubleArray.ExpansionMode;
import org.junit.After;
import org.junit.Assert;
@@ -321,7 +322,8 @@ public class ResizableDoubleArrayTest extends DoubleArrayAbstractTest {
ResizableDoubleArray eDA2 = new ResizableDoubleArray(2);
Assert.assertEquals("Initial number of elements should be 0", 0, eDA2.getNumElements());
- final IntegerDistribution randomData = new UniformIntegerDistribution(100, 1000);
+ final IntegerDistribution.Sampler randomData =
+ new UniformIntegerDistribution(100, 1000).createSampler(RandomSource.create(RandomSource.WELL_19937_C));
final int iterations = randomData.sample();
for( int i = 0; i < iterations; i++) {
@@ -342,7 +344,9 @@ public class ResizableDoubleArrayTest extends DoubleArrayAbstractTest {
ResizableDoubleArray eDA3 = new ResizableDoubleArray(3, 3.0, 3.5);
Assert.assertEquals("Initial number of elements should be 0", 0, eDA3.getNumElements() );
- final IntegerDistribution randomData = new UniformIntegerDistribution(100, 3000);
+ final IntegerDistribution.Sampler randomData =
+ new UniformIntegerDistribution(100, 3000).createSampler(RandomSource.create(RandomSource.WELL_19937_C));
+;
final int iterations = randomData.sample();
for( int i = 0; i < iterations; i++) {