Work around infinite loop.


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/trunk@1154614 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Gilles Sadowski 2011-08-06 22:26:55 +00:00
parent d451a1fb92
commit 334c01e6eb
2 changed files with 40 additions and 10 deletions

View File

@ -169,25 +169,37 @@ public abstract class BaseSecantSolver
// Update the bounds with the new approximation. // Update the bounds with the new approximation.
if (f1 * fx < 0) { if (f1 * fx < 0) {
// We had [x0..x1]. We update it to [x1, x]. Note that the // The value of x1 has switched to the other bound, thus inverting
// value of x1 has switched to the other bound, thus inverting
// the interval. // the interval.
x0 = x1; x0 = x1;
f0 = f1; f0 = f1;
x1 = x;
f1 = fx;
inverted = !inverted; inverted = !inverted;
} else { } else {
// We had [x0..x1]. We update it to [x0, x]. switch (method) {
if (method == Method.ILLINOIS) { case ILLINOIS:
f0 *= 0.5; f0 *= 0.5;
} break;
if (method == Method.PEGASUS) { case PEGASUS:
f0 *= f1 / (f1 + fx); f0 *= f1 / (f1 + fx);
break;
case REGULA_FALSI:
if (x == x1) {
final double delta = FastMath.max(rtol * FastMath.abs(x1),
atol);
// Update formula cannot make any progress: Update the
// search interval.
x0 = 0.5 * (x0 + x1 - delta);
f0 = computeObjectiveValue(x0);
} }
break;
default:
// Should never happen.
throw new MathInternalError();
}
}
// Update from [x0, x1] to [x0, x].
x1 = x; x1 = x;
f1 = fx; f1 = fx;
}
// If the function value of the last approximation is too small, // If the function value of the last approximation is too small,
// given the function value accuracy, then we can't get closer to // given the function value accuracy, then we can't get closer to

View File

@ -17,6 +17,10 @@
package org.apache.commons.math.analysis.solvers; package org.apache.commons.math.analysis.solvers;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.junit.Test;
import org.junit.Assert;
/** /**
* Test case for {@link RegulaFalsiSolver Regula Falsi} solver. * Test case for {@link RegulaFalsiSolver Regula Falsi} solver.
* *
@ -35,4 +39,18 @@ public final class RegulaFalsiSolverTest extends BaseSecantSolverAbstractTest {
// even a million iterations. As such, it was disabled. // even a million iterations. As such, it was disabled.
return new int[] {3, 7, 8, 19, 18, 11, 67, 55, 288, 151, -1}; return new int[] {3, 7, 8, 19, 18, 11, 67, 55, 288, 151, -1};
} }
@Test
public void testIssue631() {
final UnivariateRealFunction f = new UnivariateRealFunction() {
@Override
public double value(double x) {
return Math.exp(x) - Math.pow(Math.PI, 3.0);
}
};
final UnivariateRealSolver solver = new RegulaFalsiSolver();
final double root = solver.solve(3624, f, 1, 10);
Assert.assertEquals(3.4341896575482003, root, 1e-15);
}
} }