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