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 2008/07/10 14:40:45 UTC
svn commit: r675551 - in /commons/proper/math/branches/MATH_2_0/src:
java/org/apache/commons/math/ode/nonstiff/ site/xdoc/
test/org/apache/commons/math/ode/nonstiff/
Author: luc
Date: Thu Jul 10 05:40:44 2008
New Revision: 675551
URL: http://svn.apache.org/viewvc?rev=675551&view=rev
Log:
Replaced size adjustment of all steps of fixed steps Runge-Kutta integrators by a truncation of the last step only.
JIRA: MATH-214
Modified:
commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/StepInterpolatorAbstractTest.java
commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java
Modified: commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/java/org/apache/commons/math/ode/nonstiff/RungeKuttaIntegrator.java Thu Jul 10 05:40:44 2008
@@ -22,6 +22,7 @@
import org.apache.commons.math.ode.DerivativeException;
import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math.ode.IntegratorException;
+import org.apache.commons.math.ode.events.CombinedEventsManager;
import org.apache.commons.math.ode.sampling.AbstractStepInterpolator;
import org.apache.commons.math.ode.sampling.DummyStepInterpolator;
import org.apache.commons.math.ode.sampling.StepHandler;
@@ -106,19 +107,20 @@
}
interpolator.storeTime(t0);
- // recompute the step
- long nbStep = Math.max(1l, Math.abs(Math.round((t - t0) / step)));
- boolean lastStep = false;
+ // set up integration control objects
stepStart = t0;
- stepSize = (t - t0) / nbStep;
+ stepSize = step;
for (StepHandler handler : stepHandlers) {
handler.reset();
}
- for (long i = 0; ! lastStep; ++i) {
+ CombinedEventsManager manager = addEndTimeChecker(t, eventsHandlersManager);
+ boolean lastStep = false;
+
+ // main integration loop
+ while (!lastStep) {
interpolator.shift();
- boolean needUpdate = false;
for (boolean loop = true; loop;) {
// first stage
@@ -148,11 +150,10 @@
yTmp[j] = y[j] + stepSize * sum;
}
- // Discrete events handling
+ // discrete events handling
interpolator.storeTime(stepStart + stepSize);
- if (eventsHandlersManager.evaluateStep(interpolator)) {
- needUpdate = true;
- stepSize = eventsHandlersManager.getEventTime() - stepStart;
+ if (manager.evaluateStep(interpolator)) {
+ stepSize = manager.getEventTime() - stepStart;
} else {
loop = false;
}
@@ -162,12 +163,8 @@
// the step has been accepted
final double nextStep = stepStart + stepSize;
System.arraycopy(yTmp, 0, y, 0, y0.length);
- eventsHandlersManager.stepAccepted(nextStep, y);
- if (eventsHandlersManager.stop()) {
- lastStep = true;
- } else {
- lastStep = (i == (nbStep - 1));
- }
+ manager.stepAccepted(nextStep, y);
+ lastStep = manager.stop();
// provide the step data to the step handler
interpolator.storeTime(nextStep);
@@ -176,19 +173,14 @@
}
stepStart = nextStep;
- if (eventsHandlersManager.reset(stepStart, y) && ! lastStep) {
+ if (manager.reset(stepStart, y) && ! lastStep) {
// some events handler has triggered changes that
// invalidate the derivatives, we need to recompute them
equations.computeDerivatives(stepStart, y, yDotK[0]);
}
- if (needUpdate) {
- // an event handler has changed the step
- // we need to recompute stepsize
- nbStep = Math.max(1l, Math.abs(Math.round((t - stepStart) / step)));
- stepSize = (t - stepStart) / nbStep;
- i = -1;
- }
+ // make sure step size is set to default before next step
+ stepSize = step;
}
Modified: commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml (original)
+++ commons/proper/math/branches/MATH_2_0/src/site/xdoc/changes.xml Thu Jul 10 05:40:44 2008
@@ -39,6 +39,10 @@
</properties>
<body>
<release version="2.0" date="TBD" description="TBD">
+ <action dev="luc" type="fix" issue="MATH-214" >
+ Replaced size adjustment of all steps of fixed steps Runge-Kutta integrators by
+ a truncation of the last step only.
+ </action>
<action dev="luc" type="update">
The ODE integrators now support several step handlers at once, instead of just one.
This is more consistent with event handlers management.
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ClassicalRungeKuttaIntegratorTest.java Thu Jul 10 05:40:44 2008
@@ -20,6 +20,7 @@
import junit.framework.*;
import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math.ode.FirstOrderIntegrator;
import org.apache.commons.math.ode.IntegratorException;
import org.apache.commons.math.ode.events.EventHandler;
@@ -191,6 +192,36 @@
private TestProblem3 pb;
}
+ public void testStepSize()
+ throws DerivativeException, IntegratorException {
+ final double step = 1.23456;
+ FirstOrderIntegrator integ = new ClassicalRungeKuttaIntegrator(step);
+ integ.addStepHandler(new StepHandler() {
+ private static final long serialVersionUID = 0L;
+ public void handleStep(StepInterpolator interpolator, boolean isLast) {
+ if (! isLast) {
+ assertEquals(step,
+ interpolator.getCurrentTime() - interpolator.getPreviousTime(),
+ 1.0e-12);
+ }
+ }
+ public boolean requiresDenseOutput() {
+ return false;
+ }
+ public void reset() {
+ }
+ });
+ integ.integrate(new FirstOrderDifferentialEquations() {
+ private static final long serialVersionUID = 0L;
+ public void computeDerivatives(double t, double[] y, double[] dot) {
+ dot[0] = 1.0;
+ }
+ public int getDimension() {
+ return 1;
+ }
+ }, 0.0, new double[] { 0.0 }, 5.0, new double[1]);
+ }
+
public static Test suite() {
return new TestSuite(ClassicalRungeKuttaIntegratorTest.class);
}
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/EulerIntegratorTest.java Thu Jul 10 05:40:44 2008
@@ -20,10 +20,13 @@
import junit.framework.*;
import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math.ode.FirstOrderIntegrator;
import org.apache.commons.math.ode.IntegratorException;
import org.apache.commons.math.ode.events.EventHandler;
import org.apache.commons.math.ode.nonstiff.EulerIntegrator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
public class EulerIntegratorTest
extends TestCase {
@@ -123,7 +126,37 @@
assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
}
-
+
+ public void testStepSize()
+ throws DerivativeException, IntegratorException {
+ final double step = 1.23456;
+ FirstOrderIntegrator integ = new EulerIntegrator(step);
+ integ.addStepHandler(new StepHandler() {
+ private static final long serialVersionUID = 0L;
+ public void handleStep(StepInterpolator interpolator, boolean isLast) {
+ if (! isLast) {
+ assertEquals(step,
+ interpolator.getCurrentTime() - interpolator.getPreviousTime(),
+ 1.0e-12);
+ }
+ }
+ public boolean requiresDenseOutput() {
+ return false;
+ }
+ public void reset() {
+ }
+ });
+ integ.integrate(new FirstOrderDifferentialEquations() {
+ private static final long serialVersionUID = 0L;
+ public void computeDerivatives(double t, double[] y, double[] dot) {
+ dot[0] = 1.0;
+ }
+ public int getDimension() {
+ return 1;
+ }
+ }, 0.0, new double[] { 0.0 }, 5.0, new double[1]);
+ }
+
public static Test suite() {
return new TestSuite(EulerIntegratorTest.class);
}
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/GillIntegratorTest.java Thu Jul 10 05:40:44 2008
@@ -20,6 +20,7 @@
import junit.framework.*;
import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math.ode.FirstOrderIntegrator;
import org.apache.commons.math.ode.IntegratorException;
import org.apache.commons.math.ode.events.EventHandler;
@@ -181,6 +182,36 @@
private TestProblem3 pb;
}
+ public void testStepSize()
+ throws DerivativeException, IntegratorException {
+ final double step = 1.23456;
+ FirstOrderIntegrator integ = new GillIntegrator(step);
+ integ.addStepHandler(new StepHandler() {
+ private static final long serialVersionUID = 0L;
+ public void handleStep(StepInterpolator interpolator, boolean isLast) {
+ if (! isLast) {
+ assertEquals(step,
+ interpolator.getCurrentTime() - interpolator.getPreviousTime(),
+ 1.0e-12);
+ }
+ }
+ public boolean requiresDenseOutput() {
+ return false;
+ }
+ public void reset() {
+ }
+ });
+ integ.integrate(new FirstOrderDifferentialEquations() {
+ private static final long serialVersionUID = 0L;
+ public void computeDerivatives(double t, double[] y, double[] dot) {
+ dot[0] = 1.0;
+ }
+ public int getDimension() {
+ return 1;
+ }
+ }, 0.0, new double[] { 0.0 }, 5.0, new double[1]);
+ }
+
public static Test suite() {
return new TestSuite(GillIntegratorTest.class);
}
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/MidpointIntegratorTest.java Thu Jul 10 05:40:44 2008
@@ -20,10 +20,13 @@
import junit.framework.*;
import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math.ode.FirstOrderIntegrator;
import org.apache.commons.math.ode.IntegratorException;
import org.apache.commons.math.ode.events.EventHandler;
import org.apache.commons.math.ode.nonstiff.MidpointIntegrator;
+import org.apache.commons.math.ode.sampling.StepHandler;
+import org.apache.commons.math.ode.sampling.StepInterpolator;
public class MidpointIntegratorTest
extends TestCase {
@@ -124,6 +127,36 @@
}
+ public void testStepSize()
+ throws DerivativeException, IntegratorException {
+ final double step = 1.23456;
+ FirstOrderIntegrator integ = new MidpointIntegrator(step);
+ integ.addStepHandler(new StepHandler() {
+ private static final long serialVersionUID = 0L;
+ public void handleStep(StepInterpolator interpolator, boolean isLast) {
+ if (! isLast) {
+ assertEquals(step,
+ interpolator.getCurrentTime() - interpolator.getPreviousTime(),
+ 1.0e-12);
+ }
+ }
+ public boolean requiresDenseOutput() {
+ return false;
+ }
+ public void reset() {
+ }
+ });
+ integ.integrate(new FirstOrderDifferentialEquations() {
+ private static final long serialVersionUID = 0L;
+ public void computeDerivatives(double t, double[] y, double[] dot) {
+ dot[0] = 1.0;
+ }
+ public int getDimension() {
+ return 1;
+ }
+ }, 0.0, new double[] { 0.0 }, 5.0, new double[1]);
+ }
+
public static Test suite() {
return new TestSuite(MidpointIntegratorTest.class);
}
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/StepInterpolatorAbstractTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/StepInterpolatorAbstractTest.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/StepInterpolatorAbstractTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/StepInterpolatorAbstractTest.java Thu Jul 10 05:40:44 2008
@@ -48,6 +48,10 @@
final double h = 0.001 * (interpolator.getCurrentTime() - interpolator.getPreviousTime());
final double t = interpolator.getCurrentTime() - 300 * h;
+ if (Math.abs(h) < 10 * Math.ulp(t)) {
+ return;
+ }
+
interpolator.setInterpolatedTime(t - 4 * h);
final double[] yM4h = interpolator.getInterpolatedState().clone();
interpolator.setInterpolatedTime(t - 3 * h);
@@ -73,6 +77,9 @@
32 * (yP3h[i] - yM3h[i]) +
-168 * (yP2h[i] - yM2h[i]) +
672 * (yP1h[i] - yM1h[i])) / (840 * h);
+ if (Math.abs(approYDot - yDot[i]) >= threshold) {
+ System.out.println("gotcha!");
+ }
assertEquals(approYDot, yDot[i], threshold);
}
Modified: commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java
URL: http://svn.apache.org/viewvc/commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java?rev=675551&r1=675550&r2=675551&view=diff
==============================================================================
--- commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java (original)
+++ commons/proper/math/branches/MATH_2_0/src/test/org/apache/commons/math/ode/nonstiff/ThreeEighthesIntegratorTest.java Thu Jul 10 05:40:44 2008
@@ -20,6 +20,7 @@
import junit.framework.*;
import org.apache.commons.math.ode.DerivativeException;
+import org.apache.commons.math.ode.FirstOrderDifferentialEquations;
import org.apache.commons.math.ode.FirstOrderIntegrator;
import org.apache.commons.math.ode.IntegratorException;
import org.apache.commons.math.ode.events.EventHandler;
@@ -178,6 +179,36 @@
}
+ public void testStepSize()
+ throws DerivativeException, IntegratorException {
+ final double step = 1.23456;
+ FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step);
+ integ.addStepHandler(new StepHandler() {
+ private static final long serialVersionUID = 0L;
+ public void handleStep(StepInterpolator interpolator, boolean isLast) {
+ if (! isLast) {
+ assertEquals(step,
+ interpolator.getCurrentTime() - interpolator.getPreviousTime(),
+ 1.0e-12);
+ }
+ }
+ public boolean requiresDenseOutput() {
+ return false;
+ }
+ public void reset() {
+ }
+ });
+ integ.integrate(new FirstOrderDifferentialEquations() {
+ private static final long serialVersionUID = 0L;
+ public void computeDerivatives(double t, double[] y, double[] dot) {
+ dot[0] = 1.0;
+ }
+ public int getDimension() {
+ return 1;
+ }
+ }, 0.0, new double[] { 0.0 }, 5.0, new double[1]);
+ }
+
public static Test suite() {
return new TestSuite(ThreeEighthesIntegratorTest.class);
}