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.EulerIntegrator;
24  import org.apache.commons.math.ode.FirstOrderIntegrator;
25  import org.apache.commons.math.ode.IntegratorException;
26  import org.apache.commons.math.ode.SwitchingFunction;
27  
28  public class EulerIntegratorTest
29    extends TestCase {
30  
31    public EulerIntegratorTest(String name) {
32      super(name);
33    }
34  
35    public void testDimensionCheck() {
36      try  {
37        TestProblem1 pb = new TestProblem1();
38        new EulerIntegrator(0.01).integrate(pb,
39                                            0.0, new double[pb.getDimension()+10],
40                                            1.0, new double[pb.getDimension()+10]);
41          fail("an exception should have been thrown");
42      } catch(DerivativeException de) {
43        fail("wrong exception caught");
44      } catch(IntegratorException ie) {
45      }
46    }
47    
48    public void testDecreasingSteps()
49      throws DerivativeException, IntegratorException {
50  
51      TestProblemAbstract[] problems = TestProblemFactory.getProblems();
52      for (int k = 0; k < problems.length; ++k) {
53  
54        double previousError = Double.NaN;
55        for (int i = 4; i < 10; ++i) {
56  
57          TestProblemAbstract pb  = (TestProblemAbstract) problems[k].clone();
58          double step = (pb.getFinalTime() - pb.getInitialTime())
59            * Math.pow(2.0, -i);
60  
61          FirstOrderIntegrator integ = new EulerIntegrator(step);
62          TestProblemHandler handler = new TestProblemHandler(pb, integ);
63          integ.setStepHandler(handler);
64          SwitchingFunction[] functions = pb.getSwitchingFunctions();
65          for (int l = 0; l < functions.length; ++l) {
66            integ.addSwitchingFunction(functions[l],
67                                       Double.POSITIVE_INFINITY, 1.0e-6 * step, 1000);
68          }
69          integ.integrate(pb,
70                          pb.getInitialTime(), pb.getInitialState(),
71                          pb.getFinalTime(), new double[pb.getDimension()]);
72  
73          double error = handler.getMaximalValueError();
74          if (i > 4) {
75            assertTrue(error < Math.abs(previousError));
76          }
77          previousError = error;
78          assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
79  
80        }
81  
82      }
83  
84    }
85  
86    public void testSmallStep()
87      throws DerivativeException, IntegratorException {
88  
89      TestProblem1 pb  = new TestProblem1();
90      double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001;
91  
92      FirstOrderIntegrator integ = new EulerIntegrator(step);
93      TestProblemHandler handler = new TestProblemHandler(pb, integ);
94      integ.setStepHandler(handler);
95      integ.integrate(pb,
96                      pb.getInitialTime(), pb.getInitialState(),
97                      pb.getFinalTime(), new double[pb.getDimension()]);
98  
99     assertTrue(handler.getLastError() < 2.0e-4);
100    assertTrue(handler.getMaximalValueError() < 1.0e-3);
101    assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
102    assertEquals("Euler", 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 EulerIntegrator(step);
113     TestProblemHandler handler = new TestProblemHandler(pb, integ);
114     integ.setStepHandler(handler);
115     integ.integrate(pb,
116                     pb.getInitialTime(), pb.getInitialState(),
117                     pb.getFinalTime(), new double[pb.getDimension()]);
118 
119     assertTrue(handler.getLastError() > 0.01);
120     assertTrue(handler.getMaximalValueError() > 0.2);
121     assertEquals(0, handler.getMaximalTimeError(), 1.0e-12);
122 
123   }
124   
125   public static Test suite() {
126     return new TestSuite(EulerIntegratorTest.class);
127   }
128 
129 }