Renamed abstract test classes to match build environment filters. Project: http://git-wip-us.apache.org/repos/asf/commons-math/repo Commit: http://git-wip-us.apache.org/repos/asf/commons-math/commit/29649959 Tree: http://git-wip-us.apache.org/repos/asf/commons-math/tree/29649959 Diff: http://git-wip-us.apache.org/repos/asf/commons-math/diff/29649959
Branch: refs/heads/3.6-release Commit: 29649959e22888a0814541acc01f9ca8d86aaa72 Parents: 445f091 Author: Luc Maisonobe <l...@apache.org> Authored: Sat Jan 2 10:27:49 2016 +0100 Committer: Luc Maisonobe <l...@apache.org> Committed: Sat Jan 2 10:27:49 2016 +0100 ---------------------------------------------------------------------- .../AbstractAdamsFieldIntegratorTest.java | 260 -------- ...ctEmbeddedRungeKuttaFieldIntegratorTest.java | 600 ----------------- .../AbstractRungeKuttaFieldIntegratorTest.java | 662 ------------------- ...ractRungeKuttaFieldStepInterpolatorTest.java | 305 --------- .../AdamsBashforthFieldIntegratorTest.java | 2 +- .../AdamsFieldIntegratorAbstractTest.java | 260 ++++++++ .../AdamsMoultonFieldIntegratorTest.java | 2 +- ...sicalRungKuttaFieldStepInterpolatorTest.java | 2 +- .../ClassicalRungeKuttaFieldIntegratorTest.java | 2 +- .../DormandPrince54FieldIntegratorTest.java | 2 +- ...ormandPrince54FieldStepInterpolatorTest.java | 2 +- .../DormandPrince853FieldIntegratorTest.java | 2 +- ...rmandPrince853FieldStepInterpolatorTest.java | 2 +- ...edRungeKuttaFieldIntegratorAbstractTest.java | 600 +++++++++++++++++ .../ode/nonstiff/EulerFieldIntegratorTest.java | 2 +- .../EulerFieldStepInterpolatorTest.java | 2 +- .../ode/nonstiff/GillFieldIntegratorTest.java | 2 +- .../nonstiff/GillFieldStepInterpolatorTest.java | 2 +- .../HighamHall54FieldIntegratorTest.java | 2 +- .../HighamHall54FieldStepInterpolatorTest.java | 2 +- .../ode/nonstiff/LutherFieldIntegratorTest.java | 2 +- .../LutherFieldStepInterpolatorTest.java | 2 +- .../nonstiff/MidpointFieldIntegratorTest.java | 2 +- .../MidpointFieldStepInterpolatorTest.java | 2 +- .../RungeKuttaFieldIntegratorAbstractTest.java | 662 +++++++++++++++++++ ...eKuttaFieldStepInterpolatorAbstractTest.java | 305 +++++++++ .../ThreeEighthesFieldIntegratorTest.java | 2 +- .../ThreeEighthesFieldStepInterpolatorTest.java | 2 +- 28 files changed, 1847 insertions(+), 1847 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/commons-math/blob/29649959/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractAdamsFieldIntegratorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractAdamsFieldIntegratorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractAdamsFieldIntegratorTest.java deleted file mode 100644 index 74a5841..0000000 --- a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractAdamsFieldIntegratorTest.java +++ /dev/null @@ -1,260 +0,0 @@ -/* - * 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.MathIllegalStateException; -import org.apache.commons.math3.exception.MaxCountExceededException; -import org.apache.commons.math3.exception.NumberIsTooSmallException; -import org.apache.commons.math3.ode.AbstractFieldIntegrator; -import org.apache.commons.math3.ode.FieldExpandableODE; -import org.apache.commons.math3.ode.FieldODEState; -import org.apache.commons.math3.ode.FieldODEStateAndDerivative; -import org.apache.commons.math3.ode.FirstOrderFieldIntegrator; -import org.apache.commons.math3.ode.MultistepFieldIntegrator; -import org.apache.commons.math3.ode.TestFieldProblem1; -import org.apache.commons.math3.ode.TestFieldProblem5; -import org.apache.commons.math3.ode.TestFieldProblem6; -import org.apache.commons.math3.ode.TestFieldProblemAbstract; -import org.apache.commons.math3.ode.TestFieldProblemHandler; -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.junit.Assert; -import org.junit.Test; - -public abstract class AbstractAdamsFieldIntegratorTest { - - protected abstract <T extends RealFieldElement<T>> AdamsFieldIntegrator<T> - createIntegrator(Field<T> field, final int nSteps, final double minStep, final double maxStep, - final double scalAbsoluteTolerance, final double scalRelativeTolerance); - - protected abstract <T extends RealFieldElement<T>> AdamsFieldIntegrator<T> - createIntegrator(Field<T> field, final int nSteps, final double minStep, final double maxStep, - final double[] vecAbsoluteTolerance, final double[] vecRelativeTolerance); - - @Test(expected=NumberIsTooSmallException.class) - public abstract void testMinStep(); - - protected <T extends RealFieldElement<T>> void doDimensionCheck(final Field<T> field) { - 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 }; - - FirstOrderFieldIntegrator<T> integ = createIntegrator(field, 4, minStep, maxStep, - vecAbsoluteTolerance, - vecRelativeTolerance); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - } - - @Test - public abstract void testIncreasingTolerance(); - - protected <T extends RealFieldElement<T>> void doTestIncreasingTolerance(final Field<T> field, - double ratioMin, double ratioMax) { - - 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; - - FirstOrderFieldIntegrator<T> integ = createIntegrator(field, 4, 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() > ratioMin * scalAbsoluteTolerance); - Assert.assertTrue(handler.getMaximalValueError().getReal() < ratioMax * scalAbsoluteTolerance); - - int calls = pb.getCalls(); - Assert.assertEquals(integ.getEvaluations(), calls); - Assert.assertTrue(calls <= previousCalls); - previousCalls = calls; - - } - - } - - @Test(expected = MaxCountExceededException.class) - public abstract void exceedMaxEvaluations(); - - protected <T extends RealFieldElement<T>> void doExceedMaxEvaluations(final Field<T> field, final int max) { - - TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field); - double range = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(); - - FirstOrderFieldIntegrator<T> integ = createIntegrator(field, 2, 0, range, 1.0e-12, 1.0e-12); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.setMaxEvaluations(max); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - } - - @Test - public abstract void backward(); - - protected <T extends RealFieldElement<T>> void doBackward(final Field<T> field, - final double epsilonLast, - final double epsilonMaxValue, - final double epsilonMaxTime, - final String name) { - - TestFieldProblem5<T> pb = new TestFieldProblem5<T>(field); - double range = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(); - - AdamsFieldIntegrator<T> integ = createIntegrator(field, 4, 0, range, 1.0e-12, 1.0e-12); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - Assert.assertEquals(0.0, handler.getLastError().getReal(), epsilonLast); - Assert.assertEquals(0.0, handler.getMaximalValueError().getReal(), epsilonMaxValue); - Assert.assertEquals(0, handler.getMaximalTimeError().getReal(), epsilonMaxTime); - Assert.assertEquals(name, integ.getName()); - } - - @Test - public abstract void polynomial(); - - protected <T extends RealFieldElement<T>> void doPolynomial(final Field<T> field, - final int nLimit, - final double epsilonBad, - final double epsilonGood) { - TestFieldProblem6<T> pb = new TestFieldProblem6<T>(field); - double range = pb.getFinalTime().subtract(pb.getInitialState().getTime()).abs().getReal(); - - for (int nSteps = 2; nSteps < 8; ++nSteps) { - AdamsFieldIntegrator<T> integ = createIntegrator(field, nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-4, 1.0e-4); - integ.setStarterIntegrator(new PerfectStarter<T>(pb, nSteps)); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - if (nSteps < nLimit) { - Assert.assertTrue(handler.getMaximalValueError().getReal() > epsilonBad); - } else { - Assert.assertTrue(handler.getMaximalValueError().getReal() < epsilonGood); - } - } - - } - - @Test(expected=MathIllegalStateException.class) - public abstract void testStartFailure(); - - protected <T extends RealFieldElement<T>> void doTestStartFailure(final Field<T> field) { - TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field); - double minStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.0001).getReal(); - double maxStep = pb.getFinalTime().subtract(pb.getInitialState().getTime()).getReal(); - double scalAbsoluteTolerance = 1.0e-6; - double scalRelativeTolerance = 1.0e-7; - - MultistepFieldIntegrator<T> integ = createIntegrator(field, 6, minStep, maxStep, - scalAbsoluteTolerance, - scalRelativeTolerance); - integ.setStarterIntegrator(new DormandPrince853FieldIntegrator<T>(field, maxStep * 0.5, maxStep, 0.1, 0.1)); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - } - - private static class PerfectStarter<T extends RealFieldElement<T>> extends AbstractFieldIntegrator<T> { - - private final PerfectInterpolator<T> interpolator; - private final int nbSteps; - - public PerfectStarter(final TestFieldProblemAbstract<T> problem, final int nbSteps) { - super(problem.getField(), "perfect-starter"); - this.interpolator = new PerfectInterpolator<T>(problem); - this.nbSteps = nbSteps; - } - - public FieldODEStateAndDerivative<T> integrate(FieldExpandableODE<T> equations, - FieldODEState<T> initialState, T finalTime) { - T tStart = initialState.getTime().add(finalTime.subtract(initialState.getTime()).multiply(0.01)); - getEvaluationsCounter().increment(nbSteps); - interpolator.setCurrentTime(initialState.getTime()); - for (int i = 0; i < nbSteps; ++i) { - T tK = initialState.getTime().multiply(nbSteps - 1 - (i + 1)).add(tStart.multiply(i + 1)).divide(nbSteps - 1); - interpolator.setPreviousTime(interpolator.getCurrentTime()); - interpolator.setCurrentTime(tK); - for (FieldStepHandler<T> handler : getStepHandlers()) { - handler.handleStep(interpolator, i == nbSteps - 1); - } - } - return interpolator.getInterpolatedState(tStart); - } - - } - - private static class PerfectInterpolator<T extends RealFieldElement<T>> implements FieldStepInterpolator<T> { - private final TestFieldProblemAbstract<T> problem; - private T previousTime; - private T currentTime; - - public PerfectInterpolator(final TestFieldProblemAbstract<T> problem) { - this.problem = problem; - } - - public void setPreviousTime(T previousTime) { - this.previousTime = previousTime; - } - - public void setCurrentTime(T currentTime) { - this.currentTime = currentTime; - } - - public T getCurrentTime() { - return currentTime; - } - - public boolean isForward() { - return problem.getFinalTime().subtract(problem.getInitialState().getTime()).getReal() >= 0; - } - - public FieldODEStateAndDerivative<T> getPreviousState() { - return getInterpolatedState(previousTime); - } - - public FieldODEStateAndDerivative<T> getCurrentState() { - return getInterpolatedState(currentTime); - } - - public FieldODEStateAndDerivative<T> getInterpolatedState(T time) { - T[] y = problem.computeTheoreticalState(time); - T[] yDot = problem.computeDerivatives(time, y); - return new FieldODEStateAndDerivative<T>(time, y, yDot); - } - - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/29649959/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 deleted file mode 100644 index 97458d0..0000000 --- a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractEmbeddedRungeKuttaFieldIntegratorTest.java +++ /dev/null @@ -1,600 +0,0 @@ -/* - * 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.analysis.differentiation.DerivativeStructure; -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.FirstOrderFieldDifferentialEquations; -import org.apache.commons.math3.ode.FirstOrderFieldIntegrator; -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(); - if (fieldIntegrator instanceof DormandPrince853FieldIntegrator) { - // special case for Dormand-Prince 8(5,3), the array in the regular - // integrator is smaller because as of 3.X, the interpolation steps - // are not performed by the integrator itself - T[][] reducedFieldA = MathArrays.buildArray(field, 12, -1); - T[] reducedFieldB = MathArrays.buildArray(field, 13); - T[] reducedFieldC = MathArrays.buildArray(field, 12); - System.arraycopy(fieldA, 0, reducedFieldA, 0, reducedFieldA.length); - System.arraycopy(fieldB, 0, reducedFieldB, 0, reducedFieldB.length); - System.arraycopy(fieldC, 0, reducedFieldC, 0, reducedFieldC.length); - fieldA = reducedFieldA; - fieldB = reducedFieldB; - fieldC = reducedFieldC; - } - - 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) { - FirstOrderFieldDifferentialEquations<T> equations = new FirstOrderFieldDifferentialEquations<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<T>(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<T>(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 }; - - FirstOrderFieldIntegrator<T> integ = createIntegrator(field, minStep, maxStep, - vecAbsoluteTolerance, vecRelativeTolerance); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(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; - - FirstOrderFieldIntegrator<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; - - FirstOrderFieldIntegrator<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; - - FirstOrderFieldIntegrator<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; - - FirstOrderFieldIntegrator<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<T>(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<T>(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<T>(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 epsilonLast, - 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<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - Assert.assertEquals(0, handler.getLastError().getReal(), epsilonLast); - 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 }; - - FirstOrderFieldIntegrator<T> integ = createIntegrator(field, minStep, maxStep, - vecAbsoluteTolerance, vecRelativeTolerance); - integ.addStepHandler(new KeplerHandler<T>(pb, epsilon)); - integ.integrate(new FieldExpandableODE<T>(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); - } - } - } - - @Test - public abstract void testPartialDerivatives(); - - protected void doTestPartialDerivatives(final double epsilonY, - final double[] epsilonPartials) { - - // parameters indices - final int parameters = 5; - final int order = 1; - final int parOmega = 0; - final int parTO = 1; - final int parY00 = 2; - final int parY01 = 3; - final int parT = 4; - - DerivativeStructure omega = new DerivativeStructure(parameters, order, parOmega, 1.3); - DerivativeStructure t0 = new DerivativeStructure(parameters, order, parTO, 1.3); - DerivativeStructure[] y0 = new DerivativeStructure[] { - new DerivativeStructure(parameters, order, parY00, 3.0), - new DerivativeStructure(parameters, order, parY01, 4.0) - }; - DerivativeStructure t = new DerivativeStructure(parameters, order, parT, 6.0); - SinCos sinCos = new SinCos(omega); - - EmbeddedRungeKuttaFieldIntegrator<DerivativeStructure> integrator = - createIntegrator(omega.getField(), - t.subtract(t0).multiply(0.001).getReal(), t.subtract(t0).getReal(), - 1.0e-12, 1.0e-12); - FieldODEStateAndDerivative<DerivativeStructure> result = - integrator.integrate(new FieldExpandableODE<DerivativeStructure>(sinCos), - new FieldODEState<DerivativeStructure>(t0, y0), - t); - - // check values - for (int i = 0; i < sinCos.getDimension(); ++i) { - Assert.assertEquals(sinCos.theoreticalY(t.getReal())[i], result.getState()[i].getValue(), epsilonY); - } - - // check derivatives - final double[][] derivatives = sinCos.getDerivatives(t.getReal()); - for (int i = 0; i < sinCos.getDimension(); ++i) { - for (int parameter = 0; parameter < parameters; ++parameter) { - Assert.assertEquals(derivatives[i][parameter], dYdP(result.getState()[i], parameter), epsilonPartials[parameter]); - } - } - - } - - private double dYdP(final DerivativeStructure y, final int parameter) { - int[] orders = new int[y.getFreeParameters()]; - orders[parameter] = 1; - return y.getPartialDerivative(orders); - } - - private static class SinCos implements FirstOrderFieldDifferentialEquations<DerivativeStructure> { - - private final DerivativeStructure omega; - private DerivativeStructure r; - private DerivativeStructure alpha; - - private double dRdY00; - private double dRdY01; - private double dAlphadOmega; - private double dAlphadT0; - private double dAlphadY00; - private double dAlphadY01; - - protected SinCos(final DerivativeStructure omega) { - this.omega = omega; - } - - public int getDimension() { - return 2; - } - - public void init(final DerivativeStructure t0, final DerivativeStructure[] y0, - final DerivativeStructure finalTime) { - - // theoretical solution is y(t) = { r * sin(omega * t + alpha), r * cos(omega * t + alpha) } - // so we retrieve alpha by identification from the initial state - final DerivativeStructure r2 = y0[0].multiply(y0[0]).add(y0[1].multiply(y0[1])); - - this.r = r2.sqrt(); - this.dRdY00 = y0[0].divide(r).getReal(); - this.dRdY01 = y0[1].divide(r).getReal(); - - this.alpha = y0[0].atan2(y0[1]).subtract(t0.multiply(omega)); - this.dAlphadOmega = -t0.getReal(); - this.dAlphadT0 = -omega.getReal(); - this.dAlphadY00 = y0[1].divide(r2).getReal(); - this.dAlphadY01 = y0[0].negate().divide(r2).getReal(); - - } - - public DerivativeStructure[] computeDerivatives(final DerivativeStructure t, final DerivativeStructure[] y) { - return new DerivativeStructure[] { - omega.multiply(y[1]), - omega.multiply(y[0]).negate() - }; - } - - public double[] theoreticalY(final double t) { - final double theta = omega.getReal() * t + alpha.getReal(); - return new double[] { - r.getReal() * FastMath.sin(theta), r.getReal() * FastMath.cos(theta) - }; - } - - public double[][] getDerivatives(final double t) { - - // intermediate angle and state - final double theta = omega.getReal() * t + alpha.getReal(); - final double sin = FastMath.sin(theta); - final double cos = FastMath.cos(theta); - final double y0 = r.getReal() * sin; - final double y1 = r.getReal() * cos; - - // partial derivatives of the state first component - final double dY0dOmega = y1 * (t + dAlphadOmega); - final double dY0dT0 = y1 * dAlphadT0; - final double dY0dY00 = dRdY00 * sin + y1 * dAlphadY00; - final double dY0dY01 = dRdY01 * sin + y1 * dAlphadY01; - final double dY0dT = y1 * omega.getReal(); - - // partial derivatives of the state second component - final double dY1dOmega = - y0 * (t + dAlphadOmega); - final double dY1dT0 = - y0 * dAlphadT0; - final double dY1dY00 = dRdY00 * cos - y0 * dAlphadY00; - final double dY1dY01 = dRdY01 * cos - y0 * dAlphadY01; - final double dY1dT = - y0 * omega.getReal(); - - return new double[][] { - { dY0dOmega, dY0dT0, dY0dY00, dY0dY01, dY0dT }, - { dY1dOmega, dY1dT0, dY1dY00, dY1dY01, dY1dT } - }; - - } - - } - -} http://git-wip-us.apache.org/repos/asf/commons-math/blob/29649959/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldIntegratorTest.java ---------------------------------------------------------------------- diff --git a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldIntegratorTest.java b/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldIntegratorTest.java deleted file mode 100644 index 35cc13d..0000000 --- a/src/test/java/org/apache/commons/math3/ode/nonstiff/AbstractRungeKuttaFieldIntegratorTest.java +++ /dev/null @@ -1,662 +0,0 @@ -/* - * 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 java.lang.reflect.Array; - -import org.apache.commons.math3.Field; -import org.apache.commons.math3.RealFieldElement; -import org.apache.commons.math3.analysis.differentiation.DerivativeStructure; -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.FirstOrderFieldDifferentialEquations; -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.TestFieldProblem2; -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.TestFieldProblem6; -import org.apache.commons.math3.ode.TestFieldProblemAbstract; -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.ode.sampling.StepInterpolatorTestUtils; -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 AbstractRungeKuttaFieldIntegratorTest { - - protected abstract <T extends RealFieldElement<T>> RungeKuttaFieldIntegrator<T> - createIntegrator(Field<T> field, T step); - - @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 - RungeKuttaFieldIntegrator<T> fieldIntegrator = createIntegrator(field, field.getZero().add(1)); - 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 testMissedEndEvent(); - - protected <T extends RealFieldElement<T>> void doTestMissedEndEvent(final Field<T> field, - final double epsilonT, final double epsilonY) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - final T t0 = field.getZero().add(1878250320.0000029); - final T tEvent = field.getZero().add(1878250379.9999986); - final T[] k = MathArrays.buildArray(field, 3); - k[0] = field.getZero().add(1.0e-4); - k[1] = field.getZero().add(1.0e-5); - k[2] = field.getZero().add(1.0e-6); - FirstOrderFieldDifferentialEquations<T> ode = new FirstOrderFieldDifferentialEquations<T>() { - - public int getDimension() { - return k.length; - } - - public void init(T t0, T[] y0, T t) { - } - - public T[] computeDerivatives(T t, T[] y) { - T[] yDot = MathArrays.buildArray(field, k.length); - for (int i = 0; i < y.length; ++i) { - yDot[i] = k[i].multiply(y[i]); - } - return yDot; - } - }; - - RungeKuttaFieldIntegrator<T> integrator = createIntegrator(field, field.getZero().add(60.0)); - - T[] y0 = MathArrays.buildArray(field, k.length); - for (int i = 0; i < y0.length; ++i) { - y0[i] = field.getOne().add(i); - } - - FieldODEStateAndDerivative<T> result = integrator.integrate(new FieldExpandableODE<T>(ode), - new FieldODEState<T>(t0, y0), - tEvent); - Assert.assertEquals(tEvent.getReal(), result.getTime().getReal(), epsilonT); - T[] y = result.getState(); - for (int i = 0; i < y.length; ++i) { - Assert.assertEquals(y0[i].multiply(k[i].multiply(result.getTime().subtract(t0)).exp()).getReal(), - y[i].getReal(), - epsilonY); - } - - integrator.addEventHandler(new FieldEventHandler<T>() { - - public void init(FieldODEStateAndDerivative<T> state0, T t) { - } - - public FieldODEState<T> resetState(FieldODEStateAndDerivative<T> state) { - return state; - } - - public T g(FieldODEStateAndDerivative<T> state) { - return state.getTime().subtract(tEvent); - } - - public Action eventOccurred(FieldODEStateAndDerivative<T> state, boolean increasing) { - Assert.assertEquals(tEvent.getReal(), state.getTime().getReal(), epsilonT); - return Action.CONTINUE; - } - }, Double.POSITIVE_INFINITY, 1.0e-20, 100); - result = integrator.integrate(new FieldExpandableODE<T>(ode), - new FieldODEState<T>(t0, y0), - tEvent.add(120)); - Assert.assertEquals(tEvent.add(120).getReal(), result.getTime().getReal(), epsilonT); - y = result.getState(); - for (int i = 0; i < y.length; ++i) { - Assert.assertEquals(y0[i].multiply(k[i].multiply(result.getTime().subtract(t0)).exp()).getReal(), - y[i].getReal(), - epsilonY); - } - - } - - @Test - public abstract void testSanityChecks(); - - protected <T extends RealFieldElement<T>> void doTestSanityChecks(Field<T> field) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - RungeKuttaFieldIntegrator<T> integrator = createIntegrator(field, field.getZero().add(0.01)); - try { - TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field); - integrator.integrate(new FieldExpandableODE<T>(pb), - new FieldODEState<T>(field.getZero(), MathArrays.buildArray(field, pb.getDimension() + 10)), - field.getOne()); - Assert.fail("an exception should have been thrown"); - } catch(DimensionMismatchException ie) { - } - try { - TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field); - integrator.integrate(new FieldExpandableODE<T>(pb), - new FieldODEState<T>(field.getZero(), MathArrays.buildArray(field, pb.getDimension())), - field.getZero()); - Assert.fail("an exception should have been thrown"); - } catch(NumberIsTooSmallException ie) { - } - } - - @Test - public abstract void testDecreasingSteps(); - - protected <T extends RealFieldElement<T>> void doTestDecreasingSteps(Field<T> field, - final double safetyValueFactor, - final double safetyTimeFactor, - final double epsilonT) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - - @SuppressWarnings("unchecked") - TestFieldProblemAbstract<T>[] allProblems = - (TestFieldProblemAbstract<T>[]) Array.newInstance(TestFieldProblemAbstract.class, 6); - allProblems[0] = new TestFieldProblem1<T>(field); - allProblems[1] = new TestFieldProblem2<T>(field); - allProblems[2] = new TestFieldProblem3<T>(field); - allProblems[3] = new TestFieldProblem4<T>(field); - allProblems[4] = new TestFieldProblem5<T>(field); - allProblems[5] = new TestFieldProblem6<T>(field); - for (TestFieldProblemAbstract<T> pb : allProblems) { - - T previousValueError = null; - T previousTimeError = null; - for (int i = 4; i < 10; ++i) { - - T step = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(FastMath.pow(2.0, -i)); - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - FieldEventHandler<T>[] functions = pb.getEventsHandlers(); - for (int l = 0; l < functions.length; ++l) { - integ.addEventHandler(functions[l], - Double.POSITIVE_INFINITY, 1.0e-6 * step.getReal(), 1000); - } - Assert.assertEquals(functions.length, integ.getEventHandlers().size()); - FieldODEStateAndDerivative<T> stop = integ.integrate(new FieldExpandableODE<T>(pb), - pb.getInitialState(), - pb.getFinalTime()); - if (functions.length == 0) { - Assert.assertEquals(pb.getFinalTime().getReal(), stop.getTime().getReal(), epsilonT); - } - - T error = handler.getMaximalValueError(); - if (i > 4) { - Assert.assertTrue(error.subtract(previousValueError.abs().multiply(safetyValueFactor)).getReal() < 0); - } - previousValueError = error; - - T timeError = handler.getMaximalTimeError(); - if (i > 4) { - Assert.assertTrue(timeError.subtract(previousTimeError.abs().multiply(safetyTimeFactor)).getReal() <= 0); - } - previousTimeError = timeError; - - integ.clearEventHandlers(); - Assert.assertEquals(0, integ.getEventHandlers().size()); - } - - } - - } - - @Test - public abstract void testSmallStep(); - - protected <T extends RealFieldElement<T>> void doTestSmallStep(Field<T> field, - final double epsilonLast, - final double epsilonMaxValue, - final double epsilonMaxTime, - final String name) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - - TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field); - T step = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.001); - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - Assert.assertEquals(0, handler.getLastError().getReal(), epsilonLast); - Assert.assertEquals(0, handler.getMaximalValueError().getReal(), epsilonMaxValue); - Assert.assertEquals(0, handler.getMaximalTimeError().getReal(), epsilonMaxTime); - Assert.assertEquals(name, integ.getName()); - - } - - @Test - public abstract void testBigStep(); - - protected <T extends RealFieldElement<T>> void doTestBigStep(Field<T> field, - final double belowLast, - final double belowMaxValue, - final double epsilonMaxTime, - final String name) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - - TestFieldProblem1<T> pb = new TestFieldProblem1<T>(field); - T step = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.2); - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - Assert.assertTrue(handler.getLastError().getReal() > belowLast); - Assert.assertTrue(handler.getMaximalValueError().getReal() > belowMaxValue); - Assert.assertEquals(0, handler.getMaximalTimeError().getReal(), epsilonMaxTime); - Assert.assertEquals(name, integ.getName()); - - } - - @Test - public abstract void testBackward(); - - protected <T extends RealFieldElement<T>> void doTestBackward(Field<T> field, - final double epsilonLast, - final double epsilonMaxValue, - final double epsilonMaxTime, - final String name) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - - TestFieldProblem5<T> pb = new TestFieldProblem5<T>(field); - T step = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.001).abs(); - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - TestFieldProblemHandler<T> handler = new TestFieldProblemHandler<T>(pb, integ); - integ.addStepHandler(handler); - integ.integrate(new FieldExpandableODE<T>(pb), pb.getInitialState(), pb.getFinalTime()); - - Assert.assertEquals(0, handler.getLastError().getReal(), epsilonLast); - 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 expectedMaxError, double epsilon) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - - final TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field, field.getZero().add(0.9)); - T step = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.0003); - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - integ.addStepHandler(new KeplerHandler<T>(pb, expectedMaxError, epsilon)); - integ.integrate(new FieldExpandableODE<T>(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 expectedMaxError; - private final double epsilon; - public KeplerHandler(TestFieldProblem3<T> pb, double expectedMaxError, double epsilon) { - this.pb = pb; - this.expectedMaxError = expectedMaxError; - 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(expectedMaxError, maxError.getReal(), epsilon); - } - } - } - - @Test - public abstract void testStepSize(); - - protected <T extends RealFieldElement<T>> void doTestStepSize(final Field<T> field, final double epsilon) - throws DimensionMismatchException, NumberIsTooSmallException, - MaxCountExceededException, NoBracketingException { - final T step = field.getZero().add(1.23456); - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - integ.addStepHandler(new FieldStepHandler<T>() { - public void handleStep(FieldStepInterpolator<T> interpolator, boolean isLast) { - if (! isLast) { - Assert.assertEquals(step.getReal(), - interpolator.getCurrentState().getTime().subtract(interpolator.getPreviousState().getTime()).getReal(), - epsilon); - } - } - public void init(FieldODEStateAndDerivative<T> s0, T t) { - } - }); - integ.integrate(new FieldExpandableODE<T>(new FirstOrderFieldDifferentialEquations<T>() { - public void init(T t0, T[] y0, T t) { - } - public T[] computeDerivatives(T t, T[] y) { - T[] dot = MathArrays.buildArray(t.getField(), 1); - dot[0] = t.getField().getOne(); - return dot; - } - public int getDimension() { - return 1; - } - }), new FieldODEState<T>(field.getZero(), MathArrays.buildArray(field, 1)), field.getZero().add(5.0)); - } - - @Test - public abstract void testSingleStep(); - - protected <T extends RealFieldElement<T>> void doTestSingleStep(final Field<T> field, final double epsilon) { - - final TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field, field.getZero().add(0.9)); - T h = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.0003); - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, field.getZero().add(Double.NaN)); - T t = pb.getInitialState().getTime(); - T[] y = pb.getInitialState().getState(); - for (int i = 0; i < 100; ++i) { - y = integ.singleStep(pb, t, y, t.add(h)); - t = t.add(h); - } - T[] yth = pb.computeTheoreticalState(t); - T dx = y[0].subtract(yth[0]); - T dy = y[1].subtract(yth[1]); - T error = dx.multiply(dx).add(dy.multiply(dy)); - Assert.assertEquals(0.0, error.getReal(), epsilon); - } - - @Test - public abstract void testTooLargeFirstStep(); - - protected <T extends RealFieldElement<T>> void doTestTooLargeFirstStep(final Field<T> field) { - - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, field.getZero().add(0.5)); - final T t0 = field.getZero(); - final T[] y0 = MathArrays.buildArray(field, 1); - y0[0] = field.getOne(); - final T t = field.getZero().add(0.001); - FirstOrderFieldDifferentialEquations<T> equations = new FirstOrderFieldDifferentialEquations<T>() { - - public int getDimension() { - return 1; - } - - public void init(T t0, T[] y0, T t) { - } - - public T[] computeDerivatives(T t, T[] y) { - Assert.assertTrue(t.getReal() >= FastMath.nextAfter(t0.getReal(), Double.NEGATIVE_INFINITY)); - Assert.assertTrue(t.getReal() <= FastMath.nextAfter(t.getReal(), Double.POSITIVE_INFINITY)); - T[] yDot = MathArrays.buildArray(field, 1); - yDot[0] = y[0].multiply(-100.0); - return yDot; - } - - }; - - integ.integrate(new FieldExpandableODE<T>(equations), new FieldODEState<T>(t0, y0), t); - - } - - @Test - public abstract void testUnstableDerivative(); - - protected <T extends RealFieldElement<T>> void doTestUnstableDerivative(Field<T> field, double epsilon) { - final StepFieldProblem<T> stepProblem = new StepFieldProblem<T>(field, - field.getZero().add(0.0), - field.getZero().add(1.0), - field.getZero().add(2.0)); - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, field.getZero().add(0.3)); - integ.addEventHandler(stepProblem, 1.0, 1.0e-12, 1000); - FieldODEStateAndDerivative<T> result = integ.integrate(new FieldExpandableODE<T>(stepProblem), - new FieldODEState<T>(field.getZero(), MathArrays.buildArray(field, 1)), - field.getZero().add(10.0)); - Assert.assertEquals(8.0, result.getState()[0].getReal(), epsilon); - } - - @Test - public abstract void testDerivativesConsistency(); - - protected <T extends RealFieldElement<T>> void doTestDerivativesConsistency(final Field<T> field, double epsilon) { - TestFieldProblem3<T> pb = new TestFieldProblem3<T>(field); - T step = pb.getFinalTime().subtract(pb.getInitialState().getTime()).multiply(0.001); - RungeKuttaFieldIntegrator<T> integ = createIntegrator(field, step); - StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10); - } - - @Test - public abstract void testPartialDerivatives(); - - protected void doTestPartialDerivatives(final double epsilonY, - final double[] epsilonPartials) { - - // parameters indices - final int parameters = 5; - final int order = 1; - final int parOmega = 0; - final int parTO = 1; - final int parY00 = 2; - final int parY01 = 3; - final int parT = 4; - - DerivativeStructure omega = new DerivativeStructure(parameters, order, parOmega, 1.3); - DerivativeStructure t0 = new DerivativeStructure(parameters, order, parTO, 1.3); - DerivativeStructure[] y0 = new DerivativeStructure[] { - new DerivativeStructure(parameters, order, parY00, 3.0), - new DerivativeStructure(parameters, order, parY01, 4.0) - }; - DerivativeStructure t = new DerivativeStructure(parameters, order, parT, 6.0); - SinCos sinCos = new SinCos(omega); - - RungeKuttaFieldIntegrator<DerivativeStructure> integrator = - createIntegrator(omega.getField(), t.subtract(t0).multiply(0.001)); - FieldODEStateAndDerivative<DerivativeStructure> result = - integrator.integrate(new FieldExpandableODE<DerivativeStructure>(sinCos), - new FieldODEState<DerivativeStructure>(t0, y0), - t); - - // check values - for (int i = 0; i < sinCos.getDimension(); ++i) { - Assert.assertEquals(sinCos.theoreticalY(t.getReal())[i], result.getState()[i].getValue(), epsilonY); - } - - // check derivatives - final double[][] derivatives = sinCos.getDerivatives(t.getReal()); - for (int i = 0; i < sinCos.getDimension(); ++i) { - for (int parameter = 0; parameter < parameters; ++parameter) { - Assert.assertEquals(derivatives[i][parameter], - dYdP(result.getState()[i], parameter), - epsilonPartials[parameter]); - } - } - - } - - private double dYdP(final DerivativeStructure y, final int parameter) { - int[] orders = new int[y.getFreeParameters()]; - orders[parameter] = 1; - return y.getPartialDerivative(orders); - } - - private static class SinCos implements FirstOrderFieldDifferentialEquations<DerivativeStructure> { - - private final DerivativeStructure omega; - private DerivativeStructure r; - private DerivativeStructure alpha; - - private double dRdY00; - private double dRdY01; - private double dAlphadOmega; - private double dAlphadT0; - private double dAlphadY00; - private double dAlphadY01; - - protected SinCos(final DerivativeStructure omega) { - this.omega = omega; - } - - public int getDimension() { - return 2; - } - - public void init(final DerivativeStructure t0, final DerivativeStructure[] y0, - final DerivativeStructure finalTime) { - - // theoretical solution is y(t) = { r * sin(omega * t + alpha), r * cos(omega * t + alpha) } - // so we retrieve alpha by identification from the initial state - final DerivativeStructure r2 = y0[0].multiply(y0[0]).add(y0[1].multiply(y0[1])); - - this.r = r2.sqrt(); - this.dRdY00 = y0[0].divide(r).getReal(); - this.dRdY01 = y0[1].divide(r).getReal(); - - this.alpha = y0[0].atan2(y0[1]).subtract(t0.multiply(omega)); - this.dAlphadOmega = -t0.getReal(); - this.dAlphadT0 = -omega.getReal(); - this.dAlphadY00 = y0[1].divide(r2).getReal(); - this.dAlphadY01 = y0[0].negate().divide(r2).getReal(); - - } - - public DerivativeStructure[] computeDerivatives(final DerivativeStructure t, final DerivativeStructure[] y) { - return new DerivativeStructure[] { - omega.multiply(y[1]), - omega.multiply(y[0]).negate() - }; - } - - public double[] theoreticalY(final double t) { - final double theta = omega.getReal() * t + alpha.getReal(); - return new double[] { - r.getReal() * FastMath.sin(theta), r.getReal() * FastMath.cos(theta) - }; - } - - public double[][] getDerivatives(final double t) { - - // intermediate angle and state - final double theta = omega.getReal() * t + alpha.getReal(); - final double sin = FastMath.sin(theta); - final double cos = FastMath.cos(theta); - final double y0 = r.getReal() * sin; - final double y1 = r.getReal() * cos; - - // partial derivatives of the state first component - final double dY0dOmega = y1 * (t + dAlphadOmega); - final double dY0dT0 = y1 * dAlphadT0; - final double dY0dY00 = dRdY00 * sin + y1 * dAlphadY00; - final double dY0dY01 = dRdY01 * sin + y1 * dAlphadY01; - final double dY0dT = y1 * omega.getReal(); - - // partial derivatives of the state second component - final double dY1dOmega = - y0 * (t + dAlphadOmega); - final double dY1dT0 = - y0 * dAlphadT0; - final double dY1dY00 = dRdY00 * cos - y0 * dAlphadY00; - final double dY1dY01 = dRdY01 * cos - y0 * dAlphadY01; - final double dY1dT = - y0 * omega.getReal(); - - return new double[][] { - { dY0dOmega, dY0dT0, dY0dY00, dY0dY01, dY0dT }, - { dY1dOmega, dY1dT0, dY1dY00, dY1dY01, dY1dT } - }; - - } - - } - -}