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