You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@commons.apache.org by lu...@apache.org on 2013/03/19 15:09:08 UTC
svn commit: r1458294 - in /commons/proper/math/trunk/src: changes/changes.xml
main/java/org/apache/commons/math3/ode/AbstractIntegrator.java
test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java
Author: luc
Date: Tue Mar 19 14:09:08 2013
New Revision: 1458294
URL: http://svn.apache.org/r1458294
Log:
Fixed missing update in ODE event handlers.
When a RESET_STATE was triggered, event states for events not triggered
in the same step were not updated properly.
JIRA: MATH-950
Modified:
commons/proper/math/trunk/src/changes/changes.xml
commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ode/AbstractIntegrator.java
commons/proper/math/trunk/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java
Modified: commons/proper/math/trunk/src/changes/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/changes/changes.xml?rev=1458294&r1=1458293&r2=1458294&view=diff
==============================================================================
--- commons/proper/math/trunk/src/changes/changes.xml (original)
+++ commons/proper/math/trunk/src/changes/changes.xml Tue Mar 19 14:09:08 2013
@@ -55,6 +55,9 @@ This is a minor release: It combines bug
Changes to existing features were made in a backwards-compatible
way such as to allow drop-in replacement of the v3.1[.1] JAR file.
">
+ <action dev="luc" type="fix" issue="MATH-950" >
+ Fixed missing update in ODE event handlers, when a RESET_STATE is triggered.
+ </action>
<action dev="psteitz" type="update" issue="MATH-671">
Made EmpiricalDisribution smoothing kernel pluggable.
</action>
Modified: commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ode/AbstractIntegrator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ode/AbstractIntegrator.java?rev=1458294&r1=1458293&r2=1458294&view=diff
==============================================================================
--- commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ode/AbstractIntegrator.java (original)
+++ commons/proper/math/trunk/src/main/java/org/apache/commons/math3/ode/AbstractIntegrator.java Tue Mar 19 14:09:08 2013
@@ -338,11 +338,15 @@ public abstract class AbstractIntegrator
interpolator.setSoftPreviousTime(previousT);
interpolator.setSoftCurrentTime(eventT);
- // trigger the event
+ // get state at event time
interpolator.setInterpolatedTime(eventT);
final double[] eventY = interpolator.getInterpolatedState().clone();
- currentEvent.stepAccepted(eventT, eventY);
- isLastStep = currentEvent.stop();
+
+ // advance all event states to current time
+ for (final EventState state : eventsStates) {
+ state.stepAccepted(eventT, eventY);
+ isLastStep = isLastStep || state.stop();
+ }
// handle the first part of the step, up to the event
for (final StepHandler handler : stepHandlers) {
@@ -352,21 +356,19 @@ public abstract class AbstractIntegrator
if (isLastStep) {
// the event asked to stop integration
System.arraycopy(eventY, 0, y, 0, y.length);
- for (final EventState remaining : occuringEvents) {
- remaining.stepAccepted(eventT, eventY);
- }
return eventT;
}
- if (currentEvent.reset(eventT, eventY)) {
+ boolean needReset = false;
+ for (final EventState state : eventsStates) {
+ needReset = needReset || state.reset(eventT, eventY);
+ }
+ if (needReset) {
// some event handler has triggered changes that
// invalidate the derivatives, we need to recompute them
System.arraycopy(eventY, 0, y, 0, y.length);
computeDerivatives(eventT, y, yDot);
resetOccurred = true;
- for (final EventState remaining : occuringEvents) {
- remaining.stepAccepted(eventT, eventY);
- }
return eventT;
}
@@ -383,6 +385,7 @@ public abstract class AbstractIntegrator
}
+ // last part of the step, after the last event
interpolator.setInterpolatedTime(currentT);
final double[] currentY = interpolator.getInterpolatedState();
for (final EventState state : eventsStates) {
Modified: commons/proper/math/trunk/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/trunk/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java?rev=1458294&r1=1458293&r2=1458294&view=diff
==============================================================================
--- commons/proper/math/trunk/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java (original)
+++ commons/proper/math/trunk/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853IntegratorTest.java Tue Mar 19 14:09:08 2013
@@ -333,6 +333,73 @@ public class DormandPrince853IntegratorT
Assert.assertEquals(8.0, y[0], 1.0e-12);
}
+ @Test
+ public void testEventsScheduling() {
+
+ FirstOrderDifferentialEquations sincos = new FirstOrderDifferentialEquations() {
+
+ public int getDimension() {
+ return 2;
+ }
+
+ public void computeDerivatives(double t, double[] y, double[] yDot) {
+ yDot[0] = y[1];
+ yDot[1] = -y[0];
+ }
+
+ };
+
+ SchedulingChecker sinChecker = new SchedulingChecker(0); // events at 0, PI, 2PI ...
+ SchedulingChecker cosChecker = new SchedulingChecker(1); // events at PI/2, 3PI/2, 5PI/2 ...
+
+ FirstOrderIntegrator integ =
+ new DormandPrince853Integrator(0.001, 1.0, 1.0e-12, 0.0);
+ integ.addEventHandler(sinChecker, 0.01, 1.0e-7, 100);
+ integ.addStepHandler(sinChecker);
+ integ.addEventHandler(cosChecker, 0.01, 1.0e-7, 100);
+ integ.addStepHandler(cosChecker);
+ double t0 = 0.5;
+ double[] y0 = new double[] { FastMath.sin(t0), FastMath.cos(t0) };
+ double t = 10.0;
+ double[] y = new double[2];
+ integ.integrate(sincos, t0, y0, t, y);
+
+ }
+
+ private static class SchedulingChecker implements StepHandler, EventHandler {
+
+ int index;
+ double tMin;
+
+ public SchedulingChecker(int index) {
+ this.index = index;
+ }
+
+ public void init(double t0, double[] y0, double t) {
+ tMin = t0;
+ }
+
+ public void handleStep(StepInterpolator interpolator, boolean isLast) {
+ tMin = interpolator.getCurrentTime();
+ }
+
+ public double g(double t, double[] y) {
+ // once a step has been handled by handleStep,
+ // events checking should only refer to dates after the step
+ Assert.assertTrue(t >= tMin);
+ return y[index];
+ }
+
+ public Action eventOccurred(double t, double[] y, boolean increasing) {
+ return Action.RESET_STATE;
+ }
+
+ public void resetState(double t, double[] y) {
+ // in fact, we don't need to reset anything for the test
+ }
+
+ }
+
private static class KeplerHandler implements StepHandler {
public KeplerHandler(TestProblem3 pb) {
this.pb = pb;