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: - *

- *

- * - * @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++) {