This is an automated email from the ASF dual-hosted git repository. aherbert pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/commons-rng.git
commit 56c15c8fe406ff0e5a02aa20f9484f5d1942a055 Author: aherbert <[email protected]> AuthorDate: Mon Apr 15 16:43:26 2019 +0100 RNG-93: SmallMeanPoissonSampler requires probability p0 to be positive. --- .../sampling/distribution/SmallMeanPoissonSampler.java | 18 ++++++++---------- .../distribution/SmallMeanPoissonSamplerTest.java | 7 +++++-- src/changes/changes.xml | 4 ++++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSampler.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSampler.java index 607feef..9e920bd 100644 --- a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSampler.java +++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSampler.java @@ -38,8 +38,6 @@ import org.apache.commons.rng.UniformRandomProvider; */ public class SmallMeanPoissonSampler implements DiscreteSampler { - /** Upper bound to avoid truncation. */ - private static final double MAX_MEAN = 0.5 * Integer.MAX_VALUE; /** * Pre-compute {@code Math.exp(-mean)}. * Note: This is the probability of the Poisson sample {@code P(n=0)}. @@ -53,8 +51,7 @@ public class SmallMeanPoissonSampler /** * @param rng Generator of uniformly distributed random numbers. * @param mean Mean. - * @throws IllegalArgumentException if {@code mean <= 0} or - * {@code mean > 0.5 *} {@link Integer#MAX_VALUE}. + * @throws IllegalArgumentException if {@code mean <= 0} or {@code Math.exp(-mean)} is not positive. */ public SmallMeanPoissonSampler(UniformRandomProvider rng, double mean) { @@ -62,13 +59,14 @@ public class SmallMeanPoissonSampler if (mean <= 0) { throw new IllegalArgumentException("mean is not strictly positive: " + mean); } - if (mean > MAX_MEAN) { - throw new IllegalArgumentException("mean " + mean + " > " + MAX_MEAN); - } - p0 = Math.exp(-mean); - // The returned sample is bounded by 1000 * mean or Integer.MAX_VALUE - limit = (int) Math.ceil(Math.min(1000 * mean, Integer.MAX_VALUE)); + if (p0 > 0) { + // The returned sample is bounded by 1000 * mean + limit = (int) Math.ceil(1000 * mean); + } else { + // This excludes NaN values for the mean + throw new IllegalArgumentException("No p(x=0) probability for mean: " + mean); + } } /** {@inheritDoc} */ diff --git a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSamplerTest.java b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSamplerTest.java index 92a60fb..d8db267 100644 --- a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSamplerTest.java +++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSamplerTest.java @@ -29,10 +29,13 @@ public class SmallMeanPoissonSamplerTest { * Test the constructor with a bad mean. */ @Test(expected=IllegalArgumentException.class) - public void testConstructorThrowsWithMeanLargerThanUpperBound() { + public void testConstructorThrowsWithMeanThatSetsProbabilityP0ToZero() { final UniformRandomProvider rng = RandomSource.create(RandomSource.SPLIT_MIX_64); - final double mean = Integer.MAX_VALUE / 2 + 1; + final double p0 = Double.MIN_VALUE; + // Note: p0 = Math.exp(-mean) => mean = -Math.log(p0). + // Add to the limit on the mean to cause p0 to be zero. + final double mean = -Math.log(p0) + 1; @SuppressWarnings("unused") SmallMeanPoissonSampler sampler = new SmallMeanPoissonSampler(rng, mean); } diff --git a/src/changes/changes.xml b/src/changes/changes.xml index f286d59..f754aae 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -75,6 +75,10 @@ re-run tests that fail, and pass the build if they succeed within the allotted number of reruns (the test will be marked as 'flaky' in the report). "> + <action dev="aherbert" type="fix" issue="RNG-93"> + "SmallMeanPoissonSampler": Requires the Poisson probability for p(x=0) to be positive + setting an upper bound on the mean of approximately 744.44. + </action> <action dev="aherbert" type="fix" issue="RNG-92"> "LargeMeanPoissonSampler": Requires mean >= 1. </action>
