2
* Licensed to the Apache Software Foundation (ASF) under one or more
3
* contributor license agreements. See the NOTICE file distributed with
4
* this work for additional information regarding copyright ownership.
5
* The ASF licenses this file to You under the Apache License, Version 2.0
6
* (the "License"); you may not use this file except in compliance with
7
* the License. You may obtain a copy of the License at
9
* http://www.apache.org/licenses/LICENSE-2.0
11
* Unless required by applicable law or agreed to in writing, software
12
* distributed under the License is distributed on an "AS IS" BASIS,
13
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
* See the License for the specific language governing permissions and
15
* limitations under the License.
18
package org.apache.commons.math.ode.nonstiff;
20
import static org.junit.Assert.assertEquals;
21
import static org.junit.Assert.assertTrue;
23
import org.apache.commons.math.ode.DerivativeException;
24
import org.apache.commons.math.ode.FirstOrderIntegrator;
25
import org.apache.commons.math.ode.IntegratorException;
26
import org.apache.commons.math.ode.TestProblem1;
27
import org.apache.commons.math.ode.TestProblem5;
28
import org.apache.commons.math.ode.TestProblem6;
29
import org.apache.commons.math.ode.TestProblemHandler;
30
import org.junit.Test;
32
public class AdamsMoultonIntegratorTest {
34
@Test(expected=IntegratorException.class)
35
public void dimensionCheck() throws DerivativeException, IntegratorException {
36
TestProblem1 pb = new TestProblem1();
37
FirstOrderIntegrator integ =
38
new AdamsMoultonIntegrator(2, 0.0, 1.0, 1.0e-10, 1.0e-10);
40
0.0, new double[pb.getDimension()+10],
41
1.0, new double[pb.getDimension()+10]);
44
@Test(expected=IntegratorException.class)
45
public void testMinStep() throws DerivativeException, IntegratorException {
47
TestProblem1 pb = new TestProblem1();
48
double minStep = 0.1 * (pb.getFinalTime() - pb.getInitialTime());
49
double maxStep = pb.getFinalTime() - pb.getInitialTime();
50
double[] vecAbsoluteTolerance = { 1.0e-15, 1.0e-16 };
51
double[] vecRelativeTolerance = { 1.0e-15, 1.0e-16 };
53
FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, minStep, maxStep,
55
vecRelativeTolerance);
56
TestProblemHandler handler = new TestProblemHandler(pb, integ);
57
integ.addStepHandler(handler);
59
pb.getInitialTime(), pb.getInitialState(),
60
pb.getFinalTime(), new double[pb.getDimension()]);
65
public void testIncreasingTolerance()
66
throws DerivativeException, IntegratorException {
68
int previousCalls = Integer.MAX_VALUE;
69
for (int i = -12; i < -2; ++i) {
70
TestProblem1 pb = new TestProblem1();
72
double maxStep = pb.getFinalTime() - pb.getInitialTime();
73
double scalAbsoluteTolerance = Math.pow(10.0, i);
74
double scalRelativeTolerance = 0.01 * scalAbsoluteTolerance;
76
FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, minStep, maxStep,
77
scalAbsoluteTolerance,
78
scalRelativeTolerance);
79
TestProblemHandler handler = new TestProblemHandler(pb, integ);
80
integ.addStepHandler(handler);
82
pb.getInitialTime(), pb.getInitialState(),
83
pb.getFinalTime(), new double[pb.getDimension()]);
85
// the 0.15 and 3.0 factors are only valid for this test
86
// and has been obtained from trial and error
87
// there is no general relation between local and global errors
88
assertTrue(handler.getMaximalValueError() > (0.15 * scalAbsoluteTolerance));
89
assertTrue(handler.getMaximalValueError() < (3.0 * scalAbsoluteTolerance));
90
assertEquals(0, handler.getMaximalTimeError(), 1.0e-16);
92
int calls = pb.getCalls();
93
assertEquals(integ.getEvaluations(), calls);
94
assertTrue(calls <= previousCalls);
95
previousCalls = calls;
101
@Test(expected = DerivativeException.class)
102
public void exceedMaxEvaluations() throws DerivativeException, IntegratorException {
104
TestProblem1 pb = new TestProblem1();
105
double range = pb.getFinalTime() - pb.getInitialTime();
107
AdamsMoultonIntegrator integ = new AdamsMoultonIntegrator(2, 0, range, 1.0e-12, 1.0e-12);
108
TestProblemHandler handler = new TestProblemHandler(pb, integ);
109
integ.addStepHandler(handler);
110
integ.setMaxEvaluations(650);
112
pb.getInitialTime(), pb.getInitialState(),
113
pb.getFinalTime(), new double[pb.getDimension()]);
118
public void backward() throws DerivativeException, IntegratorException {
120
TestProblem5 pb = new TestProblem5();
121
double range = Math.abs(pb.getFinalTime() - pb.getInitialTime());
123
FirstOrderIntegrator integ = new AdamsMoultonIntegrator(4, 0, range, 1.0e-12, 1.0e-12);
124
TestProblemHandler handler = new TestProblemHandler(pb, integ);
125
integ.addStepHandler(handler);
126
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
127
pb.getFinalTime(), new double[pb.getDimension()]);
129
assertTrue(handler.getLastError() < 1.0e-9);
130
assertTrue(handler.getMaximalValueError() < 1.0e-9);
131
assertEquals(0, handler.getMaximalTimeError(), 1.0e-16);
132
assertEquals("Adams-Moulton", integ.getName());
136
public void polynomial() throws DerivativeException, IntegratorException {
137
TestProblem6 pb = new TestProblem6();
138
double range = Math.abs(pb.getFinalTime() - pb.getInitialTime());
140
for (int nSteps = 1; nSteps < 7; ++nSteps) {
141
AdamsMoultonIntegrator integ =
142
new AdamsMoultonIntegrator(nSteps, 1.0e-6 * range, 0.1 * range, 1.0e-9, 1.0e-9);
143
TestProblemHandler handler = new TestProblemHandler(pb, integ);
144
integ.addStepHandler(handler);
145
integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
146
pb.getFinalTime(), new double[pb.getDimension()]);
148
assertTrue(integ.getEvaluations() > 150);
150
assertTrue(integ.getEvaluations() < 100);