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:
Luc Maisonobe 2008-09-11 09:57:11 +00:00
parent 81c6a9a29d
commit f4c984a31b
16 changed files with 231 additions and 10 deletions

View File

@ -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();
}

View File

@ -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();
}

View File

@ -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;

View File

@ -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;
}

View File

@ -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>

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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;

View File

@ -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 {

View File

@ -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 {

View File

@ -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 {

View File

@ -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;

View File

@ -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 {