diff --git a/src/java/org/apache/commons/math/ode/AdaptiveStepsizeIntegrator.java b/src/java/org/apache/commons/math/ode/AdaptiveStepsizeIntegrator.java
index ad6f0fa14..b3864262f 100644
--- a/src/java/org/apache/commons/math/ode/AdaptiveStepsizeIntegrator.java
+++ b/src/java/org/apache/commons/math/ode/AdaptiveStepsizeIntegrator.java
@@ -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} */
diff --git a/src/java/org/apache/commons/math/ode/FirstOrderIntegrator.java b/src/java/org/apache/commons/math/ode/FirstOrderIntegrator.java
index beaded737..64e265064 100644
--- a/src/java/org/apache/commons/math/ode/FirstOrderIntegrator.java
+++ b/src/java/org/apache/commons/math/ode/FirstOrderIntegrator.java
@@ -96,13 +96,15 @@ public interface FirstOrderIntegrator extends Serializable {
* (can be set to a value smaller than t0
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 ti.
diff --git a/src/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java b/src/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java
index 26addc210..77df0c6b2 100644
--- a/src/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java
+++ b/src/java/org/apache/commons/math/ode/nonstiff/EmbeddedRungeKuttaIntegrator.java
@@ -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;
}
diff --git a/src/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java b/src/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java
index d3fa565eb..c48b3d3c8 100644
--- a/src/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java
+++ b/src/java/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegrator.java
@@ -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. */
diff --git a/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java b/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
index 3403af0a6..087f5aa99 100644
--- a/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
+++ b/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
@@ -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;
}
diff --git a/src/site/xdoc/changes.xml b/src/site/xdoc/changes.xml
index d765cd86b..d085235b6 100644
--- a/src/site/xdoc/changes.xml
+++ b/src/site/xdoc/changes.xml
@@ -39,6 +39,15 @@ The type attribute can be add,update,fix,remove.
+
+ 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).
+
Clarified the ODE package by breaking in into several sub-packages and renaming
classes (SwitchingFunctions/EventHandler, SwitchingFunctionsHandler/CombinedEventsManager)
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java
index d3a6da0e3..4cbdd884e 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java
@@ -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) {
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince54IntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince54IntegratorTest.java
index 4bc1e1cb2..a3717d643 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince54IntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince54IntegratorTest.java
@@ -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 {
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince853IntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince853IntegratorTest.java
index 1d68cd0f9..8ea28e2fa 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince853IntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/DormandPrince853IntegratorTest.java
@@ -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());
}
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java
index 7b9c6b63e..ce9da9ee3 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java
@@ -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) {
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java
index 2621abd27..1ef0d9db0 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java
@@ -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) {
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegratorTest.java
index 4b3ac5dc9..128e80ac8 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/GraggBulirschStoerIntegratorTest.java
@@ -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());
}
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java
index 9e0ff2c08..e77bbc132 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java
@@ -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) {
diff --git a/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java b/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java
index 032e3a9af..f0089fc97 100644
--- a/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java
+++ b/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java
@@ -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) {