1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.hipparchus.ode.nonstiff;
19
20
21 import org.hipparchus.analysis.differentiation.DerivativeStructure;
22 import org.hipparchus.ode.ODEStateAndDerivative;
23 import org.hipparchus.ode.OrdinaryDifferentialEquation;
24 import org.hipparchus.ode.sampling.AbstractODEStateInterpolator;
25 import org.hipparchus.ode.sampling.ODEStateInterpolator;
26 import org.hipparchus.util.FastMath;
27 import org.junit.Assert;
28 import org.junit.Test;
29
30 public abstract class ODEStateInterpolatorAbstractTest {
31
32 @Test
33 public abstract void interpolationAtBounds();
34
35 protected void doInterpolationAtBounds(double epsilon) {
36 ODEStateInterpolator interpolator = setUpInterpolator(new SinCos(), 0.0, new double[] { 0.0, 1.0 }, 0.125);
37
38 Assert.assertEquals(0.0, interpolator.getPreviousState().getTime(), 1.0e-15);
39 for (int i = 0; i < 2; ++i) {
40 Assert.assertEquals(interpolator.getPreviousState().getPrimaryState()[i],
41 interpolator.getInterpolatedState(interpolator.getPreviousState().getTime()).getPrimaryState()[i],
42 epsilon);
43 }
44 Assert.assertEquals(0.125, interpolator.getCurrentState().getTime(), 1.0e-15);
45 for (int i = 0; i < 2; ++i) {
46 Assert.assertEquals(interpolator.getCurrentState().getPrimaryState()[i],
47 interpolator.getInterpolatedState(interpolator.getCurrentState().getTime()).getPrimaryState()[i],
48 epsilon);
49 }
50 Assert.assertEquals(false, interpolator.isPreviousStateInterpolated());
51 Assert.assertEquals(false, interpolator.isCurrentStateInterpolated());
52 }
53
54 @Test
55 public abstract void interpolationInside();
56
57 protected void doInterpolationInside(double epsilonSin, double epsilonCos) {
58
59 SinCos sinCos = new SinCos();
60 ODEStateInterpolator interpolator = setUpInterpolator(sinCos, 0.0, new double[] { 0.0, 1.0 }, 0.0125);
61
62 int n = 100;
63 double maxErrorSin = 0;
64 double maxErrorCos = 0;
65 for (int i = 0; i <= n; ++i) {
66 double t = ((n - i) * interpolator.getPreviousState().getTime() +
67 i * interpolator.getCurrentState().getTime()) / n;
68 final double[] interpolated = interpolator.getInterpolatedState(t).getPrimaryState();
69 double[] reference = sinCos.theoreticalState(t);
70 maxErrorSin = FastMath.max(maxErrorSin, FastMath.abs(interpolated[0] - reference[0]));
71 maxErrorCos = FastMath.max(maxErrorCos, FastMath.abs(interpolated[1] - reference[1]));
72 }
73
74 Assert.assertEquals(0.0, maxErrorSin, epsilonSin);
75 Assert.assertEquals(0.0, maxErrorCos, epsilonCos);
76
77 Assert.assertEquals(false, interpolator.isPreviousStateInterpolated());
78 Assert.assertEquals(false, interpolator.isCurrentStateInterpolated());
79 }
80
81 @Test
82 public abstract void restrictPrevious();
83
84 protected void doRestrictPrevious(double epsilon, double epsilonDot) {
85
86 AbstractODEStateInterpolator original = setUpInterpolator(new SinCos(), 0.0, new double[] { 0.0, 1.0 }, 0.125);
87
88 Assert.assertEquals(false, original.isPreviousStateInterpolated());
89 Assert.assertEquals(false, original.isCurrentStateInterpolated());
90
91 AbstractODEStateInterpolator restricted = original.restrictStep(original.getInterpolatedState(1.0 / 32),
92 original.getCurrentState());
93
94 Assert.assertSame(original.getPreviousState(), original.getGlobalPreviousState());
95 Assert.assertSame(original.getCurrentState(), original.getGlobalCurrentState());
96 Assert.assertSame(original.getGlobalPreviousState(), restricted.getGlobalPreviousState());
97 Assert.assertSame(original.getGlobalCurrentState(), restricted.getGlobalCurrentState());
98 Assert.assertNotSame(restricted.getPreviousState(), restricted.getGlobalPreviousState());
99 Assert.assertSame(restricted.getCurrentState(), restricted.getGlobalCurrentState());
100 Assert.assertEquals(1.0 / 32, restricted.getPreviousState().getTime(), 1.0e-15);
101 Assert.assertEquals(true, restricted.isPreviousStateInterpolated());
102 Assert.assertEquals(false, restricted.isCurrentStateInterpolated());
103
104 checkRestricted(original, restricted, epsilon, epsilonDot);
105
106 }
107
108 @Test
109 public abstract void restrictCurrent();
110
111 protected void doRestrictCurrent(double epsilon, double epsilonDot) {
112
113 AbstractODEStateInterpolator original = setUpInterpolator(new SinCos(), 0.0, new double[] { 0.0, 1.0 }, 0.125);
114
115 Assert.assertEquals(false, original.isPreviousStateInterpolated());
116 Assert.assertEquals(false, original.isCurrentStateInterpolated());
117
118 AbstractODEStateInterpolator restricted = original.restrictStep(original.getPreviousState(),
119 original.getInterpolatedState(3.0 / 32));
120
121 Assert.assertSame(original.getPreviousState(), original.getGlobalPreviousState());
122 Assert.assertSame(original.getCurrentState(), original.getGlobalCurrentState());
123 Assert.assertSame(original.getGlobalPreviousState(), restricted.getGlobalPreviousState());
124 Assert.assertSame(original.getGlobalCurrentState(), restricted.getGlobalCurrentState());
125 Assert.assertSame(restricted.getPreviousState(), restricted.getGlobalPreviousState());
126 Assert.assertNotSame(restricted.getCurrentState(), restricted.getGlobalCurrentState());
127 Assert.assertEquals(3.0 / 32, restricted.getCurrentState().getTime(), 1.0e-15);
128 Assert.assertEquals(false, restricted.isPreviousStateInterpolated());
129 Assert.assertEquals(true, restricted.isCurrentStateInterpolated());
130
131 checkRestricted(original, restricted, epsilon, epsilonDot);
132
133 }
134
135 @Test
136 public abstract void restrictBothEnds();
137
138 protected void doRestrictBothEnds(double epsilon, double epsilonDot) {
139
140 AbstractODEStateInterpolator original = setUpInterpolator(new SinCos(), 0.0, new double[] { 0.0, 1.0 }, 0.125);
141
142 Assert.assertEquals(false, original.isPreviousStateInterpolated());
143 Assert.assertEquals(false, original.isCurrentStateInterpolated());
144
145 AbstractODEStateInterpolator restricted = original.restrictStep(original.getInterpolatedState(1.0 / 32),
146 original.getInterpolatedState(3.0 / 32));
147
148 Assert.assertSame(original.getPreviousState(), original.getGlobalPreviousState());
149 Assert.assertSame(original.getCurrentState(), original.getGlobalCurrentState());
150 Assert.assertSame(original.getGlobalPreviousState(), restricted.getGlobalPreviousState());
151 Assert.assertSame(original.getGlobalCurrentState(), restricted.getGlobalCurrentState());
152 Assert.assertNotSame(restricted.getPreviousState(), restricted.getGlobalPreviousState());
153 Assert.assertNotSame(restricted.getCurrentState(), restricted.getGlobalCurrentState());
154 Assert.assertEquals(1.0 / 32, restricted.getPreviousState().getTime(), 1.0e-15);
155 Assert.assertEquals(3.0 / 32, restricted.getCurrentState().getTime(), 1.0e-15);
156 Assert.assertEquals(true, restricted.isPreviousStateInterpolated());
157 Assert.assertEquals(true, restricted.isCurrentStateInterpolated());
158
159 checkRestricted(original, restricted, epsilon, epsilonDot);
160
161 }
162
163 @Test
164 public abstract void degenerateInterpolation();
165
166 protected void doDegenerateInterpolation() {
167 AbstractODEStateInterpolator interpolator = setUpInterpolator(new SinCos(), 0.0, new double[] { 0.0, 1.0 }, 0.0);
168 ODEStateAndDerivative interpolatedState = interpolator.getInterpolatedState(0.0);
169 Assert.assertEquals(0.0, interpolatedState.getTime(), 0.0);
170 Assert.assertEquals(0.0, interpolatedState.getPrimaryState()[0], 0.0);
171 Assert.assertEquals(1.0, interpolatedState.getPrimaryState()[1], 0.0);
172 Assert.assertEquals(1.0, interpolatedState.getPrimaryDerivative()[0], 0.0);
173 Assert.assertEquals(0.0, interpolatedState.getPrimaryDerivative()[1], 0.0);
174 }
175
176 private void checkRestricted(AbstractODEStateInterpolator original, AbstractODEStateInterpolator restricted,
177 double epsilon, double epsilonDot) {
178 for (double t = restricted.getPreviousState().getTime();
179 t <= restricted.getCurrentState().getTime();
180 t += 1.0 / 256) {
181 ODEStateAndDerivative originalInterpolated = original.getInterpolatedState(t);
182 ODEStateAndDerivative restrictedInterpolated = restricted.getInterpolatedState(t);
183 Assert.assertEquals(t, originalInterpolated.getTime(), 1.0e-15);
184 Assert.assertEquals(t, restrictedInterpolated.getTime(), 1.0e-15);
185 Assert.assertEquals(originalInterpolated.getPrimaryState()[0],
186 restrictedInterpolated.getPrimaryState()[0],
187 epsilon);
188 Assert.assertEquals(originalInterpolated.getPrimaryState()[1],
189 restrictedInterpolated.getPrimaryState()[1],
190 epsilon);
191 Assert.assertEquals(originalInterpolated.getPrimaryDerivative()[0],
192 restrictedInterpolated.getPrimaryDerivative()[0],
193 epsilonDot);
194 Assert.assertEquals(originalInterpolated.getPrimaryDerivative()[1],
195 restrictedInterpolated.getPrimaryDerivative()[1],
196 epsilonDot);
197 }
198
199 }
200
201 public interface ReferenceODE extends OrdinaryDifferentialEquation {
202 double[] theoreticalState(double t);
203 DerivativeStructure[] theoreticalState(DerivativeStructure t);
204 }
205
206 protected abstract AbstractODEStateInterpolator setUpInterpolator(final ReferenceODE eqn,
207 final double t0, final double[] y0,
208 final double t1);
209
210 private static class SinCos implements ReferenceODE {
211 public int getDimension() {
212 return 2;
213 }
214 public double[] computeDerivatives(final double t, final double[] y) {
215 return new double[] {
216 y[1], -y[0]
217 };
218 }
219 public double[] theoreticalState(final double t) {
220 return new double[] {
221 FastMath.sin(t), FastMath.cos(t)
222 };
223 }
224 public DerivativeStructure[] theoreticalState(final DerivativeStructure t) {
225 return new DerivativeStructure[] {
226 t.sin(), t.cos()
227 };
228 }
229 }
230
231 }