You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by er...@apache.org on 2018/11/15 16:36:34 UTC
commons-rng git commit: RNG-52: Conservative upper bound to avoid
silent truncation.
Repository: commons-rng
Updated Branches:
refs/heads/master 350fb428e -> 8c927dc65
RNG-52: Conservative upper bound to avoid silent truncation.
Functionality is not limited since the Poisson distribution is already
well approximated by a Gaussian for mean values larger than about 1000.
Project: http://git-wip-us.apache.org/repos/asf/commons-rng/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-rng/commit/8c927dc6
Tree: http://git-wip-us.apache.org/repos/asf/commons-rng/tree/8c927dc6
Diff: http://git-wip-us.apache.org/repos/asf/commons-rng/diff/8c927dc6
Branch: refs/heads/master
Commit: 8c927dc65dc5d86daa16304a83b033b25c43fd28
Parents: 350fb42
Author: Gilles <er...@apache.org>
Authored: Thu Nov 15 17:33:56 2018 +0100
Committer: Gilles <er...@apache.org>
Committed: Thu Nov 15 17:33:56 2018 +0100
----------------------------------------------------------------------
.../distribution/LargeMeanPoissonSampler.java | 12 ++---
.../distribution/SmallMeanPoissonSampler.java | 7 ++-
.../LargeMeanPoissonSamplerTest.java | 11 ++--
.../SmallMeanPoissonSamplerTest.java | 54 ++++++++++++++++++++
src/changes/changes.xml | 3 ++
5 files changed, 74 insertions(+), 13 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8c927dc6/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
----------------------------------------------------------------------
diff --git a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
index 70cc68b..33675d8 100644
--- a/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
+++ b/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSampler.java
@@ -38,10 +38,10 @@ import org.apache.commons.rng.sampling.distribution.InternalUtils.FactorialLog;
*/
public class LargeMeanPoissonSampler
implements DiscreteSampler {
-
+ /** Upper bound to avoid truncation. */
+ private static final double MAX_MEAN = 0.5 * Integer.MAX_VALUE;
/** Class to compute {@code log(n!)}. This has no cached values. */
private static final InternalUtils.FactorialLog NO_CACHE_FACTORIAL_LOG;
-
/** Used when there is no requirement for a small mean Poisson sampler. */
private static final DiscreteSampler NO_SMALL_MEAN_POISSON_SAMPLER = null;
@@ -96,10 +96,10 @@ public class LargeMeanPoissonSampler
private final DiscreteSampler smallMeanPoissonSampler;
/**
- * @param rng Generator of uniformly distributed random numbers.
+ * @param rng Generator of uniformly distributed random numbers.
* @param mean Mean.
* @throws IllegalArgumentException if {@code mean <= 0} or
- * {@code mean >} {@link Integer#MAX_VALUE}.
+ * {@code mean > 0.5 *} {@link Integer#MAX_VALUE}.
*/
public LargeMeanPoissonSampler(UniformRandomProvider rng,
double mean) {
@@ -107,8 +107,8 @@ public class LargeMeanPoissonSampler
throw new IllegalArgumentException(mean + " <= " + 0);
}
// The algorithm is not valid if Math.floor(mean) is not an integer.
- if (mean > Integer.MAX_VALUE) {
- throw new IllegalArgumentException(mean + " > " + Integer.MAX_VALUE);
+ if (mean > MAX_MEAN) {
+ throw new IllegalArgumentException(mean + " > " + MAX_MEAN);
}
this.rng = rng;
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8c927dc6/commons-rng-sampling/src/main/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSampler.java
----------------------------------------------------------------------
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 170a85b..c8e744e 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
@@ -32,10 +32,12 @@ import org.apache.commons.rng.UniformRandomProvider;
* @since 1.1
*
* This sampler is suitable for {@code mean < 40}.
+ * For large means, {@link LargePoissonSampler} should be used instead.
*/
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)}.
@@ -57,6 +59,9 @@ public class SmallMeanPoissonSampler
if (mean <= 0) {
throw new IllegalArgumentException(mean + " <= " + 0);
}
+ if (mean > MAX_MEAN) {
+ throw new IllegalArgumentException(mean + " > " + MAX_MEAN);
+ }
p0 = Math.exp(-mean);
// The returned sample is bounded by 1000 * mean or Integer.MAX_VALUE
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8c927dc6/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSamplerTest.java
----------------------------------------------------------------------
diff --git a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSamplerTest.java b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSamplerTest.java
index 480f452..7ee0517 100644
--- a/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSamplerTest.java
+++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/LargeMeanPoissonSamplerTest.java
@@ -35,23 +35,22 @@ public class LargeMeanPoissonSamplerTest {
* Test the constructor with a bad mean.
*/
@Test(expected=IllegalArgumentException.class)
- public void testConstructorThrowsWithZeroMean() {
+ public void testConstructorThrowsWithMeanLargerThanUpperBound() {
final RestorableUniformRandomProvider rng =
RandomSource.create(RandomSource.SPLIT_MIX_64);
@SuppressWarnings("unused")
- LargeMeanPoissonSampler sampler = new LargeMeanPoissonSampler(rng, 0);
+ LargeMeanPoissonSampler sampler = new LargeMeanPoissonSampler(rng, Integer.MAX_VALUE / 2 + 1);
}
/**
- * Test the constructor with a mean that is too large.
+ * Test the constructor with a bad mean.
*/
@Test(expected=IllegalArgumentException.class)
- public void testConstructorThrowsWithNonIntegerMean() {
+ public void testConstructorThrowsWithZeroMean() {
final RestorableUniformRandomProvider rng =
RandomSource.create(RandomSource.SPLIT_MIX_64);
- final double mean = Integer.MAX_VALUE + 1.0;
@SuppressWarnings("unused")
- LargeMeanPoissonSampler sampler = new LargeMeanPoissonSampler(rng, mean);
+ LargeMeanPoissonSampler sampler = new LargeMeanPoissonSampler(rng, 0);
}
/**
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8c927dc6/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSamplerTest.java
----------------------------------------------------------------------
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
new file mode 100644
index 0000000..775f326
--- /dev/null
+++ b/commons-rng-sampling/src/test/java/org/apache/commons/rng/sampling/distribution/SmallMeanPoissonSamplerTest.java
@@ -0,0 +1,54 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.commons.rng.sampling.distribution;
+
+import org.apache.commons.rng.RandomProviderState;
+import org.apache.commons.rng.RestorableUniformRandomProvider;
+import org.apache.commons.rng.simple.RandomSource;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * This test checks the {@link SmallMeanPoissonSampler} can be created
+ * from a saved state.
+ */
+public class SmallMeanPoissonSamplerTest {
+
+ // Edge cases for construction
+
+ /**
+ * Test the constructor with a bad mean.
+ */
+ @Test(expected=IllegalArgumentException.class)
+ public void testConstructorThrowsWithMeanLargerThanUpperBound() {
+ final RestorableUniformRandomProvider rng =
+ RandomSource.create(RandomSource.SPLIT_MIX_64);
+ @SuppressWarnings("unused")
+ SmallMeanPoissonSampler sampler = new SmallMeanPoissonSampler(rng, Integer.MAX_VALUE / 2 + 1);
+ }
+
+ /**
+ * Test the constructor with a bad mean.
+ */
+ @Test(expected=IllegalArgumentException.class)
+ public void testConstructorThrowsWithZeroMean() {
+ final RestorableUniformRandomProvider rng =
+ RandomSource.create(RandomSource.SPLIT_MIX_64);
+ @SuppressWarnings("unused")
+ SmallMeanPoissonSampler sampler = new SmallMeanPoissonSampler(rng, 0);
+ }
+}
http://git-wip-us.apache.org/repos/asf/commons-rng/blob/8c927dc6/src/changes/changes.xml
----------------------------------------------------------------------
diff --git a/src/changes/changes.xml b/src/changes/changes.xml
index 62557fe..9e249c5 100644
--- a/src/changes/changes.xml
+++ b/src/changes/changes.xml
@@ -67,6 +67,9 @@ Additional code is provided in the following module:
It is however not part of the official API and no compatibility
should be expected in subsequent releases.
">
+ <action dev="erans" type="update" issue="RNG-52">
+ Set conservative upper bound in "LargePoissonSampler" to avoid truncation.
+ </action>
<action dev="erans" type="fix" issue="RNG-59">
Use JDK's "SecureRandom" to seed the "SeedFactory".
</action>