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);
   }