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.GillIntegrator;
25 import org.apache.commons.math.ode.IntegratorException;
26 import org.apache.commons.math.ode.StepHandler;
27 import org.apache.commons.math.ode.StepInterpolator;
28 import org.apache.commons.math.ode.SwitchingFunction;
29
30 public class GillIntegratorTest
31 extends TestCase {
32
33 public GillIntegratorTest(String name) {
34 super(name);
35 }
36
37 public void testDimensionCheck() {
38 try {
39 TestProblem1 pb = new TestProblem1();
40 new GillIntegrator(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 = 5; 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 GillIntegrator(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 > 5) {
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 GillIntegrator(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("Gill", 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 GillIntegrator(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 GillIntegrator(step);
131 integ.setStepHandler(new KeplerStepHandler(pb));
132 integ.integrate(pb,
133 pb.getInitialTime(), pb.getInitialState(),
134 pb.getFinalTime(), new double[pb.getDimension()]);
135 }
136
137 public void testUnstableDerivative()
138 throws DerivativeException, IntegratorException {
139 final StepProblem stepProblem = new StepProblem(0.0, 1.0, 2.0);
140 FirstOrderIntegrator integ = new GillIntegrator(0.3);
141 integ.addSwitchingFunction(stepProblem, 1.0, 1.0e-12, 1000);
142 double[] y = { Double.NaN };
143 integ.integrate(stepProblem, 0.0, new double[] { 0.0 }, 10.0, y);
144 assertEquals(8.0, y[0], 1.0e-12);
145 }
146
147 private static class KeplerStepHandler implements StepHandler {
148 public KeplerStepHandler(TestProblem3 pb) {
149 this.pb = pb;
150 reset();
151 }
152 public boolean requiresDenseOutput() {
153 return false;
154 }
155 public void reset() {
156 maxError = 0;
157 }
158 public void handleStep(StepInterpolator interpolator,
159 boolean isLast) {
160
161 double[] interpolatedY = interpolator.getInterpolatedState ();
162 double[] theoreticalY = pb.computeTheoreticalState(interpolator.getCurrentTime());
163 double dx = interpolatedY[0] - theoreticalY[0];
164 double dy = interpolatedY[1] - theoreticalY[1];
165 double error = dx * dx + dy * dy;
166 if (error > maxError) {
167 maxError = error;
168 }
169 if (isLast) {
170
171
172
173 assertTrue(maxError > 0.001);
174 }
175 }
176 private double maxError;
177 private TestProblem3 pb;
178 }
179
180 public static Test suite() {
181 return new TestSuite(GillIntegratorTest.class);
182 }
183
184 }