You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by ah...@apache.org on 2021/09/20 23:35:04 UTC

[commons-statistics] branch master updated: Fix geometric distribution for p=1

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-statistics.git


The following commit(s) were added to refs/heads/master by this push:
     new 5822059  Fix geometric distribution for p=1
5822059 is described below

commit 5822059d2ccec58438f14c9ab689c0e2b6305555
Author: Alex Herbert <ah...@apache.org>
AuthorDate: Tue Sep 21 00:35:02 2021 +0100

    Fix geometric distribution for p=1
---
 .../statistics/distribution/GeometricDistribution.java | 18 +++++++++---------
 .../distribution/GeometricDistributionTest.java        |  6 ------
 2 files changed, 9 insertions(+), 15 deletions(-)

diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GeometricDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GeometricDistribution.java
index 6022b35..3f16e05 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GeometricDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GeometricDistribution.java
@@ -58,8 +58,8 @@ public class GeometricDistribution extends AbstractDiscreteDistribution {
     /** {@inheritDoc} */
     @Override
     public double probability(int x) {
-        if (x < 0) {
-            return 0.0;
+        if (x <= 0) {
+            return x < 0 ? 0.0 : probabilityOfSuccess;
         }
         return Math.exp(log1mProbabilityOfSuccess * x) * probabilityOfSuccess;
     }
@@ -67,8 +67,8 @@ public class GeometricDistribution extends AbstractDiscreteDistribution {
     /** {@inheritDoc} */
     @Override
     public double logProbability(int x) {
-        if (x < 0) {
-            return Double.NEGATIVE_INFINITY;
+        if (x <= 0) {
+            return x < 0 ? Double.NEGATIVE_INFINITY : logProbabilityOfSuccess;
         }
         return x * log1mProbabilityOfSuccess + logProbabilityOfSuccess;
     }
@@ -101,7 +101,7 @@ public class GeometricDistribution extends AbstractDiscreteDistribution {
             throw new DistributionException(DistributionException.INVALID_PROBABILITY, p);
         }
         if (p == 1) {
-            return Integer.MAX_VALUE;
+            return getSupportUpperBound();
         }
         if (p == 0) {
             return 0;
@@ -145,14 +145,14 @@ public class GeometricDistribution extends AbstractDiscreteDistribution {
     /**
      * {@inheritDoc}
      *
-     * <p>The upper bound of the support is infinite (which we approximate as
-     * {@code Integer.MAX_VALUE}).
+     * <p>The upper bound of the support is positive infinity except for the
+     * probability parameter {@code p = 1.0}.
      *
-     * @return upper bound of the support (always Integer.MAX_VALUE)
+     * @return upper bound of the support ({@code Integer.MAX_VALUE} or 0)
      */
     @Override
     public int getSupportUpperBound() {
-        return Integer.MAX_VALUE;
+        return probabilityOfSuccess < 1 ? Integer.MAX_VALUE : 0;
     }
 
     /**
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java
index ff55aec..25b528a 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/GeometricDistributionTest.java
@@ -19,7 +19,6 @@ package org.apache.commons.statistics.distribution;
 import org.apache.commons.rng.simple.RandomSource;
 import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Disabled;
 import org.junit.jupiter.api.Test;
 import org.junit.jupiter.params.ParameterizedTest;
 import org.junit.jupiter.params.provider.ValueSource;
@@ -156,7 +155,6 @@ class GeometricDistributionTest extends DiscreteDistributionAbstractTest {
     //-------------------- Additional test cases -------------------------------
 
     @Test
-    @Disabled("Requires special handling at x=0 when p=1.0")
     void testProbabilityOfSuccessOne() {
         final GeometricDistribution dist = new GeometricDistribution(1.0);
         Assertions.assertEquals(1.0, dist.getProbabilityOfSuccess());
@@ -170,18 +168,14 @@ class GeometricDistributionTest extends DiscreteDistributionAbstractTest {
         setCumulativeTestValues(new double[] {1.0, 1.0, 1.0});
         setInverseCumulativeTestPoints(new double[] {0, 0.5, 1.0});
         setInverseCumulativeTestValues(new int[] {0, 0, 0});
-        // XXX: Fails (pmf(x=0) returns NaN)
         verifyProbabilities();
-        // XXX: Fails (logpmf(x=0) returns NaN)
         verifyLogProbabilities();
         verifyCumulativeProbabilities();
         verifySurvivalProbability();
         verifySurvivalAndCumulativeProbabilityComplement();
-        // XXX: Fails (icdf(p=1) returns Integer.MAX_VALUE)
         verifyInverseCumulativeProbabilities();
 
         Assertions.assertEquals(0, dist.getSupportLowerBound());
-        // XXX: Fails (returns Integer.MAX_VALUE)
         Assertions.assertEquals(0, dist.getSupportUpperBound());
 
         final DiscreteDistribution.Sampler s = dist.createSampler(RandomSource.SPLIT_MIX_64.create());