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.
|
// 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();
|
||||||
}
|
}
|
||||||
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,
|
// 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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue