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  import java.util.Random;
22  import java.io.ByteArrayOutputStream;
23  import java.io.ByteArrayInputStream;
24  import java.io.ObjectOutputStream;
25  import java.io.ObjectInputStream;
26  import java.io.IOException;
27  
28  import org.apache.commons.math.ode.ContinuousOutputModel;
29  import org.apache.commons.math.ode.DerivativeException;
30  import org.apache.commons.math.ode.GraggBulirschStoerIntegrator;
31  import org.apache.commons.math.ode.IntegratorException;
32  
33  public class GraggBulirschStoerStepInterpolatorTest
34    extends TestCase {
35  
36    public GraggBulirschStoerStepInterpolatorTest(String name) {
37      super(name);
38    }
39  
40    public void testSerialization()
41      throws DerivativeException, IntegratorException,
42             IOException, ClassNotFoundException {
43  
44      TestProblem3 pb  = new TestProblem3(0.9);
45      double minStep   = 0;
46      double maxStep   = pb.getFinalTime() - pb.getInitialTime();
47      double absTolerance = 1.0e-8;
48      double relTolerance = 1.0e-8;
49  
50      GraggBulirschStoerIntegrator integ =
51        new GraggBulirschStoerIntegrator(minStep, maxStep,
52                                         absTolerance, relTolerance);
53      integ.setStepHandler(new ContinuousOutputModel());
54      integ.integrate(pb,
55                      pb.getInitialTime(), pb.getInitialState(),
56                      pb.getFinalTime(), new double[pb.getDimension()]);
57  
58      ByteArrayOutputStream bos = new ByteArrayOutputStream();
59      ObjectOutputStream    oos = new ObjectOutputStream(bos);
60      oos.writeObject(integ.getStepHandler());
61  
62      assertTrue(bos.size () > 34000);
63      assertTrue(bos.size () < 35000);
64  
65      ByteArrayInputStream  bis = new ByteArrayInputStream(bos.toByteArray());
66      ObjectInputStream     ois = new ObjectInputStream(bis);
67      ContinuousOutputModel cm  = (ContinuousOutputModel) ois.readObject();
68  
69      Random random = new Random(347588535632l);
70      double maxError = 0.0;
71      for (int i = 0; i < 1000; ++i) {
72        double r = random.nextDouble();
73        double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
74        cm.setInterpolatedTime(time);
75        double[] interpolatedY = cm.getInterpolatedState ();
76        double[] theoreticalY  = pb.computeTheoreticalState(time);
77        double dx = interpolatedY[0] - theoreticalY[0];
78        double dy = interpolatedY[1] - theoreticalY[1];
79        double error = dx * dx + dy * dy;
80        if (error > maxError) {
81          maxError = error;
82        }
83      }
84  
85      assertTrue(maxError < 5.0e-11);
86  
87    }
88  
89    public void testClone()
90    throws DerivativeException, IntegratorException {
91      TestProblem3 pb = new TestProblem3(0.9);
92      double minStep = 0;
93      double maxStep = pb.getFinalTime() - pb.getInitialTime();
94      double scalAbsoluteTolerance = 1.0e-8;
95      double scalRelativeTolerance = scalAbsoluteTolerance;
96      GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep,
97                                                                            scalAbsoluteTolerance,
98                                                                            scalRelativeTolerance);
99      integ.setStepHandler(new StepHandler() {
100         public void handleStep(StepInterpolator interpolator, boolean isLast)
101         throws DerivativeException {
102             StepInterpolator cloned = interpolator.copy();
103             double tA = cloned.getPreviousTime();
104             double tB = cloned.getCurrentTime();
105             double halfStep = Math.abs(tB - tA) / 2;
106             assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12);
107             assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12);
108             for (int i = 0; i < 10; ++i) {
109                 double t = (i * tB + (9 - i) * tA) / 9;
110                 interpolator.setInterpolatedTime(t);
111                 assertTrue(Math.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10));
112                 cloned.setInterpolatedTime(t);
113                 assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12);
114                 double[] referenceState = interpolator.getInterpolatedState();
115                 double[] cloneState     = cloned.getInterpolatedState();
116                 for (int j = 0; j < referenceState.length; ++j) {
117                     assertEquals(referenceState[j], cloneState[j], 1.0e-12);
118                 }
119             }
120         }
121         public boolean requiresDenseOutput() {
122             return true;
123         }
124         public void reset() {
125         }
126     });
127     integ.integrate(pb,
128             pb.getInitialTime(), pb.getInitialState(),
129             pb.getFinalTime(), new double[pb.getDimension()]);
130 
131   }
132 
133   public static Test suite() {
134     return new TestSuite(GraggBulirschStoerStepInterpolatorTest.class);
135   }
136 
137 }