Add explicit logDensity computation

Expands the range where computation is possible to allow logDensity(x)
when density(x) == 0 for:

- Logistic
- Nakagami

Added tests to demonstrate this.
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 7bbdebd..f945274 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
@@ -85,6 +85,19 @@
 
     /** {@inheritDoc} */
     @Override
+    public double logDensity(double x) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
+            return Double.NEGATIVE_INFINITY;
+        }
+
+        final double z = oneOverScale * (x - mu);
+        final double v = Math.exp(-z);
+        return -Math.log(scale) - z - 2 * Math.log(1 + v);
+    }
+
+    /** {@inheritDoc} */
+    @Override
     public double cumulativeProbability(double x) {
         final double z = oneOverScale * (x - mu);
         return 1 / (1 + Math.exp(-z));
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 05429d4..db838b2 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
@@ -17,6 +17,7 @@
 package org.apache.commons.statistics.distribution;
 
 import org.apache.commons.numbers.gamma.Gamma;
+import org.apache.commons.numbers.gamma.LogGamma;
 import org.apache.commons.numbers.gamma.RegularizedGamma;
 
 /**
@@ -29,6 +30,8 @@
     private static final double SUPPORT_HI = Double.POSITIVE_INFINITY;
     /** The minimum allowed for the shape parameter. */
     private static final double MIN_SHAPE = 0.5;
+    /** Natural logarithm of 2. */
+    private static final double LN_2 = 0.6931471805599453094172321;
 
     /** The shape parameter. */
     private final double mu;
@@ -88,6 +91,18 @@
 
     /** {@inheritDoc} */
     @Override
+    public double logDensity(double x) {
+        if (x <= SUPPORT_LO ||
+            x >= SUPPORT_HI) {
+            return Double.NEGATIVE_INFINITY;
+        }
+
+        return LN_2 + Math.log(mu) * mu - LogGamma.value(mu) - Math.log(omega) * mu +
+                      Math.log(x) * (2 * mu - 1) - (mu * x * x / omega);
+    }
+
+    /** {@inheritDoc} */
+    @Override
     public double cumulativeProbability(double x) {
         if (x <= SUPPORT_LO) {
             return 0;
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/LogisticDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/LogisticDistributionTest.java
index b367283..25b5c51 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/LogisticDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/LogisticDistributionTest.java
@@ -79,6 +79,16 @@
     //-------------------- Additional test cases -------------------------------
 
     @Test
+    void testExtremeLogDensity() {
+        final double scale = 2.5;
+        final LogisticDistribution dist = new LogisticDistribution(0, scale);
+        final double x = 1e160;
+        Assertions.assertEquals(0.0, dist.density(x));
+        final double expected = -Math.log(scale) - x / scale;
+        Assertions.assertEquals(expected, dist.logDensity(x), Math.abs(expected) * 1e-14);
+    }
+
+    @Test
     void testInverseCumulativeProbabilityExtremes() {
         setInverseCumulativeTestPoints(new double[] {0, 1});
         setInverseCumulativeTestValues(new double[] {Double.NEGATIVE_INFINITY, Double.POSITIVE_INFINITY});
diff --git a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NakagamiDistributionTest.java b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NakagamiDistributionTest.java
index 9382de0..4ff0bba 100644
--- a/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NakagamiDistributionTest.java
+++ b/commons-statistics-distribution/src/test/java/org/apache/commons/statistics/distribution/NakagamiDistributionTest.java
@@ -79,6 +79,15 @@
     //-------------------- Additional test cases -------------------------------
 
     @Test
+    void testExtremeLogDensity() {
+        // XXX: Verify with more test data from a reference distribution
+        final NakagamiDistribution dist = new NakagamiDistribution(0.5, 1);
+        final double x = 50;
+        Assertions.assertEquals(0.0, dist.density(x));
+        Assertions.assertEquals(-1250.22579, dist.logDensity(x), 1e-4);
+    }
+
+    @Test
     void testParameterAccessors() {
         final NakagamiDistribution dist = makeDistribution();
         Assertions.assertEquals(0.5, dist.getShape());