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} */
public abstract void integrate (FirstOrderDifferentialEquations equations,
double t0, double[] y0,
double t, double[] y)
public abstract double integrate (FirstOrderDifferentialEquations equations,
double t0, double[] y0,
double t, double[] y)
throws DerivativeException, IntegratorException;
/** {@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)
* @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
* @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 DerivativeException this exception is propagated to the caller if
* the underlying user function triggers one
*/
public void integrate (FirstOrderDifferentialEquations equations,
double t0, double[] y0,
double t, double[] y)
public double integrate (FirstOrderDifferentialEquations equations,
double t0, double[] y0,
double t, double[] y)
throws DerivativeException, IntegratorException;
/** Get the current value of the step start time t<sub>i</sub>.

View File

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

View File

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

View File

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

View File

@ -39,6 +39,15 @@ 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" 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">
Clarified the ODE package by breaking in into several sub-packages and renaming
classes (SwitchingFunctions/EventHandler, SwitchingFunctionsHandler/CombinedEventsManager)

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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