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.nonstiff;
19  
20  import static org.junit.Assert.assertTrue;
21  
22  import java.io.ByteArrayInputStream;
23  import java.io.ByteArrayOutputStream;
24  import java.io.IOException;
25  import java.io.ObjectInputStream;
26  import java.io.ObjectOutputStream;
27  import java.util.Random;
28  
29  import org.apache.commons.math.ode.ContinuousOutputModel;
30  import org.apache.commons.math.ode.DerivativeException;
31  import org.apache.commons.math.ode.IntegratorException;
32  import org.apache.commons.math.ode.TestProblem3;
33  import org.apache.commons.math.ode.sampling.StepHandler;
34  import org.apache.commons.math.ode.sampling.StepInterpolatorTestUtils;
35  import org.junit.Test;
36  
37  public class ClassicalRungeKuttaStepInterpolatorTest {
38  
39    @Test
40    public void derivativesConsistency()
41    throws DerivativeException, IntegratorException {
42      TestProblem3 pb = new TestProblem3();
43      double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.001;
44      ClassicalRungeKuttaIntegrator integ = new ClassicalRungeKuttaIntegrator(step);
45      StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 1.0e-10);
46    }
47  
48    @Test
49    public void serialization()
50      throws DerivativeException, IntegratorException,
51             IOException, ClassNotFoundException {
52  
53      TestProblem3 pb = new TestProblem3(0.9);
54      double step = (pb.getFinalTime() - pb.getInitialTime()) * 0.0003;
55      ClassicalRungeKuttaIntegrator integ = new ClassicalRungeKuttaIntegrator(step);
56      integ.addStepHandler(new ContinuousOutputModel());
57      integ.integrate(pb,
58                      pb.getInitialTime(), pb.getInitialState(),
59                      pb.getFinalTime(), new double[pb.getDimension()]);
60  
61      ByteArrayOutputStream bos = new ByteArrayOutputStream();
62      ObjectOutputStream    oos = new ObjectOutputStream(bos);
63      for (StepHandler handler : integ.getStepHandlers()) {
64          oos.writeObject(handler);
65      }
66  
67      assertTrue(bos.size () > 700000);
68      assertTrue(bos.size () < 701000);
69  
70      ByteArrayInputStream  bis = new ByteArrayInputStream(bos.toByteArray());
71      ObjectInputStream     ois = new ObjectInputStream(bis);
72      ContinuousOutputModel cm  = (ContinuousOutputModel) ois.readObject();
73  
74      Random random = new Random(347588535632l);
75      double maxError = 0.0;
76      for (int i = 0; i < 1000; ++i) {
77        double r = random.nextDouble();
78        double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
79        cm.setInterpolatedTime(time);
80        double[] interpolatedY = cm.getInterpolatedState ();
81        double[] theoreticalY  = pb.computeTheoreticalState(time);
82        double dx = interpolatedY[0] - theoreticalY[0];
83        double dy = interpolatedY[1] - theoreticalY[1];
84        double error = dx * dx + dy * dy;
85        if (error > maxError) {
86          maxError = error;
87        }
88      }
89  
90      assertTrue(maxError > 0.005);
91  
92    }
93  
94  }