Fixed an infinite loop encountered in some backward integration cases for ODE solvers
git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_0@694197 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
81c6a9a29d
commit
f4c984a31b
|
@ -91,7 +91,7 @@ public class AdamsBashforthIntegrator extends MultistepIntegrator {
|
|||
coeffs[i] = f.doubleValue();
|
||||
}
|
||||
|
||||
this.step = step;
|
||||
this.step = Math.abs(step);
|
||||
|
||||
}
|
||||
|
||||
|
@ -116,7 +116,7 @@ public class AdamsBashforthIntegrator extends MultistepIntegrator {
|
|||
|
||||
// set up integration control objects
|
||||
stepStart = t0;
|
||||
stepSize = step;
|
||||
stepSize = forward ? step : -step;
|
||||
for (StepHandler handler : stepHandlers) {
|
||||
handler.reset();
|
||||
}
|
||||
|
|
|
@ -107,7 +107,7 @@ public class AdamsMoultonIntegrator extends MultistepIntegrator {
|
|||
correctorCoeffs[i] = fCorrector.doubleValue();
|
||||
}
|
||||
|
||||
this.step = step;
|
||||
this.step = Math.abs(step);
|
||||
|
||||
}
|
||||
|
||||
|
@ -132,7 +132,7 @@ public class AdamsMoultonIntegrator extends MultistepIntegrator {
|
|||
|
||||
// set up integration control objects
|
||||
stepStart = t0;
|
||||
stepSize = step;
|
||||
stepSize = forward ? step : -step;
|
||||
for (StepHandler handler : stepHandlers) {
|
||||
handler.reset();
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ public abstract class AdaptiveStepsizeIntegrator
|
|||
|
||||
super(name);
|
||||
|
||||
this.minStep = minStep;
|
||||
this.maxStep = maxStep;
|
||||
this.minStep = Math.abs(minStep);
|
||||
this.maxStep = Math.abs(maxStep);
|
||||
this.initialStep = -1.0;
|
||||
|
||||
this.scalAbsoluteTolerance = scalAbsoluteTolerance;
|
||||
|
|
|
@ -73,7 +73,7 @@ public abstract class RungeKuttaIntegrator extends AbstractIntegrator {
|
|||
this.a = a;
|
||||
this.b = b;
|
||||
this.prototype = prototype;
|
||||
this.step = step;
|
||||
this.step = Math.abs(step);
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
|
@ -109,7 +109,7 @@ public abstract class RungeKuttaIntegrator extends AbstractIntegrator {
|
|||
|
||||
// set up integration control objects
|
||||
stepStart = t0;
|
||||
stepSize = step;
|
||||
stepSize = forward ? step : -step;
|
||||
for (StepHandler handler : stepHandlers) {
|
||||
handler.reset();
|
||||
}
|
||||
|
@ -180,7 +180,7 @@ public abstract class RungeKuttaIntegrator extends AbstractIntegrator {
|
|||
}
|
||||
|
||||
// make sure step size is set to default before next step
|
||||
stepSize = step;
|
||||
stepSize = forward ? step : -step;
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -39,6 +39,9 @@ The <action> type attribute can be add,update,fix,remove.
|
|||
</properties>
|
||||
<body>
|
||||
<release version="2.0" date="TBD" description="TBD">
|
||||
<action dev="luc" type="fix" due-to="Pascal Parraud">
|
||||
Fixed an infinite loop encountered in some backward integration cases for ODE solvers.
|
||||
</action>
|
||||
<action dev="luc" type="add" issue="MATH-222" due-to="Ted Dunning">
|
||||
Added beta distribution.
|
||||
</action>
|
||||
|
|
|
@ -198,7 +198,25 @@ public class AdamsBashforthIntegratorTest
|
|||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-14);
|
||||
|
||||
}
|
||||
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new AdamsBashforthIntegrator(5, step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 8.0e-11);
|
||||
assertTrue(handler.getMaximalValueError() < 8.0e-11);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Adams-Bashforth", integ.getName());
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite(AdamsBashforthIntegratorTest.class);
|
||||
}
|
||||
|
|
|
@ -209,6 +209,24 @@ public class AdamsMoultonIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new AdamsMoultonIntegrator(5, step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 5.0e-10);
|
||||
assertTrue(handler.getMaximalValueError() < 7.0e-10);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Adams-Moulton", integ.getName());
|
||||
}
|
||||
|
||||
public static Test suite() {
|
||||
return new TestSuite(AdamsMoultonIntegratorTest.class);
|
||||
}
|
||||
|
|
|
@ -145,6 +145,24 @@ public class ClassicalRungeKuttaIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 5.0e-10);
|
||||
assertTrue(handler.getMaximalValueError() < 7.0e-10);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("classical Runge-Kutta", integ.getName());
|
||||
}
|
||||
|
||||
public void testKepler()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
|
|
|
@ -101,6 +101,29 @@ public class DormandPrince54IntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double minStep = 0;
|
||||
double maxStep = pb.getFinalTime() - pb.getInitialTime();
|
||||
double scalAbsoluteTolerance = 1.0e-8;
|
||||
double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
|
||||
|
||||
FirstOrderIntegrator integ = new DormandPrince54Integrator(minStep, maxStep,
|
||||
scalAbsoluteTolerance,
|
||||
scalRelativeTolerance);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 2.0e-7);
|
||||
assertTrue(handler.getMaximalValueError() < 2.0e-7);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Dormand-Prince 5(4)", integ.getName());
|
||||
}
|
||||
|
||||
private static class DP54SmallLastHandler implements StepHandler {
|
||||
|
||||
private static final long serialVersionUID = -8168590945325629799L;
|
||||
|
|
|
@ -125,6 +125,29 @@ public class DormandPrince853IntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double minStep = 0;
|
||||
double maxStep = pb.getFinalTime() - pb.getInitialTime();
|
||||
double scalAbsoluteTolerance = 1.0e-8;
|
||||
double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
|
||||
|
||||
FirstOrderIntegrator integ = new DormandPrince853Integrator(minStep, maxStep,
|
||||
scalAbsoluteTolerance,
|
||||
scalRelativeTolerance);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 8.0e-8);
|
||||
assertTrue(handler.getMaximalValueError() < 2.0e-7);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Dormand-Prince 8 (5, 3)", integ.getName());
|
||||
}
|
||||
|
||||
public void testEvents()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
|
|
|
@ -127,6 +127,24 @@ public class EulerIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new EulerIntegrator(step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 0.45);
|
||||
assertTrue(handler.getMaximalValueError() < 0.45);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Euler", integ.getName());
|
||||
}
|
||||
|
||||
public void testStepSize()
|
||||
throws DerivativeException, IntegratorException {
|
||||
final double step = 1.23456;
|
||||
|
|
|
@ -125,6 +125,24 @@ public class GillIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new GillIntegrator(step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 5.0e-10);
|
||||
assertTrue(handler.getMaximalValueError() < 7.0e-10);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Gill", integ.getName());
|
||||
}
|
||||
|
||||
public void testKepler()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
|
|
|
@ -90,6 +90,29 @@ public class GraggBulirschStoerIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double minStep = 0;
|
||||
double maxStep = pb.getFinalTime() - pb.getInitialTime();
|
||||
double scalAbsoluteTolerance = 1.0e-8;
|
||||
double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
|
||||
|
||||
FirstOrderIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep,
|
||||
scalAbsoluteTolerance,
|
||||
scalRelativeTolerance);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 9.0e-10);
|
||||
assertTrue(handler.getMaximalValueError() < 9.0e-10);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Gragg-Bulirsch-Stoer", integ.getName());
|
||||
}
|
||||
|
||||
public void testIncreasingTolerance()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
|
|
|
@ -138,6 +138,29 @@ public class HighamHall54IntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double minStep = 0;
|
||||
double maxStep = pb.getFinalTime() - pb.getInitialTime();
|
||||
double scalAbsoluteTolerance = 1.0e-8;
|
||||
double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
|
||||
|
||||
FirstOrderIntegrator integ = new HighamHall54Integrator(minStep, maxStep,
|
||||
scalAbsoluteTolerance,
|
||||
scalRelativeTolerance);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 5.0e-7);
|
||||
assertTrue(handler.getMaximalValueError() < 5.0e-7);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("Higham-Hall 5(4)", integ.getName());
|
||||
}
|
||||
|
||||
public void testEvents()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
|
|
|
@ -127,6 +127,24 @@ public class MidpointIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new MidpointIntegrator(step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 6.0e-4);
|
||||
assertTrue(handler.getMaximalValueError() < 6.0e-4);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("midpoint", integ.getName());
|
||||
}
|
||||
|
||||
public void testStepSize()
|
||||
throws DerivativeException, IntegratorException {
|
||||
final double step = 1.23456;
|
||||
|
|
|
@ -125,6 +125,24 @@ public class ThreeEighthesIntegratorTest
|
|||
|
||||
}
|
||||
|
||||
public void testBackward()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
TestProblem5 pb = new TestProblem5();
|
||||
double step = Math.abs(pb.getFinalTime() - pb.getInitialTime()) * 0.001;
|
||||
|
||||
FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step);
|
||||
TestProblemHandler handler = new TestProblemHandler(pb, integ);
|
||||
integ.addStepHandler(handler);
|
||||
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
|
||||
pb.getFinalTime(), new double[pb.getDimension()]);
|
||||
|
||||
assertTrue(handler.getLastError() < 5.0e-10);
|
||||
assertTrue(handler.getMaximalValueError() < 7.0e-10);
|
||||
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
|
||||
assertEquals("3/8", integ.getName());
|
||||
}
|
||||
|
||||
public void testKepler()
|
||||
throws DerivativeException, IntegratorException {
|
||||
|
||||
|
|
Loading…
Reference in New Issue