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 2019/12/01 13:14:19 UTC

[commons-statistics] branch master updated: STATISTICS-21: Probability is zero outside support.

This is an automated email from the ASF dual-hosted git repository.

erans 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 c6b94be  STATISTICS-21: Probability is zero outside support.
c6b94be is described below

commit c6b94bef1bec3eebde34683bba748388ccbdf27a
Author: Gilles Sadowski <gi...@harfang.homelinux.org>
AuthorDate: Sun Dec 1 14:12:34 2019 +0100

    STATISTICS-21: Probability is zero outside support.
---
 .../distribution/ExponentialDistribution.java      | 22 ++++++++------
 .../statistics/distribution/FDistribution.java     | 35 ++++++++++++++--------
 .../statistics/distribution/GammaDistribution.java | 28 ++++++++++-------
 .../distribution/GumbelDistribution.java           | 12 ++++++--
 .../distribution/LogisticDistribution.java         | 13 ++++++--
 .../distribution/NakagamiDistribution.java         | 20 ++++++++++---
 .../distribution/WeibullDistribution.java          | 24 ++++++++-------
 .../ContinuousDistributionAbstractTest.java        | 16 ++++++++++
 8 files changed, 119 insertions(+), 51 deletions(-)

diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ExponentialDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ExponentialDistribution.java
index c671544..3ae91c0 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ExponentialDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/ExponentialDistribution.java
@@ -23,6 +23,10 @@ import org.apache.commons.rng.sampling.distribution.AhrensDieterExponentialSampl
  * Implementation of the <a href="http://en.wikipedia.org/wiki/Exponential_distribution">exponential distribution</a>.
  */
 public class ExponentialDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = 0;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** The mean of this distribution. */
     private final double mean;
     /** The logarithm of the mean, stored to reduce computing time. */
@@ -52,9 +56,11 @@ public class ExponentialDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} **/
     @Override
     public double logDensity(double x) {
-        if (x < 0) {
+        if (x < SUPPORT_LO ||
+            x >= SUPPORT_HI) {
             return Double.NEGATIVE_INFINITY;
         }
+
         return -x / mean - logMean;
     }
 
@@ -70,13 +76,11 @@ public class ExponentialDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double cumulativeProbability(double x)  {
-        double ret;
-        if (x <= 0) {
-            ret = 0;
-        } else {
-            ret = 1 - Math.exp(-x / mean);
+        if (x <= SUPPORT_LO) {
+            return 0;
         }
-        return ret;
+
+        return 1 - Math.exp(-x / mean);
     }
 
     /**
@@ -126,7 +130,7 @@ public class ExponentialDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportLowerBound() {
-        return 0;
+        return SUPPORT_LO;
     }
 
     /**
@@ -139,7 +143,7 @@ public class ExponentialDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /**
diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/FDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/FDistribution.java
index 6a23fd5..317ad81 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/FDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/FDistribution.java
@@ -27,6 +27,10 @@ import org.apache.commons.numbers.gamma.RegularizedBeta;
  * @see <a href="http://mathworld.wolfram.com/F-Distribution.html">F-distribution (MathWorld)</a>
  */
 public class FDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = 0;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** The minimum degrees of freedom for the denominator when computing the mean. */
     private static final double MIN_DENOMINATOR_DF_FOR_MEAN = 2.0;
     /** The minimum degrees of freedom for the denominator when computing the variance. */
@@ -70,6 +74,11 @@ public class FDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} **/
     @Override
     public double logDensity(double x) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
+            return Double.NEGATIVE_INFINITY;
+        }
+
         final double nhalf = numeratorDegreesOfFreedom / 2;
         final double mhalf = denominatorDegreesOfFreedom / 2;
         final double logx = Math.log(x);
@@ -95,18 +104,18 @@ public class FDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double cumulativeProbability(double x)  {
-        double ret;
-        if (x <= 0) {
-            ret = 0;
-        } else {
-            final double n = numeratorDegreesOfFreedom;
-            final double m = denominatorDegreesOfFreedom;
-
-            ret = RegularizedBeta.value((n * x) / (m + n * x),
-                0.5 * n,
-                0.5 * m);
+        if (x <= SUPPORT_LO) {
+            return 0;
+        } else if (x >= SUPPORT_HI) {
+            return 1;
         }
-        return ret;
+
+        final double n = numeratorDegreesOfFreedom;
+        final double m = denominatorDegreesOfFreedom;
+
+        return RegularizedBeta.value((n * x) / (m + n * x),
+                                     0.5 * n,
+                                     0.5 * m);
     }
 
     /**
@@ -184,7 +193,7 @@ public class FDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportLowerBound() {
-        return 0;
+        return SUPPORT_LO;
     }
 
     /**
@@ -197,7 +206,7 @@ public class FDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /**
diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GammaDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GammaDistribution.java
index b7f5549..f4e8dd0 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GammaDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GammaDistribution.java
@@ -25,6 +25,10 @@ import org.apache.commons.rng.sampling.distribution.AhrensDieterMarsagliaTsangGa
  * Implementation of the <a href="http://en.wikipedia.org/wiki/Gamma_distribution">Gamma distribution</a>.
  */
 public class GammaDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = 0;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** Lanczos constant. */
     private static final double LANCZOS_G = LanczosApproximation.g();
     /** The shape parameter. */
@@ -178,9 +182,11 @@ public class GammaDistribution extends AbstractContinuousDistribution {
         *               * exp(a log1pm(---------------) - ----------- + g).
         *                                a + g + 0.5      a + g + 0.5
         */
-        if (x < 0) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
             return 0;
         }
+
         final double y = x / scale;
         if ((y <= minY) || (Math.log(y) >= maxLogY)) {
             /*
@@ -203,9 +209,11 @@ public class GammaDistribution extends AbstractContinuousDistribution {
         /*
          * see the comment in {@link #density(double)} for computation details
          */
-        if (x < 0) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
             return Double.NEGATIVE_INFINITY;
         }
+
         final double y = x / scale;
         if ((y <= minY) || (Math.log(y) >= maxLogY)) {
             /*
@@ -238,15 +246,13 @@ public class GammaDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double cumulativeProbability(double x) {
-        double ret;
-
-        if (x <= 0) {
-            ret = 0;
-        } else {
-            ret = RegularizedGamma.P.value(shape, x / scale);
+        if (x <= SUPPORT_LO) {
+            return 0;
+        } else if (x >= SUPPORT_HI) {
+            return 1;
         }
 
-        return ret;
+        return RegularizedGamma.P.value(shape, x / scale);
     }
 
     /**
@@ -282,7 +288,7 @@ public class GammaDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportLowerBound() {
-        return 0;
+        return SUPPORT_LO;
     }
 
     /**
@@ -295,7 +301,7 @@ public class GammaDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /**
diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GumbelDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GumbelDistribution.java
index 5c71855..dcd3e31 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GumbelDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/GumbelDistribution.java
@@ -20,6 +20,10 @@ package org.apache.commons.statistics.distribution;
  * This class implements the <a href="http://en.wikipedia.org/wiki/Gumbel_distribution">Gumbel distribution</a>.
  */
 public class GumbelDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = Double.NEGATIVE_INFINITY;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** &pi;<sup>2</sup>/6. */
     private static final double PI_SQUARED_OVER_SIX = Math.PI * Math.PI / 6;
     /**
@@ -70,6 +74,10 @@ public class GumbelDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double density(double x) {
+        if (x <= SUPPORT_LO) {
+            return 0;
+        }
+
         final double z = (x - mu) / beta;
         final double t = Math.exp(-z);
         return Math.exp(-z - t) / beta;
@@ -110,13 +118,13 @@ public class GumbelDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double getSupportLowerBound() {
-        return Double.NEGATIVE_INFINITY;
+        return SUPPORT_LO;
     }
 
     /** {@inheritDoc} */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /** {@inheritDoc} */
diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/LogisticDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/LogisticDistribution.java
index 985e289..a0c169a 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/LogisticDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/LogisticDistribution.java
@@ -20,6 +20,10 @@ package org.apache.commons.statistics.distribution;
  * Implementation of the <a href="http://en.wikipedia.org/wiki/Logistic_distribution">Logistic distribution</a>.
  */
 public class LogisticDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = Double.NEGATIVE_INFINITY;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** &pi;<sup>2</sup>/3. */
     private static final double PI_SQUARED_OVER_THREE = Math.PI * Math.PI / 3;
     /** Location parameter. */
@@ -69,6 +73,11 @@ public class LogisticDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double density(double x) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
+            return 0;
+        }
+
         final double z = oneOverScale * (x - mu);
         final double v = Math.exp(-z);
         return oneOverScale * v / ((1 + v) * (1 + v));
@@ -111,13 +120,13 @@ public class LogisticDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double getSupportLowerBound() {
-        return Double.NEGATIVE_INFINITY;
+        return SUPPORT_LO;
     }
 
     /** {@inheritDoc} */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /** {@inheritDoc} */
diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/NakagamiDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/NakagamiDistribution.java
index 73efc29..6f7ca56 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/NakagamiDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/NakagamiDistribution.java
@@ -23,6 +23,10 @@ import org.apache.commons.numbers.gamma.RegularizedGamma;
  * This class implements the <a href="http://en.wikipedia.org/wiki/Nakagami_distribution">Nakagami distribution</a>.
  */
 public class NakagamiDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = 0;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** The minimum allowed for the shape parameter. */
     private static final double MIN_SHAPE = 0.5;
 
@@ -73,9 +77,11 @@ public class NakagamiDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double density(double x) {
-        if (x <= 0) {
-            return 0.0;
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
+            return 0;
         }
+
         return 2.0 * Math.pow(mu, mu) / (Gamma.value(mu) * Math.pow(omega, mu)) *
                      Math.pow(x, 2 * mu - 1) * Math.exp(-mu * x * x / omega);
     }
@@ -83,6 +89,12 @@ public class NakagamiDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double cumulativeProbability(double x) {
+        if (x <= SUPPORT_LO) {
+            return 0;
+        } else if (x >= SUPPORT_HI) {
+            return 1;
+        }
+
         return RegularizedGamma.P.value(mu, mu * x * x / omega);
     }
 
@@ -102,13 +114,13 @@ public class NakagamiDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double getSupportLowerBound() {
-        return 0;
+        return SUPPORT_LO;
     }
 
     /** {@inheritDoc} */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /** {@inheritDoc} */
diff --git a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/WeibullDistribution.java b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/WeibullDistribution.java
index 4a47abe..c8da876 100644
--- a/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/WeibullDistribution.java
+++ b/commons-statistics-distribution/src/main/java/org/apache/commons/statistics/distribution/WeibullDistribution.java
@@ -31,6 +31,10 @@ import org.apache.commons.numbers.gamma.LogGamma;
  * @since 1.1
  */
 public class WeibullDistribution extends AbstractContinuousDistribution {
+    /** Support lower bound. */
+    private static final double SUPPORT_LO = 0;
+    /** Support upper bound. */
+    private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** The shape parameter. */
     private final double shape;
     /** The scale parameter. */
@@ -78,7 +82,8 @@ public class WeibullDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double density(double x) {
-        if (x < 0) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
             return 0;
         }
 
@@ -98,7 +103,8 @@ public class WeibullDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double logDensity(double x) {
-        if (x < 0) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
             return Double.NEGATIVE_INFINITY;
         }
 
@@ -118,13 +124,11 @@ public class WeibullDistribution extends AbstractContinuousDistribution {
     /** {@inheritDoc} */
     @Override
     public double cumulativeProbability(double x) {
-        double ret;
-        if (x <= 0) {
-            ret = 0.0;
-        } else {
-            ret = 1.0 - Math.exp(-Math.pow(x / scale, shape));
+        if (x <= SUPPORT_LO) {
+            return 0;
         }
-        return ret;
+
+        return 1 - Math.exp(-Math.pow(x / scale, shape));
     }
 
     /**
@@ -188,7 +192,7 @@ public class WeibullDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportLowerBound() {
-        return 0;
+        return SUPPORT_LO;
     }
 
     /**
@@ -202,7 +206,7 @@ public class WeibullDistribution extends AbstractContinuousDistribution {
      */
     @Override
     public double getSupportUpperBound() {
-        return Double.POSITIVE_INFINITY;
+        return SUPPORT_HI;
     }
 
     /**
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ContinuousDistributionAbstractTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ContinuousDistributionAbstractTest.java
index a7532f2..6375fdc 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ContinuousDistributionAbstractTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/ContinuousDistributionAbstractTest.java
@@ -307,6 +307,22 @@ public abstract class ContinuousDistributionAbstractTest {
         Assertions.assertThrows(IllegalArgumentException.class, () -> distribution.inverseCumulativeProbability(2));
     }
 
+    @Test
+    public void testOutsideSupport() {
+        // Test various quantities when the variable is outside the support.
+        final double lo = distribution.getSupportLowerBound();
+        final double hi = distribution.getSupportUpperBound();
+        final double below = lo - Math.ulp(lo);
+        final double above = hi + Math.ulp(hi);
+
+        Assertions.assertEquals(0d, distribution.density(below), 0d);
+        Assertions.assertEquals(0d, distribution.density(above), 0d);
+        Assertions.assertEquals(Double.NEGATIVE_INFINITY, distribution.logDensity(below), 0d);
+        Assertions.assertEquals(Double.NEGATIVE_INFINITY, distribution.logDensity(above), 0d);
+        Assertions.assertEquals(0d, distribution.cumulativeProbability(below), 0d);
+        Assertions.assertEquals(1d, distribution.cumulativeProbability(above), 0d);
+    }
+
     /**
      * Test sampling
      */