1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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 HighamHall54StepInterpolatorTest {
42
43 @Test
44 public void derivativesConsistency()
45 throws DimensionMismatchException, NumberIsTooSmallException,
46 MaxCountExceededException, NoBracketingException {
47 TestProblem3 pb = new TestProblem3(0.1);
48 double minStep = 0;
49 double maxStep = pb.getFinalTime() - pb.getInitialTime();
50 double scalAbsoluteTolerance = 1.0e-8;
51 double scalRelativeTolerance = scalAbsoluteTolerance;
52 HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep,
53 scalAbsoluteTolerance,
54 scalRelativeTolerance);
55 StepInterpolatorTestUtils.checkDerivativesConsistency(integ, pb, 0.01, 4.8e-12);
56 }
57
58 @Test
59 public void serialization()
60 throws IOException, ClassNotFoundException,
61 DimensionMismatchException, NumberIsTooSmallException,
62 MaxCountExceededException, NoBracketingException {
63
64 TestProblem3 pb = new TestProblem3(0.9);
65 double minStep = 0;
66 double maxStep = pb.getFinalTime() - pb.getInitialTime();
67 double scalAbsoluteTolerance = 1.0e-8;
68 double scalRelativeTolerance = scalAbsoluteTolerance;
69 HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep,
70 scalAbsoluteTolerance,
71 scalRelativeTolerance);
72 integ.addStepHandler(new ContinuousOutputModel());
73 integ.integrate(pb,
74 pb.getInitialTime(), pb.getInitialState(),
75 pb.getFinalTime(), new double[pb.getDimension()]);
76
77 ByteArrayOutputStream bos = new ByteArrayOutputStream();
78 ObjectOutputStream oos = new ObjectOutputStream(bos);
79 for (StepHandler handler : integ.getStepHandlers()) {
80 oos.writeObject(handler);
81 }
82
83 Assert.assertTrue(bos.size () > 185000);
84 Assert.assertTrue(bos.size () < 195000);
85
86 ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
87 ObjectInputStream ois = new ObjectInputStream(bis);
88 ContinuousOutputModel cm = (ContinuousOutputModel) ois.readObject();
89
90 Random random = new Random(347588535632L);
91 double maxError = 0.0;
92 for (int i = 0; i < 1000; ++i) {
93 double r = random.nextDouble();
94 double time = r * pb.getInitialTime() + (1.0 - r) * pb.getFinalTime();
95 cm.setInterpolatedTime(time);
96 double[] interpolatedY = cm.getInterpolatedState ();
97 double[] theoreticalY = pb.computeTheoreticalState(time);
98 double dx = interpolatedY[0] - theoreticalY[0];
99 double dy = interpolatedY[1] - theoreticalY[1];
100 double error = dx * dx + dy * dy;
101 if (error > maxError) {
102 maxError = error;
103 }
104 }
105
106 Assert.assertTrue(maxError < 1.6e-10);
107 }
108
109 @Test
110 public void checkClone()
111 throws DimensionMismatchException, NumberIsTooSmallException,
112 MaxCountExceededException, NoBracketingException {
113 TestProblem3 pb = new TestProblem3(0.9);
114 double minStep = 0;
115 double maxStep = pb.getFinalTime() - pb.getInitialTime();
116 double scalAbsoluteTolerance = 1.0e-8;
117 double scalRelativeTolerance = scalAbsoluteTolerance;
118 HighamHall54Integrator integ = new HighamHall54Integrator(minStep, maxStep,
119 scalAbsoluteTolerance,
120 scalRelativeTolerance);
121 integ.addStepHandler(new StepHandler() {
122 @Override
123 public void handleStep(StepInterpolator interpolator, boolean isLast)
124 throws MaxCountExceededException {
125 StepInterpolator cloned = interpolator.copy();
126 double tA = cloned.getPreviousTime();
127 double tB = cloned.getCurrentTime();
128 double halfStep = JdkMath.abs(tB - tA) / 2;
129 Assert.assertEquals(interpolator.getPreviousTime(), tA, 1.0e-12);
130 Assert.assertEquals(interpolator.getCurrentTime(), tB, 1.0e-12);
131 for (int i = 0; i < 10; ++i) {
132 double t = (i * tB + (9 - i) * tA) / 9;
133 interpolator.setInterpolatedTime(t);
134 Assert.assertTrue(JdkMath.abs(cloned.getInterpolatedTime() - t) > (halfStep / 10));
135 cloned.setInterpolatedTime(t);
136 Assert.assertEquals(t, cloned.getInterpolatedTime(), 1.0e-12);
137 double[] referenceState = interpolator.getInterpolatedState();
138 double[] cloneState = cloned.getInterpolatedState();
139 for (int j = 0; j < referenceState.length; ++j) {
140 Assert.assertEquals(referenceState[j], cloneState[j], 1.0e-12);
141 }
142 }
143 }
144 @Override
145 public void init(double t0, double[] y0, double t) {
146 }
147 });
148 integ.integrate(pb,
149 pb.getInitialTime(), pb.getInitialState(),
150 pb.getFinalTime(), new double[pb.getDimension()]);
151 }
152 }