Changed return type for FirstOrderIntegrator.integrate() to double

in order to retrieve exact stop time. This allows to handle properly
integration interruption due to an EventHandler instance asking to
stop the integration when its associated event is triggered. The state
was already set to the current state at interruption time, but it was
difficult to get the corresponding time (it involved setting a step
handler monitoring the last step specially).

JIRA: MATH-213


git-svn-id: https://svn.apache.org/repos/asf/commons/proper/math/branches/MATH_2_0@671168 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Luc Maisonobe 2008-06-24 13:38:28 +00:00
parent f11d7217fd
commit 6d4200df71
14 changed files with 69 additions and 37 deletions

View File

@ -330,9 +330,9 @@ public abstract class AdaptiveStepsizeIntegrator
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public abstract void integrate (FirstOrderDifferentialEquations equations, public abstract double integrate (FirstOrderDifferentialEquations equations,
double t0, double[] y0, double t0, double[] y0,
double t, double[] y) double t, double[] y)
throws DerivativeException, IntegratorException; throws DerivativeException, IntegratorException;
/** {@inheritDoc} */ /** {@inheritDoc} */

View File

@ -96,13 +96,15 @@ public interface FirstOrderIntegrator extends Serializable {
* (can be set to a value smaller than <code>t0</code> for backward integration) * (can be set to a value smaller than <code>t0</code> for backward integration)
* @param y placeholder where to put the state vector at each successful * @param y placeholder where to put the state vector at each successful
* step (and hence at the end of integration), can be the same object as y0 * step (and hence at the end of integration), can be the same object as y0
* @return stop time, will be the same as target time if integration reached its
* target, but may be different if some {@link EventHandler} stops it at some point.
* @throws IntegratorException if the integrator cannot perform integration * @throws IntegratorException if the integrator cannot perform integration
* @throws DerivativeException this exception is propagated to the caller if * @throws DerivativeException this exception is propagated to the caller if
* the underlying user function triggers one * the underlying user function triggers one
*/ */
public void integrate (FirstOrderDifferentialEquations equations, public double integrate (FirstOrderDifferentialEquations equations,
double t0, double[] y0, double t0, double[] y0,
double t, double[] y) double t, double[] y)
throws DerivativeException, IntegratorException; throws DerivativeException, IntegratorException;
/** Get the current value of the step start time t<sub>i</sub>. /** Get the current value of the step start time t<sub>i</sub>.

View File

@ -161,9 +161,9 @@ public abstract class EmbeddedRungeKuttaIntegrator
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void integrate(final FirstOrderDifferentialEquations equations, public double integrate(final FirstOrderDifferentialEquations equations,
final double t0, final double[] y0, final double t0, final double[] y0,
final double t, final double[] y) final double t, final double[] y)
throws DerivativeException, IntegratorException { throws DerivativeException, IntegratorException {
sanityChecks(equations, t0, y0, t, y); sanityChecks(equations, t0, y0, t, y);
@ -318,7 +318,9 @@ public abstract class EmbeddedRungeKuttaIntegrator
} while (! lastStep); } while (! lastStep);
final double stopTime = stepStart;
resetInternalState(); resetInternalState();
return stopTime;
} }

View File

@ -508,8 +508,8 @@ public class GraggBulirschStoerIntegrator
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void integrate(final FirstOrderDifferentialEquations equations, public double integrate(final FirstOrderDifferentialEquations equations,
final double t0, final double[] y0, final double t, final double[] y) final double t0, final double[] y0, final double t, final double[] y)
throws DerivativeException, IntegratorException { throws DerivativeException, IntegratorException {
sanityChecks(equations, t0, y0, t, y); sanityChecks(equations, t0, y0, t, y);
@ -941,6 +941,8 @@ public class GraggBulirschStoerIntegrator
} }
return stepStart;
} }
/** maximal order. */ /** maximal order. */

View File

@ -145,9 +145,9 @@ public abstract class RungeKuttaIntegrator
} }
/** {@inheritDoc} */ /** {@inheritDoc} */
public void integrate(final FirstOrderDifferentialEquations equations, public double integrate(final FirstOrderDifferentialEquations equations,
final double t0, final double[] y0, final double t0, final double[] y0,
final double t, final double[] y) final double t, final double[] y)
throws DerivativeException, IntegratorException { throws DerivativeException, IntegratorException {
sanityChecks(equations, t0, y0, t, y); sanityChecks(equations, t0, y0, t, y);
@ -257,7 +257,9 @@ public abstract class RungeKuttaIntegrator
} }
final double stopTime = stepStart;
resetInternalState(); resetInternalState();
return stopTime;
} }

View File

@ -39,6 +39,15 @@ The <action> type attribute can be add,update,fix,remove.
</properties> </properties>
<body> <body>
<release version="2.0" date="TBD" description="TBD"> <release version="2.0" date="TBD" description="TBD">
<action dev="luc" type="fix" issue="MATH-213" >
Changed return type for FirstOrderIntegrator.integrate() to double
in order to retrieve exact stop time. This allows to handle properly
integration interruption due to an EventHandler instance asking to
stop the integration when its associated event is triggered. The state
was already set to the current state at interruption time, but it was
difficult to get the corresponding time (it involved setting a step
handler monitoring the last step specially).
</action>
<action dev="luc" type="update"> <action dev="luc" type="update">
Clarified the ODE package by breaking in into several sub-packages and renaming Clarified the ODE package by breaking in into several sub-packages and renaming
classes (SwitchingFunctions/EventHandler, SwitchingFunctionsHandler/CombinedEventsManager) classes (SwitchingFunctions/EventHandler, SwitchingFunctionsHandler/CombinedEventsManager)

