From aff82362cf13646b0dfae6375c895df7d5ca6b6b Mon Sep 17 00:00:00 2001 From: Gilles Sadowski Date: Thu, 28 Nov 2013 11:41:12 +0000 Subject: [PATCH] MATH-1067 Avoid infinite recursion. Thanks to Florian Erhard. git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1546350 13f79535-47bb-0310-9956-ffa450edef68 --- src/changes/changes.xml | 3 +++ .../java/org/apache/commons/math3/special/Beta.java | 9 +++++---- .../org/apache/commons/math3/special/BetaTest.java | 13 +++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/changes/changes.xml b/src/changes/changes.xml index 1da919553..4c4dfcc53 100644 --- a/src/changes/changes.xml +++ b/src/changes/changes.xml @@ -51,6 +51,9 @@ If the output is not quite correct, check for invisible trailing spaces! + + Avoid infinite recursion in "Beta.regularizedBeta" (package "o.a.c.m.special"); + Refactoring of curve fitters (package "o.a.c.m.fitting"). diff --git a/src/main/java/org/apache/commons/math3/special/Beta.java b/src/main/java/org/apache/commons/math3/special/Beta.java index c6091b48c..04696f971 100644 --- a/src/main/java/org/apache/commons/math3/special/Beta.java +++ b/src/main/java/org/apache/commons/math3/special/Beta.java @@ -189,11 +189,12 @@ public class Beta { Double.isNaN(b) || x < 0 || x > 1 || - a <= 0.0 || - b <= 0.0) { + a <= 0 || + b <= 0) { ret = Double.NaN; - } else if (x > (a + 1.0) / (a + b + 2.0)) { - ret = 1.0 - regularizedBeta(1.0 - x, b, a, epsilon, maxIterations); + } else if (x > (a + 1) / (2 + b + a) && + 1 - x <= (b + 1) / (2 + b + a)) { + ret = 1 - regularizedBeta(1 - x, b, a, epsilon, maxIterations); } else { ContinuedFraction fraction = new ContinuedFraction() { diff --git a/src/test/java/org/apache/commons/math3/special/BetaTest.java b/src/test/java/org/apache/commons/math3/special/BetaTest.java index fc9ac9c27..f886cea50 100644 --- a/src/test/java/org/apache/commons/math3/special/BetaTest.java +++ b/src/test/java/org/apache/commons/math3/special/BetaTest.java @@ -141,6 +141,19 @@ public class BetaTest { TestUtils.assertEquals(9.999950000166648e-6, actual, 1e-16); } + @Test + public void testMath1067() { + final double x = 0.22580645161290325; + final double a = 64.33333333333334; + final double b = 223; + + try { + final double r = Beta.regularizedBeta(x, a, b, 1e-14, 10000); + } catch (StackOverflowError error) { + Assert.fail("Infinite recursion"); + } + } + @Test public void testLogBetaNanPositive() { testLogBeta(Double.NaN, Double.NaN, 2.0);