http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldIntegrator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldIntegrator.java b/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldIntegrator.java index 3a5f9aa..d052f4b 100644 --- a/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldIntegrator.java @@ -99,10 +99,15 @@ public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>> /** Create an interpolator. * @param forward integration direction indicator + * @param yDotK slopes at the intermediate points + * @param globalPreviousState start of the global step + * @param globalCurrentState end of the global step * @param mapper equations mapper for the all equations * @return external weights for the high order method from Butcher array */ - protected abstract RungeKuttaFieldStepInterpolator<T> createInterpolator(boolean forward, + protected abstract RungeKuttaFieldStepInterpolator<T> createInterpolator(boolean forward, T[][] yDotK, + final FieldODEStateAndDerivative<T> globalPreviousState, + final FieldODEStateAndDerivative<T> globalCurrentState, FieldEquationsMapper<T> mapper); /** {@inheritDoc} */ @@ -124,11 +129,6 @@ public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>> final T[][] yDotK = MathArrays.buildArray(getField(), stages, -1); final T[] yTmp = MathArrays.buildArray(getField(), y0.length); - // set up an interpolator sharing the integrator arrays - final RungeKuttaFieldStepInterpolator<T> interpolator = - createInterpolator(forward, equations.getMapper()); - interpolator.storeState(stepStart); - // set up integration control objects if (forward) { if (stepStart.getTime().add(step).subtract(finalTime).getReal() >= 0) { @@ -148,8 +148,6 @@ public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>> isLastStep = false; do { - interpolator.shift(); - // first stage y = equations.getMapper().mapState(stepStart); yDotK[0] = equations.getMapper().mapDerivative(stepStart); @@ -182,16 +180,12 @@ public abstract class RungeKuttaFieldIntegrator<T extends RealFieldElement<T>> final FieldODEStateAndDerivative<T> stateTmp = new FieldODEStateAndDerivative<T>(stepEnd, yTmp, yDotTmp); // discrete events handling - interpolator.setSlopes(yDotK); - interpolator.storeState(stateTmp); System.arraycopy(yTmp, 0, y, 0, y0.length); - stepStart = acceptStep(interpolator, finalTime); + stepStart = acceptStep(createInterpolator(forward, yDotK, stepStart, stateTmp, equations.getMapper()), + finalTime); if (!isLastStep) { - // prepare next step - interpolator.storeState(stepStart); - // stepsize control for next step final T nextT = stepStart.getTime().add(stepSize); final boolean nextIsLast = forward ?
http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldStepInterpolator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldStepInterpolator.java b/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldStepInterpolator.java index 26d8fb9..9595ee2 100644 --- a/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldStepInterpolator.java +++ b/src/main/java/org/apache/commons/math4/ode/nonstiff/RungeKuttaFieldStepInterpolator.java @@ -20,6 +20,7 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.ode.sampling.AbstractFieldStepInterpolator; import org.apache.commons.math4.util.MathArrays; @@ -40,57 +41,63 @@ abstract class RungeKuttaFieldStepInterpolator<T extends RealFieldElement<T>> private final Field<T> field; /** Slopes at the intermediate points. */ - private T[][] yDotK; + private final T[][] yDotK; /** Simple constructor. * @param field field to which the time and state vector elements belong * @param forward integration direction indicator + * @param yDotK slopes at the intermediate points + * @param globalPreviousState start of the global step + * @param globalCurrentState end of the global step + * @param softPreviousState start of the restricted step + * @param softCurrentState end of the restricted step * @param mapper equations mapper for the all equations */ protected RungeKuttaFieldStepInterpolator(final Field<T> field, final boolean forward, + final T[][] yDotK, + final FieldODEStateAndDerivative<T> globalPreviousState, + final FieldODEStateAndDerivative<T> globalCurrentState, + final FieldODEStateAndDerivative<T> softPreviousState, + final FieldODEStateAndDerivative<T> softCurrentState, final FieldEquationsMapper<T> mapper) { - super(forward, mapper); + super(forward, globalPreviousState, globalCurrentState, softPreviousState, softCurrentState, mapper); this.field = field; - this.yDotK = null; - } - - /** Copy constructor. - * <p>The copy is a deep copy: its arrays are separated from the - * original arrays of the instance.</p> - - * @param interpolator interpolator to copy from. - - */ - RungeKuttaFieldStepInterpolator(final RungeKuttaFieldStepInterpolator<T> interpolator) { - - super(interpolator); - field = interpolator.field; - - if (yDotK != null) { - yDotK = MathArrays.buildArray(field, interpolator.yDotK.length, -1); - for (int k = 0; k < yDotK.length; ++k) { - yDotK[k] = interpolator.yDotK[k].clone(); - } - - } else { - yDotK = null; + this.yDotK = MathArrays.buildArray(field, yDotK.length, -1); + for (int i = 0; i < yDotK.length; ++i) { + this.yDotK[i] = yDotK[i].clone(); } - } - /** Get the field to which the time and state vector elements belong. - * @return to which the time and state vector elements belong - */ - protected Field<T> getField() { - return field; + /** {@inheritDoc} */ + protected RungeKuttaFieldStepInterpolator<T> create(boolean newForward, + FieldODEStateAndDerivative<T> newGlobalPreviousState, + FieldODEStateAndDerivative<T> newGlobalCurrentState, + FieldODEStateAndDerivative<T> newSoftPreviousState, + FieldODEStateAndDerivative<T> newSoftCurrentState, + FieldEquationsMapper<T> newMapper) { + return create(field, newForward, yDotK, + newGlobalPreviousState, newGlobalCurrentState, + newSoftPreviousState, newSoftCurrentState, + newMapper); } - /** Store the slopes at the intermediate points. - * @param slopes slopes at the intermediate points + /** Create a new instance. + * @param newField field to which the time and state vector elements belong + * @param newForward integration direction indicator + * @param newYDotK slopes at the intermediate points + * @param newGlobalPreviousState start of the global step + * @param newGlobalCurrentState end of the global step + * @param newSoftPreviousState start of the restricted step + * @param newSoftCurrentState end of the restricted step + * @param newMapper equations mapper for the all equations + * @return a new instance */ - void setSlopes(final T[][] slopes) { - this.yDotK = slopes.clone(); - } + protected abstract RungeKuttaFieldStepInterpolator<T> create(Field<T> newField, boolean newForward, T[][] newYDotK, + FieldODEStateAndDerivative<T> newGlobalPreviousState, + FieldODEStateAndDerivative<T> newGlobalCurrentState, + FieldODEStateAndDerivative<T> newSoftPreviousState, + FieldODEStateAndDerivative<T> newSoftCurrentState, + FieldEquationsMapper<T> newMapper); /** Compute a state by linear combination added to previous state. * @param coefficients coefficients to apply to the method staged derivatives http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldIntegrator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldIntegrator.java b/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldIntegrator.java index b826290..255b2da 100644 --- a/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldIntegrator.java +++ b/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldIntegrator.java @@ -20,6 +20,7 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.MathArrays; /** @@ -99,8 +100,14 @@ public class ThreeEighthesFieldIntegrator<T extends RealFieldElement<T>> /** {@inheritDoc} */ @Override protected ThreeEighthesFieldStepInterpolator<T> - createInterpolator(final boolean forward, final FieldEquationsMapper<T> mapper) { - return new ThreeEighthesFieldStepInterpolator<T>(getField(), forward, mapper); + createInterpolator(final boolean forward, T[][] yDotK, + final FieldODEStateAndDerivative<T> globalPreviousState, + final FieldODEStateAndDerivative<T> globalCurrentState, + final FieldEquationsMapper<T> mapper) { + return new ThreeEighthesFieldStepInterpolator<T>(getField(), forward, yDotK, + globalPreviousState, globalCurrentState, + globalPreviousState, globalCurrentState, + mapper); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolator.java b/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolator.java index bf0ad46..6faffd1 100644 --- a/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolator.java +++ b/src/main/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolator.java @@ -64,35 +64,44 @@ class ThreeEighthesFieldStepInterpolator<T extends RealFieldElement<T>> /** Simple constructor. * @param field field to which the time and state vector elements belong * @param forward integration direction indicator + * @param yDotK slopes at the intermediate points + * @param globalPreviousState start of the global step + * @param globalCurrentState end of the global step + * @param softPreviousState start of the restricted step + * @param softCurrentState end of the restricted step * @param mapper equations mapper for the all equations */ ThreeEighthesFieldStepInterpolator(final Field<T> field, final boolean forward, + final T[][] yDotK, + final FieldODEStateAndDerivative<T> globalPreviousState, + final FieldODEStateAndDerivative<T> globalCurrentState, + final FieldODEStateAndDerivative<T> softPreviousState, + final FieldODEStateAndDerivative<T> softCurrentState, final FieldEquationsMapper<T> mapper) { - super(field, forward, mapper); - } - - /** Copy constructor. - * @param interpolator interpolator to copy from. The copy is a deep - * copy: its arrays are separated from the original arrays of the - * instance - */ - ThreeEighthesFieldStepInterpolator(final ThreeEighthesFieldStepInterpolator<T> interpolator) { - super(interpolator); + super(field, forward, yDotK, + globalPreviousState, globalCurrentState, softPreviousState, softCurrentState, + mapper); } /** {@inheritDoc} */ - @Override - protected ThreeEighthesFieldStepInterpolator<T> doCopy() { - return new ThreeEighthesFieldStepInterpolator<T>(this); + protected ThreeEighthesFieldStepInterpolator<T> create(final Field<T> newField, final boolean newForward, final T[][] newYDotK, + final FieldODEStateAndDerivative<T> newGlobalPreviousState, + final FieldODEStateAndDerivative<T> newGlobalCurrentState, + final FieldODEStateAndDerivative<T> newSoftPreviousState, + final FieldODEStateAndDerivative<T> newSoftCurrentState, + final FieldEquationsMapper<T> newMapper) { + return new ThreeEighthesFieldStepInterpolator<T>(newField, newForward, newYDotK, + newGlobalPreviousState, newGlobalCurrentState, + newSoftPreviousState, newSoftCurrentState, + newMapper); } - /** {@inheritDoc} */ @SuppressWarnings("unchecked") @Override protected FieldODEStateAndDerivative<T> computeInterpolatedStateAndDerivatives(final FieldEquationsMapper<T> mapper, final T time, final T theta, - final T oneMinusThetaH) { + final T thetaH, final T oneMinusThetaH) { final T coeffDot3 = theta.multiply(0.75); final T coeffDot1 = coeffDot3.multiply(theta.multiply(4).subtract(5)).add(1); @@ -102,7 +111,7 @@ class ThreeEighthesFieldStepInterpolator<T extends RealFieldElement<T>> final T[] interpolatedDerivatives; if (getGlobalPreviousState() != null && theta.getReal() <= 0.5) { - final T s = theta.multiply(h).divide(8); + final T s = thetaH.divide(8); final T fourTheta2 = theta.multiply(theta).multiply(4); final T coeff1 = s.multiply(fourTheta2.multiply(2).subtract(theta.multiply(15)).add(8)); final T coeff2 = s.multiply(theta.multiply(5).subtract(fourTheta2)).multiply(3); http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/main/java/org/apache/commons/math4/ode/sampling/AbstractFieldStepInterpolator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/ode/sampling/AbstractFieldStepInterpolator.java b/src/main/java/org/apache/commons/math4/ode/sampling/AbstractFieldStepInterpolator.java index 00740f4..0486cef 100644 --- a/src/main/java/org/apache/commons/math4/ode/sampling/AbstractFieldStepInterpolator.java +++ b/src/main/java/org/apache/commons/math4/ode/sampling/AbstractFieldStepInterpolator.java @@ -40,118 +40,76 @@ import org.apache.commons.math4.ode.FieldODEStateAndDerivative; public abstract class AbstractFieldStepInterpolator<T extends RealFieldElement<T>> implements FieldStepInterpolator<T> { - /** Current time step. */ - protected T h; - /** Global previous state. */ - private FieldODEStateAndDerivative<T> globalPreviousState; + private final FieldODEStateAndDerivative<T> globalPreviousState; /** Global current state. */ - private FieldODEStateAndDerivative<T> globalCurrentState; + private final FieldODEStateAndDerivative<T> globalCurrentState; /** Soft previous state. */ - private FieldODEStateAndDerivative<T> softPreviousState; + private final FieldODEStateAndDerivative<T> softPreviousState; /** Soft current state. */ - private FieldODEStateAndDerivative<T> softCurrentState; + private final FieldODEStateAndDerivative<T> softCurrentState; /** integration direction. */ - private boolean forward; + private final boolean forward; /** Mapper for ODE equations primary and secondary components. */ private FieldEquationsMapper<T> mapper; /** Simple constructor. * @param isForward integration direction indicator + * @param globalPreviousState start of the global step + * @param globalCurrentState end of the global step + * @param softPreviousState start of the restricted step + * @param softCurrentState end of the restricted step * @param equationsMapper mapper for ODE equations primary and secondary components */ protected AbstractFieldStepInterpolator(final boolean isForward, + final FieldODEStateAndDerivative<T> globalPreviousState, + final FieldODEStateAndDerivative<T> globalCurrentState, + final FieldODEStateAndDerivative<T> softPreviousState, + final FieldODEStateAndDerivative<T> softCurrentState, final FieldEquationsMapper<T> equationsMapper) { - globalPreviousState = null; - globalCurrentState = null; - softPreviousState = null; - softCurrentState = null; - h = null; - this.forward = isForward; - this.mapper = equationsMapper; - } - - /** Copy constructor. - * <p>The copy is a deep copy: its arrays are separated from the - * original arrays of the instance.</p> - * @param interpolator interpolator to copy from. - */ - protected AbstractFieldStepInterpolator(final AbstractFieldStepInterpolator<T> interpolator) { - - globalPreviousState = interpolator.globalPreviousState; - globalCurrentState = interpolator.globalCurrentState; - softPreviousState = interpolator.softPreviousState; - softCurrentState = interpolator.softCurrentState; - h = interpolator.h; - forward = interpolator.forward; - mapper = interpolator.mapper; - - } - - /** {@inheritDoc} */ - public FieldStepInterpolator<T> copy() throws MaxCountExceededException { - - // create the new independent instance - return doCopy(); - - } - - /** Really copy the instance. - * @return a copy of the instance - */ - protected abstract FieldStepInterpolator<T> doCopy(); - - /** Shift one step forward. - * Copy the current time into the previous time, hence preparing the - * interpolator for future calls to {@link #storeTime storeTime} - */ - public void shift() { - globalPreviousState = globalCurrentState; - softPreviousState = globalPreviousState; - softCurrentState = globalCurrentState; - } - - /** Store the current step state. - * @param state current state - */ - public void storeState(final FieldODEStateAndDerivative<T> state) { - globalCurrentState = state; - softCurrentState = globalCurrentState; - if (globalPreviousState != null) { - h = globalCurrentState.getTime().subtract(globalPreviousState.getTime()); - } + this.forward = isForward; + this.globalPreviousState = globalPreviousState; + this.globalCurrentState = globalCurrentState; + this.softPreviousState = softPreviousState; + this.softCurrentState = softCurrentState; + this.mapper = equationsMapper; } - /** Restrict step range to a limited part of the global step. + /** Create a new restricted version of the instance. * <p> - * This method can be used to restrict a step and make it appear - * as if the original step was smaller. Calling this method - * <em>only</em> changes the value returned by {@link #getPreviousState()}, - * it does not change any other property + * The instance is not changed at all. * </p> - * @param softPreviousState start of the restricted step + * @param previousState start of the restricted step + * @param currentState end of the restricted step + * @return restricted version of the instance + * @see #getPreviousState() + * @see #getCurrentState() */ - public void setSoftPreviousState(final FieldODEStateAndDerivative<T> softPreviousState) { - this.softPreviousState = softPreviousState; + public AbstractFieldStepInterpolator<T> restrictStep(final FieldODEStateAndDerivative<T> previousState, + final FieldODEStateAndDerivative<T> currentState) { + return create(forward, globalPreviousState, globalCurrentState, previousState, currentState, mapper); } - /** Restrict step range to a limited part of the global step. - * <p> - * This method can be used to restrict a step and make it appear - * as if the original step was smaller. Calling this method - * <em>only</em> changes the value returned by {@link #getCurrentState()}, - * it does not change any other property - * </p> - * @param softCurrentState end of the restricted step + /** Create a new instance. + * @param newForward integration direction indicator + * @param newGlobalPreviousState start of the global step + * @param newGlobalCurrentState end of the global step + * @param newSoftPreviousState start of the restricted step + * @param newSoftCurrentState end of the restricted step + * @param newMapper equations mapper for the all equations + * @return a new instance */ - public void setSoftCurrentState(final FieldODEStateAndDerivative<T> softCurrentState) { - this.softCurrentState = softCurrentState; - } + protected abstract AbstractFieldStepInterpolator<T> create(boolean newForward, + FieldODEStateAndDerivative<T> newGlobalPreviousState, + FieldODEStateAndDerivative<T> newGlobalCurrentState, + FieldODEStateAndDerivative<T> newSoftPreviousState, + FieldODEStateAndDerivative<T> newSoftCurrentState, + FieldEquationsMapper<T> newMapper); /** * Get the previous global grid point state. @@ -169,25 +127,22 @@ public abstract class AbstractFieldStepInterpolator<T extends RealFieldElement<T return globalCurrentState; } - /** {@inheritDoc} - * @see #setSoftPreviousState(FieldODEStateAndDerivative) - */ + /** {@inheritDoc} */ public FieldODEStateAndDerivative<T> getPreviousState() { return softPreviousState; } - /** {@inheritDoc} - * @see #setSoftCurrentState(FieldODEStateAndDerivative) - */ + /** {@inheritDoc} */ public FieldODEStateAndDerivative<T> getCurrentState() { return softCurrentState; } /** {@inheritDoc} */ public FieldODEStateAndDerivative<T> getInterpolatedState(final T time) { + final T thetaH = time.subtract(globalPreviousState.getTime()); final T oneMinusThetaH = globalCurrentState.getTime().subtract(time); - final T theta = (h.getReal() == 0) ? h.getField().getZero() : h.subtract(oneMinusThetaH).divide(h); - return computeInterpolatedStateAndDerivatives(mapper, time, theta, oneMinusThetaH); + final T theta = thetaH.divide(globalCurrentState.getTime().subtract(globalPreviousState.getTime())); + return computeInterpolatedStateAndDerivatives(mapper, time, theta, thetaH, oneMinusThetaH); } /** {@inheritDoc} */ @@ -202,13 +157,15 @@ public abstract class AbstractFieldStepInterpolator<T extends RealFieldElement<T * @param time interpolation time * @param theta normalized interpolation abscissa within the step * (theta is zero at the previous time step and one at the current time step) + * @param thetaH time gap between the previous time and the interpolated time * @param oneMinusThetaH time gap between the interpolated time and * the current time * @return interpolated state and derivatives * @exception MaxCountExceededException if the number of functions evaluations is exceeded */ protected abstract FieldODEStateAndDerivative<T> computeInterpolatedStateAndDerivatives(FieldEquationsMapper<T> equationsMapper, - T time, T theta, T oneMinusThetaH) + T time, T theta, + T thetaH, T oneMinusThetaH) throws MaxCountExceededException; } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/main/java/org/apache/commons/math4/ode/sampling/FieldStepInterpolator.java ---------------------------------------------------------------------- diff --git a/src/main/java/org/apache/commons/math4/ode/sampling/FieldStepInterpolator.java b/src/main/java/org/apache/commons/math4/ode/sampling/FieldStepInterpolator.java index b1e08e3..a68d098 100644 --- a/src/main/java/org/apache/commons/math4/ode/sampling/FieldStepInterpolator.java +++ b/src/main/java/org/apache/commons/math4/ode/sampling/FieldStepInterpolator.java @@ -18,7 +18,6 @@ package org.apache.commons.math4.ode.sampling; import org.apache.commons.math4.RealFieldElement; -import org.apache.commons.math4.exception.MaxCountExceededException; import org.apache.commons.math4.ode.FieldODEStateAndDerivative; /** This interface represents an interpolator over the last step @@ -74,14 +73,4 @@ public interface FieldStepInterpolator<T extends RealFieldElement<T>> { */ boolean isForward(); - /** Copy the instance. - * <p>The copied instance is guaranteed to be independent from the - * original one. Both can be used with different settings for - * interpolated time without any side effect.</p> - * @return a deep copy of the instance, which can be used independently. - * @exception MaxCountExceededException if the number of functions evaluations is exceeded - * during step finalization - */ - FieldStepInterpolator<T> copy() throws MaxCountExceededException; - } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/ContinuousOutputFieldModelTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/ContinuousOutputFieldModelTest.java b/src/test/java/org/apache/commons/math4/ode/ContinuousOutputFieldModelTest.java new file mode 100644 index 0000000..f7bbe5c --- /dev/null +++ b/src/test/java/org/apache/commons/math4/ode/ContinuousOutputFieldModelTest.java @@ -0,0 +1,219 @@ +/* + * 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.math4.ode; + +import java.util.Random; + +import org.apache.commons.math4.Field; +import org.apache.commons.math4.RealFieldElement; +import org.apache.commons.math4.ode.nonstiff.DormandPrince54FieldIntegrator; +import org.apache.commons.math4.ode.nonstiff.DormandPrince853FieldIntegrator; +import org.apache.commons.math4.ode.sampling.DummyFieldStepInterpolator; +import org.apache.commons.math4.ode.sampling.FieldStepInterpolator; +import org.apache.commons.math4.util.Decimal64Field; +import org.apache.commons.math4.util.FastMath; +import org.apache.commons.math4.util.MathArrays; +import org.apache.commons.math4.util.MathUtils; +import org.junit.Assert; +import org.junit.Test; + +public class ContinuousOutputFieldModelTest { + + @Test + public void testBoundaries() { + doTestBoundaries(Decimal64Field.getInstance()); + } + + private <T extends RealFieldElement<T>> void doTestBoundaries(final Field<T> field) { + TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field, field.getZero().add(0.9)); + double minStep = 0; + double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(); + FieldFirstOrderIntegrator<T> integ = new DormandPrince54FieldIntegrator<T>(field, minStep, maxStep, 1.0e-8, 1.0e-8); + integ.addStepHandler(new ContinuousOutputFieldModel<T>()); + integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); + ContinuousOutputFieldModel<T> cm = (ContinuousOutputFieldModel<T>) integ.getStepHandlers().iterator().next(); + cm.getInterpolatedState(pb.getInitialState().getTime().multiply(2).subtract(pb.getFinalTime())); + cm.getInterpolatedState(pb.getFinalTime().multiply(2).subtract(pb.getInitialState().getTime())); + cm.getInterpolatedState(pb.getInitialState().getTime().add(pb.getFinalTime()).multiply(0.5)); + } + + @Test + public void testRandomAccess() { + doTestRandomAccess(Decimal64Field.getInstance()); + } + + private <T extends RealFieldElement<T>> void doTestRandomAccess(final Field<T> field) { + + TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field, field.getZero().add(0.9)); + double minStep = 0; + double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(); + FieldFirstOrderIntegrator<T> integ = new DormandPrince54FieldIntegrator<T>(field, minStep, maxStep, 1.0e-8, 1.0e-8); + ContinuousOutputFieldModel<T> cm = new ContinuousOutputFieldModel<T>(); + integ.addStepHandler(cm); + integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); + + Random random = new Random(347588535632l); + T maxError = field.getZero(); + T maxErrorDot = field.getZero(); + for (int i = 0; i < 1000; ++i) { + double r = random.nextDouble(); + T time = pb.getInitialState().getTime().multiply(r).add(pb.getFinalTime().multiply(1.0 - r)); + FieldODEStateAndDerivative<T> interpolated = cm.getInterpolatedState(time); + T[] theoreticalY = pb.computeTheoreticalState(time); + T[] theoreticalYDot = pb.doComputeDerivatives(time, theoreticalY); + T dx = interpolated.getState()[0].subtract(theoreticalY[0]); + T dy = interpolated.getState()[1].subtract(theoreticalY[1]); + T error = dx.multiply(dx).add(dy.multiply(dy)); + maxError = MathUtils.max(maxError, error); + T dxDot = interpolated.getDerivative()[0].subtract(theoreticalYDot[0]); + T dyDot = interpolated.getDerivative()[1].subtract(theoreticalYDot[1]); + T errorDot = dxDot.multiply(dxDot).add(dyDot.multiply(dyDot)); + maxErrorDot = MathUtils.max(maxErrorDot, errorDot); + } + + Assert.assertEquals(0.0, maxError.getReal(), 1.0e-9); + Assert.assertEquals(0.0, maxErrorDot.getReal(), 4.0e-7); + + } + + @Test + public void testModelsMerging() { + doTestModelsMerging(Decimal64Field.getInstance()); + } + + private <T extends RealFieldElement<T>> void doTestModelsMerging(final Field<T> field) { + + // theoretical solution: y[0] = cos(t), y[1] = sin(t) + FieldFirstOrderDifferentialEquations<T> problem = + new FieldFirstOrderDifferentialEquations<T>() { + public T[] computeDerivatives(T t, T[] y) { + T[] yDot = MathArrays.buildArray(field, 2); + yDot[0] = y[1].negate(); + yDot[1] = y[0]; + return yDot; + } + public int getDimension() { + return 2; + } + public void init(T t0, T[] y0, T finalTime) { + } + }; + + // integrate backward from π to 0; + ContinuousOutputFieldModel<T> cm1 = new ContinuousOutputFieldModel<T>(); + FieldFirstOrderIntegrator<T> integ1 = + new DormandPrince853FieldIntegrator<T>(field, 0, 1.0, 1.0e-8, 1.0e-8); + integ1.addStepHandler(cm1); + T t0 = field.getZero().add(FastMath.PI); + T[] y0 = MathArrays.buildArray(field, 2); + y0[0] = field.getOne().negate(); + y0[1] = field.getZero(); + integ1.integrate(new FieldExpandableODE<T>(problem), + new FieldODEState<T>(t0, y0), + field.getZero()); + + // integrate backward from 2π to π + ContinuousOutputFieldModel<T> cm2 = new ContinuousOutputFieldModel<T>(); + FieldFirstOrderIntegrator<T> integ2 = + new DormandPrince853FieldIntegrator<T>(field, 0, 0.1, 1.0e-12, 1.0e-12); + integ2.addStepHandler(cm2); + t0 = field.getZero().add(2.0 * FastMath.PI); + y0[0] = field.getOne(); + y0[1] = field.getZero(); + integ2.integrate(new FieldExpandableODE<T>(problem), + new FieldODEState<T>(t0, y0), + field.getZero().add(FastMath.PI)); + + // merge the two half circles + ContinuousOutputFieldModel<T> cm = new ContinuousOutputFieldModel<T>(); + cm.append(cm2); + cm.append(new ContinuousOutputFieldModel<T>()); + cm.append(cm1); + + // check circle + Assert.assertEquals(2.0 * FastMath.PI, cm.getInitialTime().getReal(), 1.0e-12); + Assert.assertEquals(0, cm.getFinalTime().getReal(), 1.0e-12); + for (double t = 0; t < 2.0 * FastMath.PI; t += 0.1) { + FieldODEStateAndDerivative<T> interpolated = cm.getInterpolatedState(field.getZero().add(t)); + Assert.assertEquals(FastMath.cos(t), interpolated.getState()[0].getReal(), 1.0e-7); + Assert.assertEquals(FastMath.sin(t), interpolated.getState()[1].getReal(), 1.0e-7); + } + + } + + @Test + public void testErrorConditions() { + doTestErrorConditions(Decimal64Field.getInstance()); + } + + private <T extends RealFieldElement<T>> void doTestErrorConditions(final Field<T> field) { + ContinuousOutputFieldModel<T> cm = new ContinuousOutputFieldModel<T>(); + cm.handleStep(buildInterpolator(field, 0, 1, new double[] { 0.0, 1.0, -2.0 }), true); + + // dimension mismatch + Assert.assertTrue(checkAppendError(field, cm, 1.0, 2.0, new double[] { 0.0, 1.0 })); + + // hole between time ranges + Assert.assertTrue(checkAppendError(field, cm, 10.0, 20.0, new double[] { 0.0, 1.0, -2.0 })); + + // propagation direction mismatch + Assert.assertTrue(checkAppendError(field, cm, 1.0, 0.0, new double[] { 0.0, 1.0, -2.0 })); + + // no errors + Assert.assertFalse(checkAppendError(field, cm, 1.0, 2.0, new double[] { 0.0, 1.0, -2.0 })); + + } + + private <T extends RealFieldElement<T>> boolean checkAppendError(Field<T> field, ContinuousOutputFieldModel<T> cm, + double t0, double t1, double[] y) { + try { + ContinuousOutputFieldModel<T> otherCm = new ContinuousOutputFieldModel<T>(); + otherCm.handleStep(buildInterpolator(field, t0, t1, y), true); + cm.append(otherCm); + } catch(IllegalArgumentException iae) { + return true; // there was an allowable error + } + return false; // no allowable error + } + + private <T extends RealFieldElement<T>> FieldStepInterpolator<T> buildInterpolator(Field<T> field, + double t0, double t1, double[] y) { + T[] fieldY = MathArrays.buildArray(field, y.length); + for (int i = 0; i < y.length; ++i) { + fieldY[i] = field.getZero().add(y[i]); + } + final FieldODEStateAndDerivative<T> s0 = new FieldODEStateAndDerivative<T>(field.getZero().add(t0), fieldY, fieldY); + final FieldODEStateAndDerivative<T> s1 = new FieldODEStateAndDerivative<T>(field.getZero().add(t1), fieldY, fieldY); + final FieldEquationsMapper<T> mapper = new FieldExpandableODE<T>(new FieldFirstOrderDifferentialEquations<T>() { + public int getDimension() { + return s0.getStateDimension(); + } + public void init(T t0, T[] y0, T finalTime) { + } + public T[] computeDerivatives(T t, T[] y) { + return y; + } + }).getMapper(); + return new DummyFieldStepInterpolator<T>(t1 >= t0, s0, s1, s0, s1, mapper); + } + + public void checkValue(double value, double reference) { + Assert.assertTrue(FastMath.abs(value - reference) < 1.0e-10); + } + +} http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java index 4716b81..b670cda 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/AbstractRungeKuttaFieldStepInterpolatorTest.java @@ -18,8 +18,6 @@ package org.apache.commons.math4.ode.nonstiff; -import java.lang.reflect.InvocationTargetException; - import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.AbstractIntegrator; @@ -38,7 +36,15 @@ import org.junit.Test; public abstract class AbstractRungeKuttaFieldStepInterpolatorTest { protected abstract <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper); + + protected abstract <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field); @Test public abstract void interpolationAtBounds(); @@ -140,10 +146,8 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest { final double t0, final double[] y0, final double t1) { - RungeKuttaFieldStepInterpolator<T> interpolator = createInterpolator(field, t1 > t0, - new FieldExpandableODE<T>(eqn).getMapper()); // get the Butcher arrays from the field integrator - FieldButcherArrayProvider<T> provider = createButcherArrayProvider(field, interpolator); + FieldButcherArrayProvider<T> provider = createButcherArrayProvider(field); T[][] a = provider.getA(); T[] b = provider.getB(); T[] c = provider.getC(); @@ -156,8 +160,7 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest { fieldY[i] = field.getZero().add(y0[i]); } fieldYDotK[0] = eqn.computeDerivatives(t, fieldY); - interpolator.storeState(new FieldODEStateAndDerivative<T>(t, fieldY, fieldYDotK[0])); - interpolator.shift(); + FieldODEStateAndDerivative<T> s0 = new FieldODEStateAndDerivative<T>(t, fieldY, fieldYDotK[0]); // perform one integration step, in order to get consistent derivatives T h = field.getZero().add(t1 - t0); @@ -170,20 +173,20 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest { } fieldYDotK[k + 1] = eqn.computeDerivatives(h.multiply(c[k]).add(t0), fieldY); } - interpolator.setSlopes(fieldYDotK); // store state at step end + t = field.getZero().add(t1); for (int i = 0; i < y0.length; ++i) { fieldY[i] = field.getZero().add(y0[i]); for (int s = 0; s < b.length; ++s) { fieldY[i] = fieldY[i].add(h.multiply(b[s].multiply(fieldYDotK[s][i]))); } } - interpolator.storeState(new FieldODEStateAndDerivative<T>(field.getZero().add(t1), - fieldY, - eqn.computeDerivatives(field.getZero().add(t1), fieldY))); + FieldODEStateAndDerivative<T> s1 = new FieldODEStateAndDerivative<T>(t, fieldY, + eqn.computeDerivatives(t, fieldY)); - return interpolator; + return createInterpolator(field, t1 > t0, fieldYDotK, s0, s1, s0, s1, + new FieldExpandableODE<T>(eqn).getMapper()); } @@ -236,10 +239,10 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest { } @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); + T fieldT = fieldInterpolator.getCurrentState().getTime().getField().getZero().add(t); + T[] fieldY = MathArrays.buildArray(fieldInterpolator.getCurrentState().getTime().getField(), y.length); for (int i = 0; i < y.length; ++i) { - fieldY[i] = fieldInterpolator.getField().getZero().add(y[i]); + fieldY[i] = fieldInterpolator.getCurrentState().getTime().getField().getZero().add(y[i]); } T[] fieldYDot = eqn.computeDerivatives(fieldT, fieldY); for (int i = 0; i < yDot.length; ++i) { @@ -281,42 +284,6 @@ public abstract class AbstractRungeKuttaFieldStepInterpolatorTest { } - private <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> - createButcherArrayProvider(final Field<T> field, final RungeKuttaFieldStepInterpolator<T> provider) { - FieldButcherArrayProvider<T> integrator = null; - try { - String interpolatorName = provider.getClass().getName(); - String integratorName = interpolatorName.replaceAll("StepInterpolator", "Integrator"); - @SuppressWarnings("unchecked") - Class<FieldButcherArrayProvider<T>> clz = (Class<FieldButcherArrayProvider<T>>) Class.forName(integratorName); - try { - integrator = clz.getConstructor(Field.class, RealFieldElement.class). - newInstance(field, field.getOne()); - } catch (NoSuchMethodException nsme) { - try { - integrator = clz.getConstructor(Field.class, - 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()); - } - } - - } catch (InvocationTargetException ite) { - Assert.fail(ite.getLocalizedMessage()); - } catch (IllegalAccessException iae) { - Assert.fail(iae.getLocalizedMessage()); - } catch (InstantiationException ie) { - Assert.fail(ie.getLocalizedMessage()); - } catch (ClassNotFoundException cnfe) { - Assert.fail(cnfe.getLocalizedMessage()); - } - - return integrator; - - } - private static class SinCos<T extends RealFieldElement<T>> implements FieldFirstOrderDifferentialEquations<T> { private final Field<T> field; protected SinCos(final Field<T> field) { http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/ClassicalRungKuttaFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/ClassicalRungKuttaFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/ClassicalRungKuttaFieldStepInterpolatorTest.java index d559200..527fe25 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/ClassicalRungKuttaFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/ClassicalRungKuttaFieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.Decimal64Field; import org.junit.Test; public class ClassicalRungKuttaFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest { protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) { - return new ClassicalRungeKuttaFieldStepInterpolator<T>(field, forward, mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new ClassicalRungeKuttaFieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new ClassicalRungeKuttaFieldIntegrator<T>(field, field.getOne()); } @Test @@ -43,7 +57,7 @@ public class ClassicalRungKuttaFieldStepInterpolatorTest extends AbstractRungeKu @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 2.8e-17, 1.2e-16, 2.3e-16, 1.0e-50); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 2.8e-17, 1.2e-16, 3.4e-16, 2.1e-17); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java index 2aeac54..ee17388 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince54FieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.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); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new DormandPrince54FieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new DormandPrince54FieldIntegrator<T>(field, 0, 1, 1, 1); } @Test @@ -43,7 +57,7 @@ public class DormandPrince54FieldStepInterpolatorTest extends AbstractRungeKutta @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 2.8e-17, 2.3e-16, 4.5e-16, 5.6e-17); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 2.8e-17, 2.3e-16, 5.6e-16, 5.6e-17); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java index bbef7b4..a104867 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/DormandPrince853FieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.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); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new DormandPrince853FieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new DormandPrince853FieldIntegrator<T>(field, 0, 1, 1, 1); } @Test http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/EulerFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/EulerFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/EulerFieldStepInterpolatorTest.java index b7fa85e..0458f5c 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/EulerFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/EulerFieldStepInterpolatorTest.java @@ -21,14 +21,27 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.Decimal64Field; import org.junit.Test; public class EulerFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest { protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) { - return new EulerFieldStepInterpolator<T>(field, forward, mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, FieldEquationsMapper<T> mapper) { + return new EulerFieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new EulerFieldIntegrator<T>(field, field.getOne()); } @Test @@ -43,7 +56,7 @@ public class EulerFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepI @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.0e-50, 1.0e-50, 1.0e-50, 1.0e-50); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 7.0e-18, 1.0e-50, 1.0e-50, 1.0e-50); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/GillFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/GillFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/GillFieldStepInterpolatorTest.java index 7dcc874..54f0098 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/GillFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/GillFieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.Decimal64Field; import org.junit.Test; public class GillFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest { protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) { - return new GillFieldStepInterpolator<T>(field, forward, mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new GillFieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new GillFieldIntegrator<T>(field, field.getOne()); } @Test @@ -43,7 +57,7 @@ public class GillFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepIn @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.0e-50, 1.0e-50, 1.0e-50); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.0e-50, 3.4e-16, 2.1e-17); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java index 0d9180b..4bbe6f0 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/HighamHall54FieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.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); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new HighamHall54FieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new HighamHall54FieldIntegrator<T>(field, 0, 1, 1, 1); } @Test @@ -43,7 +57,7 @@ public class HighamHall54FieldStepInterpolatorTest extends AbstractRungeKuttaFie @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.0e-50, 1.0e-50, 1.0e-50); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.3e-16, 1.0e-50, 3.6e-15, 2.1e-16); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/LutherFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/LutherFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/LutherFieldStepInterpolatorTest.java index 4add8ca..39ebdb9 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/LutherFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/LutherFieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.Decimal64Field; import org.junit.Test; public class LutherFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest { protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) { - return new LutherFieldStepInterpolator<T>(field, forward, mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new LutherFieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new LutherFieldIntegrator<T>(field, field.getOne()); } @Test http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/MidpointFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/MidpointFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/MidpointFieldStepInterpolatorTest.java index 20dee47..6779c4a 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/MidpointFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/MidpointFieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.Decimal64Field; import org.junit.Test; public class MidpointFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest { protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) { - return new MidpointFieldStepInterpolator<T>(field, forward, mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new MidpointFieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new MidpointFieldIntegrator<T>(field, field.getOne()); } @Test @@ -43,7 +57,7 @@ public class MidpointFieldStepInterpolatorTest extends AbstractRungeKuttaFieldSt @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.0e-50, 1.0e-50, 1.0e-50, 1.0e-50); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.0e-50, 1.0e-50, 7.0e-18); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolatorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolatorTest.java b/src/test/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolatorTest.java index 6b956fa..6891e02 100644 --- a/src/test/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolatorTest.java +++ b/src/test/java/org/apache/commons/math4/ode/nonstiff/ThreeEighthesFieldStepInterpolatorTest.java @@ -21,14 +21,28 @@ package org.apache.commons.math4.ode.nonstiff; import org.apache.commons.math4.Field; import org.apache.commons.math4.RealFieldElement; import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; import org.apache.commons.math4.util.Decimal64Field; import org.junit.Test; public class ThreeEighthesFieldStepInterpolatorTest extends AbstractRungeKuttaFieldStepInterpolatorTest { protected <T extends RealFieldElement<T>> RungeKuttaFieldStepInterpolator<T> - createInterpolator(Field<T> field, boolean forward, FieldEquationsMapper<T> mapper) { - return new ThreeEighthesFieldStepInterpolator<T>(field, forward, mapper); + createInterpolator(Field<T> field, boolean forward, T[][] yDotK, + FieldODEStateAndDerivative<T> globalPreviousState, + FieldODEStateAndDerivative<T> globalCurrentState, + FieldODEStateAndDerivative<T> softPreviousState, + FieldODEStateAndDerivative<T> softCurrentState, + FieldEquationsMapper<T> mapper) { + return new ThreeEighthesFieldStepInterpolator<T>(field, forward, yDotK, + globalPreviousState, globalCurrentState, + softPreviousState, softCurrentState, + mapper); + } + + protected <T extends RealFieldElement<T>> FieldButcherArrayProvider<T> + createButcherArrayProvider(final Field<T> field) { + return new ThreeEighthesFieldIntegrator<T>(field, field.getOne()); } @Test @@ -43,7 +57,7 @@ public class ThreeEighthesFieldStepInterpolatorTest extends AbstractRungeKuttaFi @Test public void nonFieldInterpolatorConsistency() { - doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.2e-16, 1.0e-50, 1.0e-50); + doNonFieldInterpolatorConsistency(Decimal64Field.getInstance(), 1.4e-17, 1.2e-16, 3.4e-16, 1.4e-17); } } http://git-wip-us.apache.org/repos/asf/commons-math/blob/771eb6a6/src/test/java/org/apache/commons/math4/ode/sampling/DummyFieldStepInterpolator.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math4/ode/sampling/DummyFieldStepInterpolator.java b/src/test/java/org/apache/commons/math4/ode/sampling/DummyFieldStepInterpolator.java new file mode 100644 index 0000000..f546745 --- /dev/null +++ b/src/test/java/org/apache/commons/math4/ode/sampling/DummyFieldStepInterpolator.java @@ -0,0 +1,55 @@ +/* + * 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.math4.ode.sampling; + +import org.apache.commons.math4.RealFieldElement; +import org.apache.commons.math4.ode.FieldEquationsMapper; +import org.apache.commons.math4.ode.FieldODEStateAndDerivative; + +public class DummyFieldStepInterpolator<T extends RealFieldElement<T>> + extends AbstractFieldStepInterpolator<T> { + + public DummyFieldStepInterpolator(final boolean forward, + final FieldODEStateAndDerivative<T> globalPreviousState, + final FieldODEStateAndDerivative<T> globalCurrentState, + final FieldODEStateAndDerivative<T> softPreviousState, + final FieldODEStateAndDerivative<T> softCurrentState, + final FieldEquationsMapper<T> mapper) { + super(forward, globalPreviousState, globalCurrentState, softPreviousState, softCurrentState, mapper); + } + + @Override + protected AbstractFieldStepInterpolator<T> create(final boolean newForward, + final FieldODEStateAndDerivative<T> newGlobalPreviousState, + final FieldODEStateAndDerivative<T> newGlobalCurrentState, + final FieldODEStateAndDerivative<T> newSoftPreviousState, + final FieldODEStateAndDerivative<T> newSoftCurrentState, + final FieldEquationsMapper<T> newMapper) { + return new DummyFieldStepInterpolator<T>(newForward, + newGlobalPreviousState, newGlobalCurrentState, + newSoftPreviousState, newSoftCurrentState, + newMapper); + } + + @Override + protected FieldODEStateAndDerivative<T> computeInterpolatedStateAndDerivatives(FieldEquationsMapper<T> equationsMapper, + T time, T theta, T thetaH, T oneMinusThetaH) { + return getGlobalCurrentState(); + } + +}
