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.
if (f1 * fx < 0) {
// We had [x0..x1]. We update it to [x1, x]. Note that the
// value of x1 has switched to the other bound, thus inverting
// The value of x1 has switched to the other bound, thus inverting
// the interval.
x0 = x1;
f0 = f1;
x1 = x;
f1 = fx;
inverted = !inverted;
} else {
// We had [x0..x1]. We update it to [x0, x].
if (method == Method.ILLINOIS) {
switch (method) {
case ILLINOIS:
f0 *= 0.5;
}
if (method == Method.PEGASUS) {
break;
case PEGASUS:
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();
}
x1 = x;
f1 = fx;
}
// Update from [x0, x1] to [x0, x].
x1 = x;
f1 = fx;
// If the function value of the last approximation is too small,
// 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;
import org.apache.commons.math.analysis.UnivariateRealFunction;
import org.junit.Test;
import org.junit.Assert;
/**
* 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.
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);
}
}