MATH-631
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:
parent
d451a1fb92
commit
334c01e6eb
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue