~ubuntu-branches/ubuntu/quantal/commons-math/quantal

« back to all changes in this revision

Viewing changes to src/test/org/apache/commons/math/ode/GillIntegratorTest.java

  • Committer: Bazaar Package Importer
  • Author(s): Damien Raude-Morvan
  • Date: 2009-03-15 20:20:21 UTC
  • Revision ID: james.westby@ubuntu.com-20090315202021-zto3nmvqgcf3ami4
Tags: upstream-1.2
ImportĀ upstreamĀ versionĀ 1.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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
 
8
 *
 
9
 *      http://www.apache.org/licenses/LICENSE-2.0
 
10
 *
 
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.
 
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
        // even with more than 1000 evaluations per period,
 
171
        // RK4 is not able to integrate such an eccentric
 
172
        // orbit with a good accuracy
 
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
}