diff --git a/src/changes/changes.xml b/src/changes/changes.xml index cb2535171..62f682eb6 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible trailing spaces! + + A "StackOverflowException" was thrown when passing Double.NaN or infinity to "Gamma#digamma(double)" + or "Gamma#trigamma(double)". Now the input value is propagated to the output if it is not a real number. + Improved performance of calculating the two-sample Kolmogorov-Smirnov test statistic. diff --git a/src/main/java/org/apache/commons/math4/special/Gamma.java b/src/main/java/org/apache/commons/math4/special/Gamma.java index eb3fb5b2e..aa0e90c23 100644 --- a/src/main/java/org/apache/commons/math4/special/Gamma.java +++ b/src/main/java/org/apache/commons/math4/special/Gamma.java @@ -442,6 +442,10 @@ public class Gamma { * @since 2.0 */ public static double digamma(double x) { + if (Double.isNaN(x) || Double.isInfinite(x)) { + return x; + } + if (x > 0 && x <= S_LIMIT) { // use method 5 from Bernardo AS103 // accurate to O(x) @@ -472,6 +476,10 @@ public class Gamma { * @since 2.0 */ public static double trigamma(double x) { + if (Double.isNaN(x) || Double.isInfinite(x)) { + return x; + } + if (x > 0 && x <= S_LIMIT) { return 1 / (x * x); } diff --git a/src/test/java/org/apache/commons/math4/special/GammaTest.java b/src/test/java/org/apache/commons/math4/special/GammaTest.java index 70275f34c..35da9fe5e 100644 --- a/src/test/java/org/apache/commons/math4/special/GammaTest.java +++ b/src/test/java/org/apache/commons/math4/special/GammaTest.java @@ -19,7 +19,6 @@ package org.apache.commons.math4.special; import org.apache.commons.math4.TestUtils; import org.apache.commons.math4.exception.NumberIsTooLargeException; import org.apache.commons.math4.exception.NumberIsTooSmallException; -import org.apache.commons.math4.special.Gamma; import org.apache.commons.math4.util.FastMath; import org.junit.Assert; import org.junit.Test; @@ -125,6 +124,13 @@ public class GammaTest { } } + @Test + public void testDigammaNonRealArgs() { + Assert.assertTrue(Double.isNaN(Gamma.digamma(Double.NaN))); + Assert.assertTrue(Double.isInfinite(Gamma.digamma(Double.POSITIVE_INFINITY))); + Assert.assertTrue(Double.isInfinite(Gamma.digamma(Double.NEGATIVE_INFINITY))); + } + @Test public void testTrigamma() { double eps = 1e-8; @@ -151,6 +157,13 @@ public class GammaTest { } } + @Test + public void testTrigammaNonRealArgs() { + Assert.assertTrue(Double.isNaN(Gamma.trigamma(Double.NaN))); + Assert.assertTrue(Double.isInfinite(Gamma.trigamma(Double.POSITIVE_INFINITY))); + Assert.assertTrue(Double.isInfinite(Gamma.trigamma(Double.NEGATIVE_INFINITY))); + } + /** * Reference data for the {@link Gamma#logGamma(double)} function. This data * was generated with the following