1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.commons.math.ode;
19
20 import junit.framework.*;
21
22 import org.apache.commons.math.ode.DerivativeException;
23 import org.apache.commons.math.ode.FirstOrderIntegrator;
24 import org.apache.commons.math.ode.IntegratorException;
25 import org.apache.commons.math.ode.StepHandler;
26 import org.apache.commons.math.ode.StepInterpolator;
27 import org.apache.commons.math.ode.SwitchingFunction;
28 import org.apache.commons.math.ode.ThreeEighthesIntegrator;
29
30 public class ThreeEighthesIntegratorTest
31 extends TestCase {
32
33 public ThreeEighthesIntegratorTest(String name) {
34 super(name);
35 }
36
37 public void testDimensionCheck() {
38 try {
39 TestProblem1 pb = new TestProblem1();
40 new ThreeEighthesIntegrator(0.01).integrate(pb,
41 0.0, new double[pb.getDimension()+10],
42 1.0, new double[pb.getDimension()+10]);
43 fail("an exception should have been thrown");
44 } catch(DerivativeException de) {
45 fail("wrong exception caught");
46 } catch(IntegratorException ie) {
47 }
48 }
49
50 public void testDecreasingSteps()
51 throws DerivativeException, IntegratorException {
52
53 TestProblemAbstract[] problems = TestProblemFactory.getProblems();
54 for (int k = 0; k < problems.length; ++k) {
55
56 double previousError = Double.NaN;
57 for (int i = 4; i < 10; ++i) {
58
59 TestProblemAbstract pb = (TestProblemAbstract) problems[k].clone();
60 double step = (pb.getFinalTime() - pb.getInitialTime())
61 * Math.pow(2.0, -i);
62
63 FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step);
64 TestProblemHandler handler = new TestProblemHandler(pb, integ);
65 integ.setStepHandler(handler);
66 SwitchingFunction[] functions = pb.getSwitchingFunctions();
67 for (int l = 0; l < functions.length; ++l) {
68 integ.addSwitchingFunction(functions[l],
69 Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
70 }
71 integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
72 pb.getFinalTime(), new double[pb.getDimension()]);
73
74 double error = handler.getMaximalValueError();
75 if (i > 4) {
76 assertTrue(error < Math.abs(previousError));
77 }
78 previousError = error;
79 assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
80
81 }
82
83 }
84
85 }
86
87 public void testSmallStep()
88 throws DerivativeException, IntegratorException {
89
90 TestProblem1 pb = new TestProblem1();
91 double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001;
92
93 FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step);
94 TestProblemHandler handler = new TestProblemHandler(pb, integ);
95 integ.setStepHandler(handler);
96 integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
97 pb.getFinalTime(), new double[pb.getDimension()]);
98
99 assertTrue(handler.getLastError() < 2.0e-13);
100 assertTrue(handler.getMaximalValueError() < 4.0e-12);
101 assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
102 assertEquals("3/8", integ.getName());
103
104 }
105
106 public void testBigStep()
107 throws DerivativeException, IntegratorException {
108
109 TestProblem1 pb = new TestProblem1();
110 double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.2;
111
112 FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step);
113 TestProblemHandler handler = new TestProblemHandler(pb, integ);
114 integ.setStepHandler(handler);
115 integ.integrate(pb, pb.getInitialTime(), pb.getInitialState(),
116 pb.getFinalTime(), new double[pb.getDimension()]);
117
118 assertTrue(handler.getLastError() > 0.0004);
119 assertTrue(handler.getMaximalValueError() > 0.005);
120 assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
121
122 }
123
124 public void testKepler()
125 throws DerivativeException, IntegratorException {
126
127 final TestProblem3 pb = new TestProblem3(0.9);
128 double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003;
129
130 FirstOrderIntegrator integ = new ThreeEighthesIntegrator(step);
131 integ.setStepHandler(new KeplerHandler(pb));
132 integ.integrate(pb,
133 pb.getInitialTime(), pb.getInitialState(),
134 pb.getFinalTime(), new double[pb.getDimension()]);
135 }
136
137 private static class KeplerHandler implements StepHandler {
138
139 public KeplerHandler(TestProblem3 pb) {
140 this.pb = pb;
141 maxError = 0;
142 }
143
144 public boolean requiresDenseOutput() {
145 return false;
146 }
147
148 public void reset() {
149 maxError = 0;
150 }
151
152 public void handleStep(StepInterpolator interpolator,
153 boolean isLast) {
154
155 double[] interpolatedY = interpolator.getInterpolatedState ();
156 double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime());
157 double dx = interpolatedY[0] - theoreticalY[0];
158 double dy = interpolatedY[1] - theoreticalY[1];
159 double error = dx * dx + dy * dy;
160 if (error > maxError) {
161 maxError = error;
162 }
163 if (isLast) {
164
165
166
167 assertTrue(maxError > 0.005);
168 }
169 }
170
171 private TestProblem3 pb;
172 private double maxError = 0;
173
174 }
175
176 public static Test suite() {
177 return new TestSuite(ThreeEighthesIntegratorTest.class);
178 }
179
180 }