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 2015/12/08 20:34:06 UTC
[1/8] [math] Fixed exception handling for too many iterations in
event search.
Repository: commons-math
Updated Branches:
refs/heads/field-ode d5c183b21 -> b713e4ca0
Fixed exception handling for too many iterations in event search.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/de965cbe
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/de965cbe
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/de965cbe
Branch: refs/heads/field-ode
Commit: de965cbe40791f3a2ef03fc05480d12d37923098
Parents: d5c183b
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 18:07:47 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 18:07:47 2015 +0100
----------------------------------------------------------------------
.../math3/ode/events/FieldEventState.java | 174 ++++++++-----------
1 file changed, 70 insertions(+), 104 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/de965cbe/src/main/java/org/apache/commons/math3/ode/events/FieldEventState.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/events/FieldEventState.java b/src/main/java/org/apache/commons/math3/ode/events/FieldEventState.java
index 044b889..5c22357 100644
--- a/src/main/java/org/apache/commons/math3/ode/events/FieldEventState.java
+++ b/src/main/java/org/apache/commons/math3/ode/events/FieldEventState.java
@@ -191,100 +191,91 @@ public class FieldEventState<T extends RealFieldElement<T>> {
public boolean evaluateStep(final FieldStepInterpolator<T> interpolator)
throws MaxCountExceededException, NoBracketingException {
- try {
- forward = interpolator.isForward();
- final FieldODEStateAndDerivative<T> s1 = interpolator.getCurrentState();
- final T t1 = s1.getTime();
- final T dt = t1.subtract(t0);
- if (dt.abs().subtract(convergence).getReal() < 0) {
- // we cannot do anything on such a small step, don't trigger any events
- return false;
+ forward = interpolator.isForward();
+ final FieldODEStateAndDerivative<T> s1 = interpolator.getCurrentState();
+ final T t1 = s1.getTime();
+ final T dt = t1.subtract(t0);
+ if (dt.abs().subtract(convergence).getReal() < 0) {
+ // we cannot do anything on such a small step, don't trigger any events
+ return false;
+ }
+ final int n = FastMath.max(1, (int) FastMath.ceil(FastMath.abs(dt.getReal()) / maxCheckInterval));
+ final T h = dt.divide(n);
+
+ final RealFieldUnivariateFunction<T> f = new RealFieldUnivariateFunction<T>() {
+ /** {@inheritDoc} */
+ public T value(final T t) {
+ return handler.g(interpolator.getInterpolatedState(t));
}
- final int n = FastMath.max(1, (int) FastMath.ceil(FastMath.abs(dt.getReal()) / maxCheckInterval));
- final T h = dt.divide(n);
-
- final RealFieldUnivariateFunction<T> f = new RealFieldUnivariateFunction<T>() {
- /** {@inheritDoc} */
- public T value(final T t) throws LocalMaxCountExceededException {
- try {
- return handler.g(interpolator.getInterpolatedState(t));
- } catch (MaxCountExceededException mcee) {
- throw new LocalMaxCountExceededException(mcee);
- }
- }
- };
-
- T ta = t0;
- T ga = g0;
- for (int i = 0; i < n; ++i) {
-
- // evaluate handler value at the end of the substep
- final T tb = (i == n - 1) ? t1 : t0.add(h.multiply(i + 1));
- final T gb = handler.g(interpolator.getInterpolatedState(tb));
-
- // check events occurrence
- if (g0Positive ^ (gb.getReal() >= 0)) {
- // there is a sign change: an event is expected during this step
-
- // variation direction, with respect to the integration direction
- increasing = gb.subtract(ga).getReal() >= 0;
-
- // find the event time making sure we select a solution just at or past the exact root
- final T root = forward ?
- solver.solve(maxIterationCount, f, ta, tb, AllowedSolution.RIGHT_SIDE) :
- solver.solve(maxIterationCount, f, tb, ta, AllowedSolution.LEFT_SIDE);
-
- if (previousEventTime != null &&
- root.subtract(ta).abs().subtract(convergence).getReal() <= 0 &&
- root.subtract(previousEventTime).abs().subtract(convergence).getReal() <= 0) {
- // we have either found nothing or found (again ?) a past event,
- // retry the substep excluding this value, and taking care to have the
- // required sign in case the g function is noisy around its zero and
- // crosses the axis several times
- do {
- ta = forward ? ta.add(convergence) : ta.subtract(convergence);
- ga = f.value(ta);
- } while ((g0Positive ^ (ga.getReal() >= 0)) && (forward ^ (ta.subtract(tb).getReal() >= 0)));
-
- if (forward ^ (ta.subtract(tb).getReal() >= 0)) {
- // we were able to skip this spurious root
- --i;
- } else {
- // we can't avoid this root before the end of the step,
- // we have to handle it despite it is close to the former one
- // maybe we have two very close roots
- pendingEventTime = root;
- pendingEvent = true;
- return true;
- }
- } else if (previousEventTime == null ||
- previousEventTime.subtract(root).abs().subtract(convergence).getReal() > 0) {
+ };
+
+ T ta = t0;
+ T ga = g0;
+ for (int i = 0; i < n; ++i) {
+
+ // evaluate handler value at the end of the substep
+ final T tb = (i == n - 1) ? t1 : t0.add(h.multiply(i + 1));
+ final T gb = handler.g(interpolator.getInterpolatedState(tb));
+
+ // check events occurrence
+ if (g0Positive ^ (gb.getReal() >= 0)) {
+ // there is a sign change: an event is expected during this step
+
+ // variation direction, with respect to the integration direction
+ increasing = gb.subtract(ga).getReal() >= 0;
+
+ // find the event time making sure we select a solution just at or past the exact root
+ final T root = forward ?
+ solver.solve(maxIterationCount, f, ta, tb, AllowedSolution.RIGHT_SIDE) :
+ solver.solve(maxIterationCount, f, tb, ta, AllowedSolution.LEFT_SIDE);
+
+ if (previousEventTime != null &&
+ root.subtract(ta).abs().subtract(convergence).getReal() <= 0 &&
+ root.subtract(previousEventTime).abs().subtract(convergence).getReal() <= 0) {
+ // we have either found nothing or found (again ?) a past event,
+ // retry the substep excluding this value, and taking care to have the
+ // required sign in case the g function is noisy around its zero and
+ // crosses the axis several times
+ do {
+ ta = forward ? ta.add(convergence) : ta.subtract(convergence);
+ ga = f.value(ta);
+ } while ((g0Positive ^ (ga.getReal() >= 0)) && (forward ^ (ta.subtract(tb).getReal() >= 0)));
+
+ if (forward ^ (ta.subtract(tb).getReal() >= 0)) {
+ // we were able to skip this spurious root
+ --i;
+ } else {
+ // we can't avoid this root before the end of the step,
+ // we have to handle it despite it is close to the former one
+ // maybe we have two very close roots
pendingEventTime = root;
pendingEvent = true;
return true;
- } else {
- // no sign change: there is no event for now
- ta = tb;
- ga = gb;
}
-
+ } else if (previousEventTime == null ||
+ previousEventTime.subtract(root).abs().subtract(convergence).getReal() > 0) {
+ pendingEventTime = root;
+ pendingEvent = true;
+ return true;
} else {
// no sign change: there is no event for now
ta = tb;
ga = gb;
}
+ } else {
+ // no sign change: there is no event for now
+ ta = tb;
+ ga = gb;
}
- // no event during the whole step
- pendingEvent = false;
- pendingEventTime = null;
- return false;
-
- } catch (LocalMaxCountExceededException lmcee) {
- throw lmcee.getException();
}
+ // no event during the whole step
+ pendingEvent = false;
+ pendingEventTime = null;
+ return false;
+
}
/** Get the occurrence time of the event triggered in the current step.
@@ -350,29 +341,4 @@ public class FieldEventState<T extends RealFieldElement<T>> {
}
- /** Local wrapper to propagate exceptions. */
- private static class LocalMaxCountExceededException extends RuntimeException {
-
- /** Serializable UID. */
- private static final long serialVersionUID = 20151113L;
-
- /** Wrapped exception. */
- private final MaxCountExceededException wrapped;
-
- /** Simple constructor.
- * @param exception exception to wrap
- */
- LocalMaxCountExceededException(final MaxCountExceededException exception) {
- wrapped = exception;
- }
-
- /** Get the wrapped exception.
- * @return wrapped exception
- */
- public MaxCountExceededException getException() {
- return wrapped;
- }
-
- }
-
}
[7/8] [math] Added tests for the Dormand-Prince 5(4) integrator.
Posted by lu...@apache.org.
Added tests for the Dormand-Prince 5(4) integrator.
BEWARE! These test do not pass yet. The integrator is currently not
consistent with the regular double-based integrator.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/d587d2c4
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/d587d2c4
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/d587d2c4
Branch: refs/heads/field-ode
Commit: d587d2c410dcdbf050973bdd3d7e644592f4c21b
Parents: 8f1c2d6
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 20:28:04 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 20:28:04 2015 +0100
----------------------------------------------------------------------
.../DormandPrince54FieldIntegratorTest.java | 93 ++++++++++++++++++++
...ormandPrince54FieldStepInterpolatorTest.java | 49 +++++++++++
2 files changed, 142 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/d587d2c4/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegratorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegratorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegratorTest.java
new file mode 100644
index 0000000..a52e4a5
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegratorTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.util.Decimal64Field;
+import org.junit.Test;
+
+public class DormandPrince54FieldIntegratorTest extends AbstractEmbeddedRungeKuttaFieldIntegratorTest {
+
+ protected <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double scalAbsoluteTolerance, final double scalRelativeTolerance) {
+ return new DormandPrince54FieldIntegrator<T>(field, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+ }
+
+ protected <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) {
+ return new DormandPrince54FieldIntegrator<T>(field, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+ }
+
+ @Test
+ public void testNonFieldIntegratorConsistency() {
+ doTestNonFieldIntegratorConsistency(Decimal64Field.getInstance());
+ }
+
+ @Test
+ public void testSanityChecks() {
+ doTestSanityChecks(Decimal64Field.getInstance());
+ }
+
+ @Test
+ public void testBackward() {
+ doTestBackward(Decimal64Field.getInstance(), 2.0e-7, 2.0e-7, 1.0e-12, "Dormand-Prince 5(4)");
+ }
+
+ @Test
+ public void testKepler() {
+ doTestKepler(Decimal64Field.getInstance(), 7.0e-10);
+ }
+
+ @Override
+ public void testForwardBackwardExceptions() {
+ doTestForwardBackwardExceptions(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testMinStep() {
+ doTestMinStep(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testIncreasingTolerance() {
+ // the 0.7 factor is only valid for this test
+ // and has been obtained from trial and error
+ // there is no general relation between local and global errors
+ doTestIncreasingTolerance(Decimal64Field.getInstance(), 0.7, 1.0e-12);
+ }
+
+ @Override
+ public void testEvents() {
+ doTestEvents(Decimal64Field.getInstance(), 5.0e-6, "Dormand-Prince 5(4)");
+ }
+
+ @Override
+ public void testEventsErrors() {
+ doTestEventsErrors(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testEventsNoConvergence() {
+ doTestEventsNoConvergence(Decimal64Field.getInstance());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/d587d2c4/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java
new file mode 100644
index 0000000..378fbc8
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.ode.FieldEquationsMapper;
+import org.apache.commons.math3.util.Decimal64Field;
+import org.junit.Test;
+
+public class DormandPrince54FieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest {
+
+ protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T>
+ createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) {
+ return new DormandPrince54FieldStepInterpolator<T>(field, forward, mapper);
+ }
+
+ @Test
+ public void interpolationAtBounds() {
+ doInterpolationAtBounds(Decimal64Field.getInstance(), 1.0e-50);
+ }
+
+ @Test
+ public void interpolationInside() {
+ doInterpolationInside(Decimal64Field.getInstance(), 4.0e-13, 2.7e-15);
+ }
+
+ @Test
+ public void nonFieldInterpolatorConsistency() {
+ doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 4.2e-17, 2.3e-16, 6.7e-16, 8.4e-17);
+ }
+
+}
[5/8] [math] Prevent NullPointerException in tests.
Posted by lu...@apache.org.
Prevent NullPointerException in tests.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/a3d10998
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/a3d10998
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/a3d10998
Branch: refs/heads/field-ode
Commit: a3d10998f03bbdaaf4e63e98591f76b8f64fb793
Parents: b9e3ac5
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 20:12:49 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 20:12:49 2015 +0100
----------------------------------------------------------------------
...ractRungeKuttaFieldStepInterpolatorTest.java | 32 +++++++++++++++++---
1 file changed, 27 insertions(+), 5 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/a3d10998/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
index 82e9887..64365b4 100644
--- a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
@@ -22,7 +22,9 @@ import java.lang.reflect.InvocationTargetException;
import org.apache.commons.math3.Field;
import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.ode.AbstractIntegrator;
import org.apache.commons.math3.ode.EquationsMapper;
+import org.apache.commons.math3.ode.ExpandableStatefulODE;
import org.apache.commons.math3.ode.FieldEquationsMapper;
import org.apache.commons.math3.ode.FieldExpandableODE;
import org.apache.commons.math3.ode.FieldFirstOrderDifferentialEquations;
@@ -70,7 +72,7 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
RungeKuttaFieldStepInterpolator<T> interpolator = setUpInterpolator(field,
new SinCos<>(field),
- 0.0, new double[] { 0.0, 1.0 }, 0.125);
+ 0.0, new double[] { 0.0, 1.0 }, 0.0125);
int n = 100;
double maxErrorSin = 0;
@@ -95,9 +97,10 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
double epsilonSin, double epsilonCos,
double epsilonSinDot, double epsilonCosDot) {
+ FieldFirstOrderDifferentialEquations<T> eqn = new SinCos<>(field);
RungeKuttaFieldStepInterpolator<T> fieldInterpolator =
- setUpInterpolator(field, new SinCos<>(field), 0.0, new double[] { 0.0, 1.0 }, 0.125);
- RungeKuttaStepInterpolator regularInterpolator = convertInterpolator(fieldInterpolator);
+ setUpInterpolator(field, eqn, 0.0, new double[] { 0.0, 1.0 }, 0.125);
+ RungeKuttaStepInterpolator regularInterpolator = convertInterpolator(fieldInterpolator, eqn);
int n = 100;
double maxErrorSin = 0;
@@ -185,7 +188,8 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
}
private <T extends RealFieldElement<T>>
- RungeKuttaStepInterpolator convertInterpolator(final RungeKuttaFieldStepInterpolator<T> fieldInterpolator) {
+ RungeKuttaStepInterpolator convertInterpolator(final RungeKuttaFieldStepInterpolator<T> fieldInterpolator,
+ final FieldFirstOrderDifferentialEquations<T> eqn) {
RungeKuttaStepInterpolator regularInterpolator = null;
try {
@@ -225,7 +229,25 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
secondaryMappers[i] = new EquationsMapper(start[i + 1], start[i + 2]);
}
- regularInterpolator.reinitialize(null, y, yDotArray,
+ AbstractIntegrator dummyIntegrator = new AbstractIntegrator("dummy") {
+ @Override
+ public void integrate(ExpandableStatefulODE equations, double t) {
+ Assert.fail("this method should not be called");
+ }
+ @Override
+ public void computeDerivatives(final double t, final double[] y, final double[] yDot) {
+ T fieldT = fieldInterpolator.getField().getZero().add(t);
+ T[] fieldY = MathArrays.buildArray(fieldInterpolator.getField(), y.length);
+ for (int i = 0; i < y.length; ++i) {
+ fieldY[i] = fieldInterpolator.getField().getZero().add(y[i]);
+ }
+ T[] fieldYDot = eqn.computeDerivatives(fieldT, fieldY);
+ for (int i = 0; i < yDot.length; ++i) {
+ yDot[i] = fieldYDot[i].getReal();
+ }
+ }
+ };
+ regularInterpolator.reinitialize(dummyIntegrator, y, yDotArray,
fieldInterpolator.isForward(),
primaryMapper, secondaryMappers);
[4/8] [math] Set up a shared interface for Butcher arrays used by
integrators.
Posted by lu...@apache.org.
Set up a shared interface for Butcher arrays used by integrators.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/b9e3ac55
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/b9e3ac55
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/b9e3ac55
Branch: refs/heads/field-ode
Commit: b9e3ac55df3a51b1a4de65300ff3a9da38f961fe
Parents: a39a852
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 19:14:20 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 19:14:20 2015 +0100
----------------------------------------------------------------------
.../ClassicalRungeKuttaFieldIntegrator.java | 6 +--
.../DormandPrince54FieldIntegrator.java | 6 +--
.../DormandPrince853FieldIntegrator.java | 6 +--
.../DormandPrince853FieldStepInterpolator.java | 2 +-
.../EmbeddedRungeKuttaFieldIntegrator.java | 18 +-------
.../ode/nonstiff/EulerFieldIntegrator.java | 6 +--
.../ode/nonstiff/FieldButcherArrayProvider.java | 46 ++++++++++++++++++++
.../math3/ode/nonstiff/GillFieldIntegrator.java | 6 +--
.../nonstiff/HighamHall54FieldIntegrator.java | 6 +--
.../ode/nonstiff/LutherFieldIntegrator.java | 6 +--
.../ode/nonstiff/MidpointFieldIntegrator.java | 6 +--
.../ode/nonstiff/RungeKuttaFieldIntegrator.java | 18 +-------
.../nonstiff/ThreeEighthesFieldIntegrator.java | 6 +--
...ractRungeKuttaFieldStepInterpolatorTest.java | 28 ++++++------
14 files changed, 91 insertions(+), 75 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java
index e5116e8..057a39d 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/ClassicalRungeKuttaFieldIntegrator.java
@@ -62,7 +62,7 @@ public class ClassicalRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T[] c = MathArrays.buildArray(getField(), 3);
c[0] = getField().getOne().multiply(0.5);
c[1] = c[0];
@@ -72,7 +72,7 @@ public class ClassicalRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T[][] a = MathArrays.buildArray(getField(), 3, -1);
for (int i = 0; i < a.length; ++i) {
a[i] = MathArrays.buildArray(getField(), i + 1);
@@ -88,7 +88,7 @@ public class ClassicalRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 4);
b[0] = fraction(1, 6);
b[1] = fraction(1, 3);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegrator.java
index 2b01bdb..356c165 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince54FieldIntegrator.java
@@ -130,7 +130,7 @@ public class DormandPrince54FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T[] c = MathArrays.buildArray(getField(), 6);
c[0] = fraction(1, 5);
c[1] = fraction(3, 10);
@@ -143,7 +143,7 @@ public class DormandPrince54FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T[][] a = MathArrays.buildArray(getField(), 6, -1);
for (int i = 0; i < a.length; ++i) {
a[i] = MathArrays.buildArray(getField(), i + 1);
@@ -174,7 +174,7 @@ public class DormandPrince54FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 7);
b[0] = fraction( 35, 384);
b[1] = getField().getZero();
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegrator.java
index 86b3844..2c872e8 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegrator.java
@@ -191,7 +191,7 @@ public class DormandPrince853FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T sqrt6 = getField().getOne().multiply(6).sqrt();
@@ -218,7 +218,7 @@ public class DormandPrince853FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T sqrt6 = getField().getOne().multiply(6).sqrt();
@@ -371,7 +371,7 @@ public class DormandPrince853FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 16);
b[ 0] = fraction(104257, 1929240);
b[ 1] = getField().getZero();
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolator.java
index 182d8a6..211f18c 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolator.java
@@ -52,7 +52,7 @@ class DormandPrince853FieldStepInterpolator<T extends RealFieldElement<T>>
super(field, forward, mapper);
// interpolation weights
- d = MathArrays.buildArray(getField(), 4, 16);
+ d = MathArrays.buildArray(getField(), 7, 16);
// this row is the same as the b array
d[0][ 0] = fraction(104257, 1929240);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
index 39a89e1..9a81493 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
@@ -68,7 +68,8 @@ import org.apache.commons.math3.util.MathUtils;
*/
public abstract class EmbeddedRungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
- extends AdaptiveStepsizeFieldIntegrator<T> {
+ extends AdaptiveStepsizeFieldIntegrator<T>
+ implements FieldButcherArrayProvider<T> {
/** Index of the pre-computed derivative for <i>fsal</i> methods. */
private final int fsal;
@@ -180,21 +181,6 @@ public abstract class EmbeddedRungeKuttaFieldIntegrator<T extends RealFieldEleme
return getField().getOne().multiply(p).divide(q);
}
- /** Get the time steps from Butcher array (without the first zero).
- * @return time steps from Butcher array (without the first zero
- */
- protected abstract T[] getC();
-
- /** Get the internal weights from Butcher array (without the first empty row).
- * @return internal weights from Butcher array (without the first empty row)
- */
- protected abstract T[][] getA();
-
- /** Get the external weights for the high order method from Butcher array.
- * @return external weights for the high order method from Butcher array
- */
- protected abstract T[] getB();
-
/** Create an interpolator.
* @param forward integration direction indicator
* @param mapper equations mapper for the all equations
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java
index 798c0e9..f6ee8ff 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/EulerFieldIntegrator.java
@@ -64,19 +64,19 @@ public class EulerFieldIntegrator<T extends RealFieldElement<T>> extends RungeKu
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
return MathArrays.buildArray(getField(), 0);
}
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
return MathArrays.buildArray(getField(), 0, 0);
}
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 1);
b[0] = getField().getOne();
return b;
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/FieldButcherArrayProvider.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/FieldButcherArrayProvider.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/FieldButcherArrayProvider.java
new file mode 100644
index 0000000..b37d4cb
--- /dev/null
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/FieldButcherArrayProvider.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+import org.apache.commons.math3.RealFieldElement;
+
+/** This interface represents an integrator based on Butcher arrays.
+ * @see RungeKuttaFieldIntegrator
+ * @see EmbeddedRungeKuttaFieldIntegrator
+ * @param <T> the type of the field elements
+ * @since 3.6
+ */
+
+public interface FieldButcherArrayProvider<T extends RealFieldElement<T>> {
+
+ /** Get the time steps from Butcher array (without the first zero).
+ * @return time steps from Butcher array (without the first zero
+ */
+ T[] getC();
+
+ /** Get the internal weights from Butcher array (without the first empty row).
+ * @return internal weights from Butcher array (without the first empty row)
+ */
+ T[][] getA();
+
+ /** Get the external weights for the high order method from Butcher array.
+ * @return external weights for the high order method from Butcher array
+ */
+ T[] getB();
+
+}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java
index e627782..4f4868d 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/GillFieldIntegrator.java
@@ -62,7 +62,7 @@ public class GillFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T[] c = MathArrays.buildArray(getField(), 3);
c[0] = fraction(1, 2);
c[1] = c[0];
@@ -72,7 +72,7 @@ public class GillFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T two = getField().getZero().add(2);
final T sqrtTwo = two.sqrt();
@@ -92,7 +92,7 @@ public class GillFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T two = getField().getZero().add(2);
final T sqrtTwo = two.sqrt();
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegrator.java
index 8473892..a186b1d 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegrator.java
@@ -105,7 +105,7 @@ public class HighamHall54FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T[] c = MathArrays.buildArray(getField(), 6);
c[0] = fraction(2, 9);
c[1] = fraction(1, 3);
@@ -118,7 +118,7 @@ public class HighamHall54FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T[][] a = MathArrays.buildArray(getField(), 6, -1);
for (int i = 0; i < a.length; ++i) {
a[i] = MathArrays.buildArray(getField(), i + 1);
@@ -149,7 +149,7 @@ public class HighamHall54FieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 7);
b[0] = fraction( 1, 12);
b[1] = getField().getZero();
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java
index d906703..9adb86b 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/LutherFieldIntegrator.java
@@ -71,7 +71,7 @@ public class LutherFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T q = getField().getZero().add(21).sqrt();
final T[] c = MathArrays.buildArray(getField(), 6);
c[0] = getField().getOne();
@@ -85,7 +85,7 @@ public class LutherFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T q = getField().getZero().add(21).sqrt();
final T[][] a = MathArrays.buildArray(getField(), 6, -1);
for (int i = 0; i < a.length; ++i) {
@@ -117,7 +117,7 @@ public class LutherFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 7);
b[0] = fraction( 1, 20);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java
index d3a1f2f..9ea1a06 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/MidpointFieldIntegrator.java
@@ -59,7 +59,7 @@ public class MidpointFieldIntegrator<T extends RealFieldElement<T>> extends Rung
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T[] c = MathArrays.buildArray(getField(), 1);
c[0] = getField().getOne().multiply(0.5);
return c;
@@ -67,7 +67,7 @@ public class MidpointFieldIntegrator<T extends RealFieldElement<T>> extends Rung
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T[][] a = MathArrays.buildArray(getField(), 1, 1);
a[0][0] = fraction(1, 2);
return a;
@@ -75,7 +75,7 @@ public class MidpointFieldIntegrator<T extends RealFieldElement<T>> extends Rung
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 2);
b[0] = getField().getZero();
b[1] = getField().getOne();
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/RungeKuttaFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/RungeKuttaFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/RungeKuttaFieldIntegrator.java
index befa525..ed0ed77 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/RungeKuttaFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/RungeKuttaFieldIntegrator.java
@@ -58,7 +58,8 @@ import org.apache.commons.math3.util.MathArrays;
*/
public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
- extends AbstractFieldIntegrator<T> {
+ extends AbstractFieldIntegrator<T>
+ implements FieldButcherArrayProvider<T> {
/** Time steps from Butcher array (without the first zero). */
private final T[] c;
@@ -96,21 +97,6 @@ public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>>
return getField().getZero().add(p).divide(q);
}
- /** Get the time steps from Butcher array (without the first zero).
- * @return time steps from Butcher array (without the first zero
- */
- protected abstract T[] getC();
-
- /** Get the internal weights from Butcher array (without the first empty row).
- * @return internal weights from Butcher array (without the first empty row)
- */
- protected abstract T[][] getA();
-
- /** Get the external weights for the high order method from Butcher array.
- * @return external weights for the high order method from Butcher array
- */
- protected abstract T[] getB();
-
/** Create an interpolator.
* @param forward integration direction indicator
* @param mapper equations mapper for the all equations
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java
index d298ff8..482c7d5 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/ThreeEighthesFieldIntegrator.java
@@ -61,7 +61,7 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getC() {
+ public T[] getC() {
final T[] c = MathArrays.buildArray(getField(), 3);
c[0] = fraction(1, 3);
c[1] = c[0].add(c[0]);
@@ -71,7 +71,7 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[][] getA() {
+ public T[][] getA() {
final T[][] a = MathArrays.buildArray(getField(), 3, -1);
for (int i = 0; i < a.length; ++i) {
a[i] = MathArrays.buildArray(getField(), i + 1);
@@ -87,7 +87,7 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>>
/** {@inheritDoc} */
@Override
- protected T[] getB() {
+ public T[] getB() {
final T[] b = MathArrays.buildArray(getField(), 4);
b[0] = fraction(1, 8);
b[1] = fraction(3, 8);
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b9e3ac55/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
index 9f419b9..82e9887 100644
--- a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java
@@ -140,10 +140,10 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
RungeKuttaFieldStepInterpolator<T> interpolator = createInterpolator(field, t1 > t0,
new FieldExpandableODE<T>(eqn).getMapper());
// get the Butcher arrays from the field integrator
- RungeKuttaFieldIntegrator<T> fieldIntegrator = createFieldIntegrator(field, interpolator);
- T[][] a = fieldIntegrator.getA();
- T[] b = fieldIntegrator.getB();
- T[] c = fieldIntegrator.getC();
+ FieldButcherArrayProvider<T> provider = createButcherArrayProvider(field, interpolator);
+ T[][] a = provider.getA();
+ T[] b = provider.getB();
+ T[] c = provider.getC();
// store initial state
T t = field.getZero().add(t0);
@@ -259,25 +259,23 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest {
}
- private <T extends RealFieldElement<T>> RungeKuttaFieldIntegrator<T>
- createFieldIntegrator(final Field<T> field, final RungeKuttaFieldStepInterpolator<T> interpolator) {
- RungeKuttaFieldIntegrator<T> integrator = null;
+ private <T extends RealFieldElement<T>> FieldButcherArrayProvider<T>
+ createButcherArrayProvider(final Field<T> field, final RungeKuttaFieldStepInterpolator<T> provider) {
+ FieldButcherArrayProvider<T> integrator = null;
try {
- String interpolatorName = interpolator.getClass().getName();
+ String interpolatorName = provider.getClass().getName();
String integratorName = interpolatorName.replaceAll("StepInterpolator", "Integrator");
@SuppressWarnings("unchecked")
- Class<RungeKuttaFieldIntegrator<T>> clz = (Class<RungeKuttaFieldIntegrator<T>>) Class.forName(integratorName);
+ Class<FieldButcherArrayProvider<T>> clz = (Class<FieldButcherArrayProvider<T>>) Class.forName(integratorName);
try {
integrator = clz.getConstructor(Field.class, RealFieldElement.class).
- newInstance(field, field.getOne());
+ newInstance(field, field.getOne());
} catch (NoSuchMethodException nsme) {
try {
integrator = clz.getConstructor(Field.class,
- RealFieldElement.class,
- RealFieldElement.class,
- RealFieldElement.class).
- newInstance(field, field.getZero().add(0.001),
- field.getOne(), field.getOne(), field.getOne());
+ Double.TYPE, Double.TYPE,
+ Double.TYPE, Double.TYPE).
+ newInstance(field, 0.001, 1.0, 1.0, 1.0);
} catch (NoSuchMethodException e) {
Assert.fail(e.getLocalizedMessage());
}
[3/8] [math] Set up test framework for field-based embedded
Runge-Kutta integrators.
Posted by lu...@apache.org.
Set up test framework for field-based embedded Runge-Kutta integrators.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/a39a8527
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/a39a8527
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/a39a8527
Branch: refs/heads/field-ode
Commit: a39a8527ddc71711357cc9f1ff84771fe24d0109
Parents: d671ede
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 18:09:41 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 18:09:41 2015 +0100
----------------------------------------------------------------------
...ctEmbeddedRungeKuttaFieldIntegratorTest.java | 445 +++++++++++++++++++
1 file changed, 445 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/a39a8527/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractEmbeddedRungeKuttaFieldIntegratorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractEmbeddedRungeKuttaFieldIntegratorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractEmbeddedRungeKuttaFieldIntegratorTest.java
new file mode 100644
index 0000000..06a05c9
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractEmbeddedRungeKuttaFieldIntegratorTest.java
@@ -0,0 +1,445 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.exception.DimensionMismatchException;
+import org.apache.commons.math3.exception.MaxCountExceededException;
+import org.apache.commons.math3.exception.NoBracketingException;
+import org.apache.commons.math3.exception.NumberIsTooSmallException;
+import org.apache.commons.math3.ode.FieldExpandableODE;
+import org.apache.commons.math3.ode.FieldFirstOrderDifferentialEquations;
+import org.apache.commons.math3.ode.FieldFirstOrderIntegrator;
+import org.apache.commons.math3.ode.FieldODEState;
+import org.apache.commons.math3.ode.FieldODEStateAndDerivative;
+import org.apache.commons.math3.ode.TestFieldProblem1;
+import org.apache.commons.math3.ode.TestFieldProblem3;
+import org.apache.commons.math3.ode.TestFieldProblem4;
+import org.apache.commons.math3.ode.TestFieldProblem5;
+import org.apache.commons.math3.ode.TestFieldProblemHandler;
+import org.apache.commons.math3.ode.events.Action;
+import org.apache.commons.math3.ode.events.FieldEventHandler;
+import org.apache.commons.math3.ode.sampling.FieldStepHandler;
+import org.apache.commons.math3.ode.sampling.FieldStepInterpolator;
+import org.apache.commons.math3.util.FastMath;
+import org.apache.commons.math3.util.MathArrays;
+import org.junit.Assert;
+import org.junit.Test;
+
+public abstract class AbstractEmbeddedRungeKuttaFieldIntegratorTest {
+
+ protected abstract <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double scalAbsoluteTolerance, final double scalRelativeTolerance) ;
+
+ protected abstract <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance);
+
+ @Test
+ public abstract void testNonFieldIntegratorConsistency();
+
+ protected <T extends RealFieldElement<T>> void doTestNonFieldIntegratorConsistency(final Field<T> field) {
+ try {
+
+ // get the Butcher arrays from the field integrator
+ EmbeddedRungeKuttaFieldIntegrator<T> fieldIntegrator = createIntegrator(field, 0.001, 1.0, 1.0, 1.0);
+ T[][] fieldA = fieldIntegrator.getA();
+ T[] fieldB = fieldIntegrator.getB();
+ T[] fieldC = fieldIntegrator.getC();
+
+ String fieldName = fieldIntegrator.getClass().getName();
+ String regularName = fieldName.replaceAll("Field", "");
+
+ // get the Butcher arrays from the regular integrator
+ @SuppressWarnings("unchecked")
+ Class<RungeKuttaIntegrator> c = (Class<RungeKuttaIntegrator>) Class.forName(regularName);
+ java.lang.reflect.Field jlrFieldA = c.getDeclaredField("STATIC_A");
+ jlrFieldA.setAccessible(true);
+ double[][] regularA = (double[][]) jlrFieldA.get(null);
+ java.lang.reflect.Field jlrFieldB = c.getDeclaredField("STATIC_B");
+ jlrFieldB.setAccessible(true);
+ double[] regularB = (double[]) jlrFieldB.get(null);
+ java.lang.reflect.Field jlrFieldC = c.getDeclaredField("STATIC_C");
+ jlrFieldC.setAccessible(true);
+ double[] regularC = (double[]) jlrFieldC.get(null);
+
+ Assert.assertEquals(regularA.length, fieldA.length);
+ for (int i = 0; i < regularA.length; ++i) {
+ checkArray(regularA[i], fieldA[i]);
+ }
+ checkArray(regularB, fieldB);
+ checkArray(regularC, fieldC);
+
+ } catch (ClassNotFoundException cnfe) {
+ Assert.fail(cnfe.getLocalizedMessage());
+ } catch (IllegalAccessException iae) {
+ Assert.fail(iae.getLocalizedMessage());
+ } catch (IllegalArgumentException iae) {
+ Assert.fail(iae.getLocalizedMessage());
+ } catch (SecurityException se) {
+ Assert.fail(se.getLocalizedMessage());
+ } catch (NoSuchFieldException nsfe) {
+ Assert.fail(nsfe.getLocalizedMessage());
+ }
+ }
+
+ private <T extends RealFieldElement<T>> void checkArray(double[] regularArray, T[] fieldArray) {
+ Assert.assertEquals(regularArray.length, fieldArray.length);
+ for (int i = 0; i < regularArray.length; ++i) {
+ if (regularArray[i] == 0) {
+ Assert.assertTrue(0.0 == fieldArray[i].getReal());
+ } else {
+ Assert.assertEquals(regularArray[i], fieldArray[i].getReal(), FastMath.ulp(regularArray[i]));
+ }
+ }
+ }
+
+ @Test
+ public abstract void testForwardBackwardExceptions();
+
+ protected <T extends RealFieldElement<T>> void doTestForwardBackwardExceptions(final Field<T> field) {
+ FieldFirstOrderDifferentialEquations<T> equations = new FieldFirstOrderDifferentialEquations<T>() {
+
+ public int getDimension() {
+ return 1;
+ }
+
+ public void init(T t0, T[] y0, T t) {
+ }
+
+ public T[] computeDerivatives(T t, T[] y) {
+ if (t.getReal() < -0.5) {
+ throw new LocalException();
+ } else {
+ throw new RuntimeException("oops");
+ }
+ }
+ };
+
+ EmbeddedRungeKuttaFieldIntegrator<T> integrator = createIntegrator(field, 0.0, 1.0, 1.0e-10, 1.0e-10);
+
+ try {
+ integrator.integrate(new FieldExpandableODE<>(equations),
+ new FieldODEState<T>(field.getOne().negate(),
+ MathArrays.buildArray(field, 1)),
+ field.getZero());
+ Assert.fail("an exception should have been thrown");
+ } catch(LocalException de) {
+ // expected behavior
+ }
+
+ try {
+ integrator.integrate(new FieldExpandableODE<>(equations),
+ new FieldODEState<T>(field.getZero(),
+ MathArrays.buildArray(field, 1)),
+ field.getOne());
+ Assert.fail("an exception should have been thrown");
+ } catch(RuntimeException de) {
+ // expected behavior
+ }
+ }
+
+ protected static class LocalException extends RuntimeException {
+ private static final long serialVersionUID = 20151208L;
+ }
+
+ @Test(expected=NumberIsTooSmallException.class)
+ public abstract void testMinStep();
+
+ protected <T extends RealFieldElement<T>> void doTestMinStep(final Field<T> field)
+ throws NumberIsTooSmallException {
+
+ TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field);
+ double minStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.1).getReal();
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal();
+ double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 };
+ double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 };
+
+ FieldFirstOrderIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ vecAbsoluteTolerance, vecRelativeTolerance);
+ TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ);
+ integ.addStepHandler(handler);
+ integ.integrate(new FieldExpandableODE<>(pb), pb.getInitialState(), pb.getFinalTime());
+ Assert.fail("an exception should have been thrown");
+
+ }
+
+ @Test
+ public abstract void testIncreasingTolerance();
+
+ protected <T extends RealFieldElement<T>> void doTestIncreasingTolerance(final Field<T> field,
+ double factor,
+ double epsilon) {
+
+ int previousCalls = Integer.MAX_VALUE;
+ for (int i = -12; i < -2; ++i) {
+ TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field);
+ double minStep = 0;
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal();
+ double scalAbsoluteTolerance = FastMath.pow(10.0, i);
+ double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
+
+ FieldFirstOrderIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ scalAbsoluteTolerance, scalRelativeTolerance);
+ TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ);
+ integ.addStepHandler(handler);
+ integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime());
+
+ Assert.assertTrue(handler.getMaximalValueError().getReal() < (factor * scalAbsoluteTolerance));
+ Assert.assertEquals(0, handler.getMaximalTimeError().getReal(), epsilon);
+
+ int calls = pb.getCalls();
+ Assert.assertEquals(integ.getEvaluations(), calls);
+ Assert.assertTrue(calls <= previousCalls);
+ previousCalls = calls;
+
+ }
+
+ }
+
+ @Test
+ public abstract void testEvents();
+
+ protected <T extends RealFieldElement<T>> void doTestEvents(final Field<T> field,
+ final double epsilonMaxValue,
+ final String name) {
+
+ TestFieldProblem4<T> pb = new TestFieldProblem4<T>(field);
+ double minStep = 0;
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal();
+ double scalAbsoluteTolerance = 1.0e-8;
+ double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
+
+ FieldFirstOrderIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ scalAbsoluteTolerance, scalRelativeTolerance);
+ TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ);
+ integ.addStepHandler(handler);
+ FieldEventHandler<T>[] functions = pb.getEventsHandlers();
+ double convergence = 1.0e-8 * maxStep;
+ for (int l = 0; l < functions.length; ++l) {
+ integ.addEventHandler(functions[l], Double.POSITIVE_INFINITY, convergence, 1000);
+ }
+ Assert.assertEquals(functions.length, integ.getEventHandlers().size());
+ integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime());
+
+ Assert.assertEquals(0, handler.getMaximalValueError().getReal(), epsilonMaxValue);
+ Assert.assertEquals(0, handler.getMaximalTimeError().getReal(), convergence);
+ Assert.assertEquals(12.0, handler.getLastTime().getReal(), convergence);
+ Assert.assertEquals(name, integ.getName());
+ integ.clearEventHandlers();
+ Assert.assertEquals(0, integ.getEventHandlers().size());
+
+ }
+
+ @Test(expected=LocalException.class)
+ public abstract void testEventsErrors();
+
+ protected <T extends RealFieldElement<T>> void doTestEventsErrors(final Field<T> field)
+ throws LocalException {
+ final TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field);
+ double minStep = 0;
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal();
+ double scalAbsoluteTolerance = 1.0e-8;
+ double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
+
+ FieldFirstOrderIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ scalAbsoluteTolerance, scalRelativeTolerance);
+ TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ);
+ integ.addStepHandler(handler);
+
+ integ.addEventHandler(new FieldEventHandler<T>() {
+ public void init(FieldODEStateAndDerivative<T> state0, T t) {
+ }
+ public Action eventOccurred(FieldODEStateAndDerivative<T> state, boolean increasing) {
+ return Action.CONTINUE;
+ }
+ public T g(FieldODEStateAndDerivative<T> state) {
+ T middle = pb.getInitialState().getTime().add(pb.getFinalTime()).multiply(0.5);
+ T offset = state.getTime().subtract(middle);
+ if (offset.getReal() > 0) {
+ throw new LocalException();
+ }
+ return offset;
+ }
+ public FieldODEState<T> resetState(FieldODEStateAndDerivative<T> state) {
+ return state;
+ }
+ }, Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 1000);
+
+ integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime());
+
+ }
+
+ @Test
+ public abstract void testEventsNoConvergence();
+
+ protected <T extends RealFieldElement<T>> void doTestEventsNoConvergence(final Field<T> field){
+
+ final TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field);
+ double minStep = 0;
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal();
+ double scalAbsoluteTolerance = 1.0e-8;
+ double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
+
+ FieldFirstOrderIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ scalAbsoluteTolerance, scalRelativeTolerance);
+ TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ);
+ integ.addStepHandler(handler);
+
+ integ.addEventHandler(new FieldEventHandler<T>() {
+ public void init(FieldODEStateAndDerivative<T> state0, T t) {
+ }
+ public Action eventOccurred(FieldODEStateAndDerivative<T> state, boolean increasing) {
+ return Action.CONTINUE;
+ }
+ public T g(FieldODEStateAndDerivative<T> state) {
+ T middle = pb.getInitialState().getTime().add(pb.getFinalTime()).multiply(0.5);
+ T offset = state.getTime().subtract(middle);
+ return (offset.getReal() > 0) ? offset.add(0.5) : offset.subtract(0.5);
+ }
+ public FieldODEState<T> resetState(FieldODEStateAndDerivative<T> state) {
+ return state;
+ }
+ }, Double.POSITIVE_INFINITY, 1.0e-8 * maxStep, 3);
+
+ try {
+ integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime());
+ Assert.fail("an exception should have been thrown");
+ } catch (MaxCountExceededException mcee) {
+ // Expected.
+ }
+
+ }
+
+ @Test
+ public abstract void testSanityChecks();
+
+ protected <T extends RealFieldElement<T>> void doTestSanityChecks(Field<T> field) {
+ TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field);
+ try {
+ EmbeddedRungeKuttaFieldIntegrator<T> integrator = createIntegrator(field, 0,
+ pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(),
+ new double[4], new double[4]);
+ integrator.integrate(new FieldExpandableODE<>(pb),
+ new FieldODEState<T>(pb.getInitialState().getTime(),
+ MathArrays.buildArray(field, 6)),
+ pb.getFinalTime());
+ Assert.fail("an exception should have been thrown");
+ } catch(DimensionMismatchException ie) {
+ }
+ try {
+ EmbeddedRungeKuttaFieldIntegrator<T> integrator =
+ createIntegrator(field, 0,
+ pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(),
+ new double[2], new double[4]);
+ integrator.integrate(new FieldExpandableODE<>(pb), pb.getInitialState(), pb.getFinalTime());
+ Assert.fail("an exception should have been thrown");
+ } catch(DimensionMismatchException ie) {
+ }
+ try {
+ EmbeddedRungeKuttaFieldIntegrator<T> integrator =
+ createIntegrator(field, 0,
+ pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(),
+ new double[4], new double[4]);
+ integrator.integrate(new FieldExpandableODE<>(pb), pb.getInitialState(), pb.getInitialState().getTime());
+ Assert.fail("an exception should have been thrown");
+ } catch(NumberIsTooSmallException ie) {
+ }
+ }
+
+ @Test
+ public abstract void testBackward();
+
+ protected <T extends RealFieldElement<T>> void doTestBackward(Field<T> field,
+ final double espilonLast,
+ final double epsilonMaxValue,
+ final double epsilonMaxTime,
+ final String name)
+ throws DimensionMismatchException, NumberIsTooSmallException,
+ MaxCountExceededException, NoBracketingException {
+
+ TestFieldProblem5<T> pb = new TestFieldProblem5<T>(field);
+ double minStep = 0;
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).abs().getReal();
+ double scalAbsoluteTolerance = 1.0e-8;
+ double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
+
+ EmbeddedRungeKuttaFieldIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ scalAbsoluteTolerance,
+ scalRelativeTolerance);
+ TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ);
+ integ.addStepHandler(handler);
+ integ.integrate(new FieldExpandableODE<>(pb), pb.getInitialState(), pb.getFinalTime());
+
+ Assert.assertEquals(0, handler.getLastError().getReal(), espilonLast);
+ Assert.assertEquals(0, handler.getMaximalValueError().getReal(), epsilonMaxValue);
+ Assert.assertEquals(0, handler.getMaximalTimeError().getReal(), epsilonMaxTime);
+ Assert.assertEquals(name, integ.getName());
+
+ }
+
+ @Test
+ public abstract void testKepler();
+
+ protected <T extends RealFieldElement<T>> void doTestKepler(Field<T> field, double epsilon) {
+
+ final TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field, field.getZero().add(0.9));
+ double minStep = 0;
+ double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal();
+ double[] vecAbsoluteTolerance = { 1.0e-8, 1.0e-8, 1.0e-10, 1.0e-10 };
+ double[] vecRelativeTolerance = { 1.0e-10, 1.0e-10, 1.0e-8, 1.0e-8 };
+
+ FieldFirstOrderIntegrator<T> integ = createIntegrator(field, minStep, maxStep,
+ vecAbsoluteTolerance, vecRelativeTolerance);
+ integ.addStepHandler(new KeplerHandler<T>(pb, epsilon));
+ integ.integrate(new FieldExpandableODE<>(pb), pb.getInitialState(), pb.getFinalTime());
+ }
+
+ private static class KeplerHandler<T extends RealFieldElement<T>> implements FieldStepHandler<T> {
+ private T maxError;
+ private final TestFieldProblem3<T> pb;
+ private final double epsilon;
+ public KeplerHandler(TestFieldProblem3<T> pb, double epsilon) {
+ this.pb = pb;
+ this.epsilon = epsilon;
+ maxError = pb.getField().getZero();
+ }
+ public void init(FieldODEStateAndDerivative<T> state0, T t) {
+ maxError = pb.getField().getZero();
+ }
+ public void handleStep(FieldStepInterpolator<T> interpolator, boolean isLast)
+ throws MaxCountExceededException {
+
+ FieldODEStateAndDerivative<T> current = interpolator.getCurrentState();
+ T[] theoreticalY = pb.computeTheoreticalState(current.getTime());
+ T dx = current.getState()[0].subtract(theoreticalY[0]);
+ T dy = current.getState()[1].subtract(theoreticalY[1]);
+ T error = dx.multiply(dx).add(dy.multiply(dy));
+ if (error.subtract(maxError).getReal() > 0) {
+ maxError = error;
+ }
+ if (isLast) {
+ Assert.assertEquals(0.0, maxError.getReal(), epsilon);
+ }
+ }
+ }
+
+}
[8/8] [math] Added tests for the Dormand-Prince 8(5,3) integrator.
Posted by lu...@apache.org.
Added tests for the Dormand-Prince 8(5,3) integrator.
BEWARE! These test do not pass yet. The integrator is currently not
consistent with the regular double-based integrator.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/b713e4ca
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/b713e4ca
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/b713e4ca
Branch: refs/heads/field-ode
Commit: b713e4ca049989913850bb712cf0cdc344fcab35
Parents: d587d2c
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 20:28:26 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 20:28:26 2015 +0100
----------------------------------------------------------------------
.../DormandPrince853FieldIntegratorTest.java | 93 ++++++++++++++++++++
...rmandPrince853FieldStepInterpolatorTest.java | 49 +++++++++++
2 files changed, 142 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b713e4ca/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegratorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegratorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegratorTest.java
new file mode 100644
index 0000000..61a9fd8
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldIntegratorTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.util.Decimal64Field;
+import org.junit.Test;
+
+public class DormandPrince853FieldIntegratorTest extends AbstractEmbeddedRungeKuttaFieldIntegratorTest {
+
+ protected <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double scalAbsoluteTolerance, final double scalRelativeTolerance) {
+ return new DormandPrince853FieldIntegrator<T>(field, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+ }
+
+ protected <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) {
+ return new DormandPrince853FieldIntegrator<T>(field, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+ }
+
+ @Test
+ public void testNonFieldIntegratorConsistency() {
+ doTestNonFieldIntegratorConsistency(Decimal64Field.getInstance());
+ }
+
+ @Test
+ public void testSanityChecks() {
+ doTestSanityChecks(Decimal64Field.getInstance());
+ }
+
+ @Test
+ public void testBackward() {
+ doTestBackward(Decimal64Field.getInstance(), 1.1e-7, 1.1e-7, 1.0e-12, "Dormand-Prince 8 (5, 3)");
+ }
+
+ @Test
+ public void testKepler() {
+ doTestKepler(Decimal64Field.getInstance(), 2.4e-10);
+ }
+
+ @Override
+ public void testForwardBackwardExceptions() {
+ doTestForwardBackwardExceptions(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testMinStep() {
+ doTestMinStep(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testIncreasingTolerance() {
+ // the 1.3 factor is only valid for this test
+ // and has been obtained from trial and error
+ // there is no general relation between local and global errors
+ doTestIncreasingTolerance(Decimal64Field.getInstance(), 1.3, 1.0e-12);
+ }
+
+ @Override
+ public void testEvents() {
+ doTestEvents(Decimal64Field.getInstance(), 2.1e-7, "Dormand-Prince 8 (5, 3)");
+ }
+
+ @Override
+ public void testEventsErrors() {
+ doTestEventsErrors(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testEventsNoConvergence() {
+ doTestEventsNoConvergence(Decimal64Field.getInstance());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/b713e4ca/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java
new file mode 100644
index 0000000..8153ed3
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.ode.FieldEquationsMapper;
+import org.apache.commons.math3.util.Decimal64Field;
+import org.junit.Test;
+
+public class DormandPrince853FieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest {
+
+ protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T>
+ createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) {
+ return new DormandPrince853FieldStepInterpolator<T>(field, forward, mapper);
+ }
+
+ @Test
+ public void interpolationAtBounds() {
+ doInterpolationAtBounds(Decimal64Field.getInstance(), 1.0e-50);
+ }
+
+ @Test
+ public void interpolationInside() {
+ doInterpolationInside(Decimal64Field.getInstance(), 1.0e-50, 1.0e-50);
+ }
+
+ @Test
+ public void nonFieldInterpolatorConsistency() {
+ doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.0e-50, 1.0e-50, 1.0e-50, 1.0e-50);
+ }
+
+}
[2/8] [math] Fixed state copying after event detection.
Posted by lu...@apache.org.
Fixed state copying after event detection.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/d671edef
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/d671edef
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/d671edef
Branch: refs/heads/field-ode
Commit: d671edefb64cfccfb51fc957b5a94cc26fe57059
Parents: de965cb
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 18:08:31 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 18:08:31 2015 +0100
----------------------------------------------------------------------
.../math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/d671edef/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
----------------------------------------------------------------------
diff --git a/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java b/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
index 5f648f8..39a89e1 100644
--- a/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
+++ b/src/main/java/org/apache/commons/math3/ode/nonstiff/EmbeddedRungeKuttaFieldIntegrator.java
@@ -260,7 +260,8 @@ public abstract class EmbeddedRungeKuttaFieldIntegrator<T extends RealFieldEleme
while (error.subtract(1.0).getReal() >= 0) {
// first stage
- yDotK[0] = stepStart.getDerivative();
+ y = equations.getMapper().mapState(stepStart);
+ yDotK[0] = equations.getMapper().mapDerivative(stepStart);
if (firstTime) {
final T[] scale = MathArrays.buildArray(getField(), mainSetDimension);
@@ -331,7 +332,6 @@ public abstract class EmbeddedRungeKuttaFieldIntegrator<T extends RealFieldEleme
interpolator.storeState(stateTmp);
System.arraycopy(yTmp, 0, y, 0, y0.length);
stepStart = acceptStep(interpolator, finalTime);
- System.arraycopy(y, 0, yTmp, 0, y.length);
if (!isLastStep) {
[6/8] [math] Added tests for the Higham-Hall 5(4) integrator.
Posted by lu...@apache.org.
Added tests for the Higham-Hall 5(4) integrator.
Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo
Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/8f1c2d6a
Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/8f1c2d6a
Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/8f1c2d6a
Branch: refs/heads/field-ode
Commit: 8f1c2d6a5c236e908c4d7ac490847c84113a6427
Parents: a3d1099
Author: Luc Maisonobe <lu...@apache.org>
Authored: Tue Dec 8 20:26:54 2015 +0100
Committer: Luc Maisonobe <lu...@apache.org>
Committed: Tue Dec 8 20:26:54 2015 +0100
----------------------------------------------------------------------
.../HighamHall54FieldIntegratorTest.java | 93 ++++++++++++++++++++
.../HighamHall54FieldStepInterpolatorTest.java | 49 +++++++++++
2 files changed, 142 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/commons-math/blob/8f1c2d6a/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegratorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegratorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegratorTest.java
new file mode 100644
index 0000000..9ac49f4
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldIntegratorTest.java
@@ -0,0 +1,93 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.util.Decimal64Field;
+import org.junit.Test;
+
+public class HighamHall54FieldIntegratorTest extends AbstractEmbeddedRungeKuttaFieldIntegratorTest {
+
+ protected <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double scalAbsoluteTolerance, final double scalRelativeTolerance) {
+ return new HighamHall54FieldIntegrator<T>(field, minStep, maxStep, scalAbsoluteTolerance, scalRelativeTolerance);
+ }
+
+ protected <T extends RealFieldElement<T>> EmbeddedRungeKuttaFieldIntegrator<T>
+ createIntegrator(Field<T> field, final double minStep, final double maxStep,
+ final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance) {
+ return new HighamHall54FieldIntegrator<T>(field, minStep, maxStep, vecAbsoluteTolerance, vecRelativeTolerance);
+ }
+
+ @Test
+ public void testNonFieldIntegratorConsistency() {
+ doTestNonFieldIntegratorConsistency(Decimal64Field.getInstance());
+ }
+
+ @Test
+ public void testSanityChecks() {
+ doTestSanityChecks(Decimal64Field.getInstance());
+ }
+
+ @Test
+ public void testBackward() {
+ doTestBackward(Decimal64Field.getInstance(), 5.0e-7, 5.0e-7, 1.0e-12, "Higham-Hall 5(4)");
+ }
+
+ @Test
+ public void testKepler() {
+ doTestKepler(Decimal64Field.getInstance(), 1.5e-4);
+ }
+
+ @Override
+ public void testForwardBackwardExceptions() {
+ doTestForwardBackwardExceptions(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testMinStep() {
+ doTestMinStep(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testIncreasingTolerance() {
+ // the 1.3 factor is only valid for this test
+ // and has been obtained from trial and error
+ // there is no general relation between local and global errors
+ doTestIncreasingTolerance(Decimal64Field.getInstance(), 1.3, 1.0e-12);
+ }
+
+ @Override
+ public void testEvents() {
+ doTestEvents(Decimal64Field.getInstance(), 1.0e-7, "Higham-Hall 5(4)");
+ }
+
+ @Override
+ public void testEventsErrors() {
+ doTestEventsErrors(Decimal64Field.getInstance());
+ }
+
+ @Override
+ public void testEventsNoConvergence() {
+ doTestEventsNoConvergence(Decimal64Field.getInstance());
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/commons-math/blob/8f1c2d6a/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java
----------------------------------------------------------------------
diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java
new file mode 100644
index 0000000..e66cf48
--- /dev/null
+++ b/src/test/java/org/apache/commons/math3/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java
@@ -0,0 +1,49 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.commons.math3.ode.nonstiff;
+
+
+import org.apache.commons.math3.Field;
+import org.apache.commons.math3.RealFieldElement;
+import org.apache.commons.math3.ode.FieldEquationsMapper;
+import org.apache.commons.math3.util.Decimal64Field;
+import org.junit.Test;
+
+public class HighamHall54FieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest {
+
+ protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T>
+ createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) {
+ return new HighamHall54FieldStepInterpolator<T>(field, forward, mapper);
+ }
+
+ @Test
+ public void interpolationAtBounds() {
+ doInterpolationAtBounds(Decimal64Field.getInstance(), 4.9e-16);
+ }
+
+ @Test
+ public void interpolationInside() {
+ doInterpolationInside(Decimal64Field.getInstance(), 4.0e-13, 2.7e-15);
+ }
+
+ @Test
+ public void nonFieldInterpolatorConsistency() {
+ doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.0e-50, 1.0e-50, 1.0e-50);
+ }
+
+}