View Javadoc
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.math4.legacy.ode.nonstiff;
19  
20  
21  import java.io.ByteArrayInputStream;
22  import java.io.ByteArrayOutputStream;
23  import java.io.IOException;
24  import java.io.ObjectInputStream;
25  import java.io.ObjectOutputStream;
26  import java.util.Random;
27  
28  import org.apache.commons.math4.legacy.exception.DimensionMismatchException;
29  import org.apache.commons.math4.legacy.exception.MaxCountExceededException;
30  import org.apache.commons.math4.legacy.exception.NoBracketingException;
31  import org.apache.commons.math4.legacy.exception.NumberIsTooSmallException;
32  import org.apache.commons.math4.legacy.ode.ContinuousOutputModel;
33  import org.apache.commons.math4.legacy.ode.TestProblem3;
34  import org.apache.commons.math4.legacy.ode.sampling.StepHandler;
35  import org.apache.commons.math4.legacy.ode.sampling.StepInterpolator;
36  import org.apache.commons.math4.legacy.ode.sampling.StepInterpolatorTestUtils;
37  import org.apache.commons.math4.core.jdkmath.JdkMath;
38  import org.junit.Assert;
39  import org.junit.Test;
40  
41  public class GraggBulirschStoerStepInterpolatorTest {
42  
43    @Test
44    public void derivativesConsistency()
45        throws DimensionMismatchException, NumberIsTooSmallException,
46               MaxCountExceededException, NoBracketingException {
47      TestProblem3 pb = new TestProblem3(0.9);
48      double minStep   = 0;
49      double maxStep   = pb.getFinalTime() - pb.getInitialTime();
50      double absTolerance = 1.0e-8;
51      double relTolerance = 1.0e-8;
52  
53      GraggBulirschStoerIntegrator integ =
54        new GraggBulirschStoerIntegrator(minStep, maxStep,
55                                         absTolerance, relTolerance);
56      StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 0.01, 5.9e-10);
57    }
58  
59    @Test
60    public void serialization()
61      throws IOException, ClassNotFoundException,
62             DimensionMismatchException, NumberIsTooSmallException,
63             MaxCountExceededException, NoBracketingException {
64  
65      TestProblem3 pb  = new TestProblem3(0.9);
66      double minStep   = 0;
67      double maxStep   = pb.getFinalTime() - pb.getInitialTime();
68      double absTolerance = 1.0e-8;
69      double relTolerance = 1.0e-8;
70  
71      GraggBulirschStoerIntegrator integ =
72        new GraggBulirschStoerIntegrator(minStep, maxStep,
73                                         absTolerance, relTolerance);
74      integ.addStepHandler(new ContinuousOutputModel());
75      integ.integrate(pb,
76                      pb.getInitialTime(), pb.getInitialState(),
77                      pb.getFinalTime(), new double[pb.getDimension()]);
78  
79      ByteArrayOutputStream bos = new ByteArrayOutputStream();
80      ObjectOutputStream    oos = new ObjectOutputStream(bos);
81      for (StepHandler handler : integ.getStepHandlers()) {
82          oos.writeObject(handler);
83      }
84  
85      Assert.assertTrue(bos.size () > 35000);
86      Assert.assertTrue(bos.size () < 36000);
87  
88      ByteArrayInputStream  bis = new ByteArrayInputStream(bos.toByteArray());
89      ObjectInputStream     ois = new ObjectInputStream(bis);
90      ContinuousOutputModel cm  = (ContinuousOutputModel) ois.readObject();
91  
92      Random random = new Random(347588535632L);
93      double maxError = 0.0;
94      for (int i = 0; i < 1000; ++i) {
95        double r = random.nextDouble();
96        double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
97        cm.setInterpolatedTime(time);
98        double[] interpolatedY = cm.getInterpolatedState ();
99        double[] theoreticalY  = pb.computeTheoreticalState(time);
100       double dx = interpolatedY[0] - theoreticalY[0];
101       double dy = interpolatedY[1] - theoreticalY[1];
102       double error = dx * dx + dy * dy;
103       if (error > maxError) {
104         maxError = error;
105       }
106     }
107 
108     Assert.assertTrue(maxError < 5.0e-10);
109   }
110 
111   @Test
112   public void checklone()
113       throws DimensionMismatchException, NumberIsTooSmallException,
114              MaxCountExceededException, NoBracketingException {
115     TestProblem3 pb = new TestProblem3(0.9);
116     double minStep = 0;
117     double maxStep = pb.getFinalTime() - pb.getInitialTime();
118     double scalAbsoluteTolerance = 1.0e-8;
119     double scalRelativeTolerance = scalAbsoluteTolerance;
120     GraggBulirschStoerIntegrator integ = new GraggBulirschStoerIntegrator(minStep, maxStep,
121                                                                           scalAbsoluteTolerance,
122                                                                           scalRelativeTolerance);
123     integ.addStepHandler(new StepHandler() {
124         @Override
125         public void handleStep(StepInterpolator interpolator, boolean isLast)
126             throws MaxCountExceededException {
127             StepInterpolator cloned = interpolator.copy();
128             double tA = cloned.getPreviousTime();
129             double tB = cloned.getCurrentTime();
130             double halfStep = JdkMath.abs(tB - tA) / 2;
131             Assert.assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12);
132             Assert.assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12);
133             for (int i = 0; i < 10; ++i) {
134                 double t = (i * tB + (9 - i) * tA) / 9;
135                 interpolator.setInterpolatedTime(t);
136                 Assert.assertTrue(JdkMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10));
137                 cloned.setInterpolatedTime(t);
138                 Assert.assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12);
139                 double[] referenceState = interpolator.getInterpolatedState();
140                 double[] cloneState     = cloned.getInterpolatedState();
141                 for (int j = 0; j < referenceState.length; ++j) {
142                     Assert.assertEquals(referenceState[j], cloneState[j], 1.0e-12);
143                 }
144             }
145         }
146         @Override
147         public void init(double t0, double[] y0, double t) {
148         }
149     });
150     integ.integrate(pb,
151             pb.getInitialTime(), pb.getInitialState(),
152             pb.getFinalTime(), new double[pb.getDimension()]);
153   }
154 }