[MATH-1241] Propagate input value to Gamma#digamma and Gamma#trigamma if the input is not a real value to avoid infinite recursion. Thanks to Aleksei Dievskii.

This commit is contained in:
tn 2015-06-24 15:30:35 +02:00
parent 276e22858c
commit 471e6b078a
3 changed files with 26 additions and 1 deletions

View File

@ -54,6 +54,10 @@ If the output is not quite correct, check for invisible trailing spaces!
</release>
<release version="4.0" date="XXXX-XX-XX" description="">
<action dev="tn" type="fix" issue="MATH-1241" due-to="Aleksei Dievskii"> <!-- backported to 3.6 -->
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.
</action>
<action dev="tn" type="fix" issue="MATH-1232" due-to="Otmar Ertl"> <!-- backported to 3.6 -->
Improved performance of calculating the two-sample Kolmogorov-Smirnov
test statistic.

View File

@ -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);
}

View File

@ -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 <a