Repository: commons-math Updated Branches: refs/heads/MATH_3_X 59912a072 -> d41364faa
Fixed EmpiricalDistrubiton#cumulativeProbability to correctly handle constant bin kernels. JIRA: MATH-1208. Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/d41364fa Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/d41364fa Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/d41364fa Branch: refs/heads/MATH_3_X Commit: d41364faa4f73fc885dcc9e99a838e8fa4c95998 Parents: 59912a0 Author: Phil Steitz <[email protected]> Authored: Sun Mar 8 17:46:05 2015 -0700 Committer: Phil Steitz <[email protected]> Committed: Sun Mar 8 17:46:05 2015 -0700 ---------------------------------------------------------------------- src/changes/changes.xml | 3 +++ .../commons/math3/random/EmpiricalDistribution.java | 9 +++++++-- .../commons/math3/random/EmpiricalDistributionTest.java | 12 ++++++++---- 3 files changed, 18 insertions(+), 6 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/d41364fa/src/changes/changes.xml ---------------------------------------------------------------------- diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 03d6fa9..d976897 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,9 @@ If the output is not quite correct, check for invisible trailing spaces! </release> <release version="3.5" date="2015-01-11" description=""> + <action dev="psteitz" type="fix" issue="MATH-1208"> + EmpiricalDistribution cumulativeProbability can return NaN when evaluated within a constant bin. + </action> <action dev="psteitz" type="fix" issue="MATH-1203"> EmpiricalDistribution getKernel fails for buckets with only multiple instances of the same value. </action> http://git-wip-us.apache.org/repos/asf/commons-math/blob/d41364fa/src/main/java/org/apache/commons/math3/random/EmpiricalDistribution.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math3/random/EmpiricalDistribution.java b/src/main/java/org/apache/commons/math3/random/EmpiricalDistribution.java index fc27300..c2323fc 100644 --- a/src/main/java/org/apache/commons/math3/random/EmpiricalDistribution.java +++ b/src/main/java/org/apache/commons/math3/random/EmpiricalDistribution.java @@ -620,7 +620,9 @@ public class EmpiricalDistribution extends AbstractRealDistribution { * <li>Compute K(B) = the probability mass of B with respect to the within-bin kernel * and K(B-) = the kernel distribution evaluated at the lower endpoint of B</li> * <li>Return P(B-) + P(B) * [K(x) - K(B-)] / K(B) where - * K(x) is the within-bin kernel distribution function evaluated at x.</li></ol></p> + * K(x) is the within-bin kernel distribution function evaluated at x.</li></ol> + * If K is a constant distribution, we return P(B-) + P(B) (counting the full + * mass of B).</p> * * @since 3.1 */ @@ -633,10 +635,13 @@ public class EmpiricalDistribution extends AbstractRealDistribution { final int binIndex = findBin(x); final double pBminus = pBminus(binIndex); final double pB = pB(binIndex); + final RealDistribution kernel = k(x); + if (kernel instanceof ConstantRealDistribution) { + return pBminus + pB; + } final double[] binBounds = getUpperBounds(); final double kB = kB(binIndex); final double lower = binIndex == 0 ? min : binBounds[binIndex - 1]; - final RealDistribution kernel = k(x); final double withinBinCum = (kernel.cumulativeProbability(x) - kernel.cumulativeProbability(lower)) / kB; return pBminus + pB * withinBinCum; http://git-wip-us.apache.org/repos/asf/commons-math/blob/d41364fa/src/test/java/org/apache/commons/math3/random/EmpiricalDistributionTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math3/random/EmpiricalDistributionTest.java b/src/test/java/org/apache/commons/math3/random/EmpiricalDistributionTest.java index 580be9e..abc96f2 100644 --- a/src/test/java/org/apache/commons/math3/random/EmpiricalDistributionTest.java +++ b/src/test/java/org/apache/commons/math3/random/EmpiricalDistributionTest.java @@ -433,7 +433,7 @@ public final class EmpiricalDistributionTest extends RealDistributionAbstractTes } /** - * MATH-1203 + * MATH-1203, MATH-1208 */ @Test public void testNoBinVariance() { @@ -445,6 +445,10 @@ public final class EmpiricalDistributionTest extends RealDistributionAbstractTes final double dev = dist.sample(); Assert.assertTrue(dev == 0 || dev == 1); } + Assert.assertEquals(0.5, dist.cumulativeProbability(0), Double.MIN_VALUE); + Assert.assertEquals(1.0, dist.cumulativeProbability(1), Double.MIN_VALUE); + Assert.assertEquals(0.5, dist.cumulativeProbability(0.5), Double.MIN_VALUE); + Assert.assertEquals(1.0, dist.cumulativeProbability(0.7), Double.MIN_VALUE); } /** @@ -484,11 +488,11 @@ public final class EmpiricalDistributionTest extends RealDistributionAbstractTes Assert.assertTrue(Arrays.binarySearch(values, dist.sample()) >= 0); } final double tol = 10E-12; - Assert.assertEquals(0.0, dist.cumulativeProbability(1), tol); + Assert.assertEquals(0.2, dist.cumulativeProbability(1), tol); Assert.assertEquals(0.2, dist.cumulativeProbability(2), tol); - Assert.assertEquals(0.6, dist.cumulativeProbability(10), tol); + Assert.assertEquals(0.8, dist.cumulativeProbability(10), tol); Assert.assertEquals(0.8, dist.cumulativeProbability(12), tol); - Assert.assertEquals(0.8, dist.cumulativeProbability(13), tol); + Assert.assertEquals(1.0, dist.cumulativeProbability(13), tol); Assert.assertEquals(1.0, dist.cumulativeProbability(15), tol); Assert.assertEquals(2.0, dist.inverseCumulativeProbability(0.1), tol);
