1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.hipparchus.ode.sampling;
24
25 import org.hipparchus.ode.ODEIntegrator;
26 import org.hipparchus.ode.ODEState;
27 import org.hipparchus.ode.ODEStateAndDerivative;
28 import org.hipparchus.ode.OrdinaryDifferentialEquation;
29 import org.hipparchus.ode.TestProblem3;
30 import org.hipparchus.ode.TestProblemAbstract;
31 import org.hipparchus.ode.nonstiff.DormandPrince54Integrator;
32 import org.hipparchus.util.FastMath;
33 import org.junit.Assert;
34 import org.junit.Test;
35
36
37 public class StepNormalizerTest {
38
39 @Test
40 public void testBoundariesDefault() {
41 final TestProblemAbstract pb = new TestProblem3();
42 final double range = pb.getFinalTime() - pb.getInitialTime();
43 final double stepSize = range / 5.5;
44 doTestBoundaries(pb, null, stepSize,
45 pb.getInitialTime(),
46 pb.getInitialTime() + FastMath.floor(range / stepSize) * stepSize);
47 }
48
49 @Test
50 public void testBoundariesNeither() {
51 final TestProblemAbstract pb = new TestProblem3();
52 final double range = pb.getFinalTime() - pb.getInitialTime();
53 final double stepSize = range / 5.5;
54 doTestBoundaries(pb, StepNormalizerBounds.NEITHER, stepSize,
55 pb.getInitialTime() + stepSize,
56 pb.getInitialTime() + FastMath.floor(range / stepSize) * stepSize);
57 }
58
59 @Test
60 public void testBoundariesFirst() {
61 final TestProblemAbstract pb = new TestProblem3();
62 final double range = pb.getFinalTime() - pb.getInitialTime();
63 final double stepSize = range / 5.5;
64 doTestBoundaries(pb, StepNormalizerBounds.FIRST, stepSize,
65 pb.getInitialTime(),
66 pb.getInitialTime() + FastMath.floor(range / stepSize) * stepSize);
67 }
68
69 @Test
70 public void testBoundariesLast() {
71 final TestProblemAbstract pb = new TestProblem3();
72 final double range = pb.getFinalTime() - pb.getInitialTime();
73 final double stepSize = range / 5.5;
74 doTestBoundaries(pb, StepNormalizerBounds.LAST, stepSize,
75 pb.getInitialTime() + stepSize,
76 pb.getFinalTime());
77 }
78
79 @Test
80 public void testBoundariesBoth() {
81 final TestProblemAbstract pb = new TestProblem3();
82 final double range = pb.getFinalTime() - pb.getInitialTime();
83 final double stepSize = range / 5.5;
84 doTestBoundaries(pb, StepNormalizerBounds.BOTH, stepSize,
85 pb.getInitialTime(),
86 pb.getFinalTime());
87 }
88
89 @Test
90 public void testBeforeEnd() {
91 final TestProblemAbstract pb = new TestProblem3();
92 final double range = pb.getFinalTime() - pb.getInitialTime();
93 final double stepSize = range / 10.5;
94 doTestBoundaries(pb, null, stepSize,
95 pb.getInitialTime(),
96 pb.getFinalTime() - range / 21.0);
97 }
98
99 @Test
100 public void testModeForwardMultiples() {
101 doTestStepsAtIntegerTimes(new TestProblem3(), StepNormalizerMode.MULTIPLES,
102 2.0, 7.5, 2.5, 7.5, 4.0);
103 }
104
105 @Test
106 public void testModeForwardIncrement() {
107 doTestStepsAtIntegerTimes(new TestProblem3(), StepNormalizerMode.INCREMENT,
108 2.0, 7.5, 2.5, 7.5, 3.5);
109 }
110
111 @Test
112 public void testModeBackwardMultiples() {
113 doTestStepsAtIntegerTimes(new TestProblem3(), StepNormalizerMode.MULTIPLES,
114 2.0, 2.5, 7.5, 2.5, 6.0);
115 }
116
117 @Test
118 public void testModeBackwardIncrement() {
119 doTestStepsAtIntegerTimes(new TestProblem3(), StepNormalizerMode.INCREMENT,
120 2.0, 2.5, 7.5, 2.5, 6.5);
121 }
122
123 private void doTestBoundaries(final TestProblemAbstract pb,
124 final StepNormalizerBounds bounds, final double stepSize,
125 final double expectedFirst, final double expectedLast) {
126 double minStep = 0;
127 double maxStep = pb.getFinalTime() - pb.getInitialTime();
128 ODEIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, 10.e-8, 1.0e-8);
129 final Checker checker = new Checker();
130 if (bounds == null) {
131 integ.addStepHandler(new StepNormalizer(stepSize, checker));
132 } else {
133 integ.addStepHandler(new StepNormalizer(stepSize, checker, bounds));
134 }
135 integ.integrate(pb, pb.getInitialState(), pb.getFinalTime());
136 Assert.assertEquals(expectedFirst, checker.firstTime, 1.0e-10);
137 Assert.assertEquals(expectedLast, checker.lastTime, 1.0e-10);
138 }
139
140 private void doTestStepsAtIntegerTimes(final TestProblemAbstract pb,
141 final StepNormalizerMode mode, final double stepSize,
142 final double t0, final double t1,
143 final double expectedFirst,
144 final double expectedLast) {
145 double minStep = 0;
146 double maxStep = pb.getFinalTime() - pb.getInitialTime();
147 ODEIntegrator integ = new DormandPrince54Integrator(minStep, maxStep, 10.e-8, 1.0e-8);
148 final Checker checker = new Checker();
149 integ.addStepHandler(new StepNormalizer(stepSize, checker, mode));
150 integ.integrate(new OrdinaryDifferentialEquation() {
151 public int getDimension() { return 1; }
152 public double[] computeDerivatives(double t, double[] y) { return y; }
153 }, new ODEState(t0, new double[1]), t1);
154 Assert.assertEquals(expectedFirst, checker.firstTime, 1.0e-10);
155 Assert.assertEquals(expectedLast, checker.lastTime, 1.0e-10);
156 }
157
158 private static class Checker implements ODEFixedStepHandler {
159
160 private double firstTime;
161 private double lastTime;
162
163 public void init(final ODEStateAndDerivative initialState, final double finalTime) {
164 firstTime = Double.NaN;
165 lastTime = Double.NaN;
166 }
167
168 public void handleStep(ODEStateAndDerivative s, boolean isLast) {
169 if (Double.isNaN(firstTime)) {
170 firstTime = s.getTime();
171 }
172 if (isLast) {
173 lastTime = s.getTime();
174 }
175 }
176
177 }
178
179 }