View File

@ -77,8 +77,7 @@ public class ClassicalRungeKuttaIntegratorTest
for (int i = 4; i < 10; ++i) { for (int i = 4; i < 10; ++i) {
TestProblemAbstract pb = (TestProblemAbstract) problems[k].clone(); TestProblemAbstract pb = (TestProblemAbstract) problems[k].clone();
double step = (pb.getFinalTime() - pb.getInitialTime()) double step = (pb.getFinalTime() - pb.getInitialTime()) * Math.pow(2.0, -i);
* Math.pow(2.0, -i);
FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step); FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step);
TestProblemHandler handler = new TestProblemHandler(pb, integ); TestProblemHandler handler = new TestProblemHandler(pb, integ);
@ -89,8 +88,11 @@ public class ClassicalRungeKuttaIntegratorTest
Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
} }
assertEquals(functions.length, integ.getEventsHandlers().size()); assertEquals(functions.length, integ.getEventsHandlers().size());
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]); pb.getFinalTime(), new double[pb.getDimension()]);
if (functions.length == 0) {
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
}
double error = handler.getMaximalValueError(); double error = handler.getMaximalValueError();
if (i > 4) { if (i > 4) {

View File

@ -241,9 +241,9 @@ public class DormandPrince54IntegratorTest
scalAbsoluteTolerance, scalAbsoluteTolerance,
scalRelativeTolerance); scalRelativeTolerance);
integ.setStepHandler(new VariableHandler()); integ.setStepHandler(new VariableHandler());
integ.integrate(pb, double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]);
pb.getFinalTime(), new double[pb.getDimension()]); assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
} }
private static class KeplerHandler implements StepHandler { private static class KeplerHandler implements StepHandler {

View File

@ -191,9 +191,10 @@ public class DormandPrince853IntegratorTest
scalAbsoluteTolerance, scalAbsoluteTolerance,
scalRelativeTolerance); scalRelativeTolerance);
integ.setStepHandler(new VariableHandler()); integ.setStepHandler(new VariableHandler());
integ.integrate(pb, double stopTime = integ.integrate(pb,
pb.getInitialTime(), pb.getInitialState(), pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]); pb.getFinalTime(), new double[pb.getDimension()]);
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
assertEquals("Dormand-Prince 8 (5, 3)", integ.getName()); assertEquals("Dormand-Prince 8 (5, 3)", integ.getName());
} }

View File

@ -66,9 +66,11 @@ public class EulerIntegratorTest
integ.addEventHandler(functions[l], integ.addEventHandler(functions[l],
Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
} }
integ.integrate(pb, double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
pb.getInitialTime(), pb.getInitialState(), pb.getFinalTime(), new double[pb.getDimension()]);
pb.getFinalTime(), new double[pb.getDimension()]); if (functions.length == 0) {
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
}
double error = handler.getMaximalValueError(); double error = handler.getMaximalValueError();
if (i > 4) { if (i > 4) {

View File

@ -68,8 +68,11 @@ public class GillIntegratorTest
integ.addEventHandler(functions[l], integ.addEventHandler(functions[l],
Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
} }
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]); pb.getFinalTime(), new double[pb.getDimension()]);
if (functions.length == 0) {
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
}
double error = handler.getMaximalValueError(); double error = handler.getMaximalValueError();
if (i > 5) { if (i > 5) {

View File

@ -231,9 +231,10 @@ public class GraggBulirschStoerIntegratorTest
new GraggBulirschStoerIntegrator(minStep, maxStep, new GraggBulirschStoerIntegrator(minStep, maxStep,
absTolerance, relTolerance); absTolerance, relTolerance);
integ.setStepHandler(new VariableStepHandler()); integ.setStepHandler(new VariableStepHandler());
integ.integrate(pb, double stopTime = integ.integrate(pb,
pb.getInitialTime(), pb.getInitialState(), pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]); pb.getFinalTime(), new double[pb.getDimension()]);
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
assertEquals("Gragg-Bulirsch-Stoer", integ.getName()); assertEquals("Gragg-Bulirsch-Stoer", integ.getName());
} }

View File

@ -65,9 +65,12 @@ public class MidpointIntegratorTest
integ.addEventHandler(functions[l], integ.addEventHandler(functions[l],
Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
} }
integ.integrate(pb, double stopTime = integ.integrate(pb,
pb.getInitialTime(), pb.getInitialState(), pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]); pb.getFinalTime(), new double[pb.getDimension()]);
if (functions.length == 0) {
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
}
double error = handler.getMaximalValueError(); double error = handler.getMaximalValueError();
if (i > 4) { if (i > 4) {

View File

@ -68,8 +68,11 @@ public class ThreeEighthesIntegratorTest
integ.addEventHandler(functions[l], integ.addEventHandler(functions[l],
Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000); Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
} }
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(), double stopTime = integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
pb.getFinalTime(), new double[pb.getDimension()]); pb.getFinalTime(), new double[pb.getDimension()]);
if (functions.length == 0) {
assertEquals(pb.getFinalTime(), stopTime, 1.0e-10);
}
double error = handler.getMaximalValueError(); double error = handler.getMaximalValueError();
if (i > 4) { if (i > 4) {