View Javadoc
1   /*
2    * Licensed to the Hipparchus project under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The Hipparchus project licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      https://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  
18  package org.hipparchus.ode.sampling;
19  
20  import org.hipparchus.exception.MathIllegalArgumentException;
21  import org.hipparchus.exception.MathIllegalStateException;
22  import org.hipparchus.ode.ODEIntegrator;
23  import org.hipparchus.ode.ODEState;
24  import org.hipparchus.ode.ODEStateAndDerivative;
25  import org.hipparchus.ode.OrdinaryDifferentialEquation;
26  import org.hipparchus.ode.nonstiff.GraggBulirschStoerIntegrator;
27  import org.junit.jupiter.api.Test;
28  
29  import java.util.ArrayList;
30  import java.util.List;
31  
32  import static org.junit.jupiter.api.Assertions.assertArrayEquals;
33  
34  /** Base class for step normalizer output tests. */
35  public abstract class StepNormalizerOutputTestBase
36      implements OrdinaryDifferentialEquation, ODEFixedStepHandler {
37  
38      /** The normalized output time values. */
39      private List<Double> output;
40  
41      /**
42       * Returns the start time.
43       * @return the start time
44       */
45      protected abstract double getStart();
46  
47      /**
48       * Returns the end time.
49       * @return the end time
50       */
51      protected abstract double getEnd();
52  
53      /**
54       * Returns the expected normalized output time values for increment mode.
55       * @return the expected normalized output time values for increment mode
56       */
57      protected abstract double[] getExpInc();
58  
59      /**
60       * Returns the expected reversed normalized output time values for
61       * increment mode.
62       * @return the expected reversed normalized output time values for
63       * increment mode
64       */
65      protected abstract double[] getExpIncRev();
66  
67      /**
68       * Returns the expected normalized output time values for multiples mode.
69       * @return the expected normalized output time values for multiples mode
70       */
71      protected abstract double[] getExpMul();
72  
73      /**
74       * Returns the expected reversed normalized output time values for
75       * multiples mode.
76       * @return the expected reversed normalized output time values for
77       * multiples mode
78       */
79      protected abstract double[] getExpMulRev();
80  
81      /**
82       * Returns the offsets for the unit tests below, in the order they are
83       * given below. For each test, the left and right offsets are returned.
84       * @return the offsets for the unit tests below, in the order they are
85       * given below
86       */
87      protected abstract int[][] getO();
88  
89      /**
90       * Get the array, given left and right offsets.
91       * @param a the input array
92       * @param offsetL the left side offset
93       * @param offsetR the right side offset
94       * @return the modified array
95       */
96      private double[] getArray(double[] a, int offsetL, int offsetR) {
97          double[] copy = new double[a.length - offsetR - offsetL];
98          System.arraycopy(a, offsetL, copy, 0, copy.length);
99          return copy;
100     }
101 
102     @Test
103     public void testIncNeither()
104         throws MathIllegalArgumentException, MathIllegalStateException {
105         double[] exp = getArray(getExpInc(), getO()[0][0], getO()[0][1]);
106         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.NEITHER, exp, false);
107     }
108 
109     @Test
110     public void testIncNeitherRev()
111         throws MathIllegalArgumentException, MathIllegalStateException {
112         double[] exp = getArray(getExpIncRev(), getO()[1][0], getO()[1][1]);
113         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.NEITHER, exp, true);
114     }
115 
116     @Test
117     public void testIncFirst()
118         throws MathIllegalArgumentException, MathIllegalStateException {
119         double[] exp = getArray(getExpInc(), getO()[2][0], getO()[2][1]);
120         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.FIRST, exp, false);
121     }
122 
123     @Test
124     public void testIncFirstRev()
125         throws MathIllegalArgumentException, MathIllegalStateException {
126         double[] exp = getArray(getExpIncRev(), getO()[3][0], getO()[3][1]);
127         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.FIRST, exp, true);
128     }
129 
130     @Test
131     public void testIncLast()
132         throws MathIllegalArgumentException, MathIllegalStateException {
133         double[] exp = getArray(getExpInc(), getO()[4][0], getO()[4][1]);
134         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.LAST, exp, false);
135     }
136 
137     @Test
138     public void testIncLastRev()
139         throws MathIllegalArgumentException, MathIllegalStateException {
140         double[] exp = getArray(getExpIncRev(), getO()[5][0], getO()[5][1]);
141         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.LAST, exp, true);
142     }
143 
144     @Test
145     public void testIncBoth()
146         throws MathIllegalArgumentException, MathIllegalStateException {
147         double[] exp = getArray(getExpInc(), getO()[6][0], getO()[6][1]);
148         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.BOTH, exp, false);
149     }
150 
151     @Test
152     public void testIncBothRev()
153         throws MathIllegalArgumentException, MathIllegalStateException {
154         double[] exp = getArray(getExpIncRev(), getO()[7][0], getO()[7][1]);
155         doTest(StepNormalizerMode.INCREMENT, StepNormalizerBounds.BOTH, exp, true);
156     }
157 
158     @Test
159     public void testMulNeither()
160         throws MathIllegalArgumentException, MathIllegalStateException {
161         double[] exp = getArray(getExpMul(), getO()[8][0], getO()[8][1]);
162         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.NEITHER, exp, false);
163     }
164 
165     @Test
166     public void testMulNeitherRev()
167         throws MathIllegalArgumentException, MathIllegalStateException {
168         double[] exp = getArray(getExpMulRev(), getO()[9][0], getO()[9][1]);
169         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.NEITHER, exp, true);
170     }
171 
172     @Test
173     public void testMulFirst()
174         throws MathIllegalArgumentException, MathIllegalStateException {
175         double[] exp = getArray(getExpMul(), getO()[10][0], getO()[10][1]);
176         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.FIRST, exp, false);
177     }
178 
179     @Test
180     public void testMulFirstRev()
181         throws MathIllegalArgumentException, MathIllegalStateException {
182         double[] exp = getArray(getExpMulRev(), getO()[11][0], getO()[11][1]);
183         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.FIRST, exp, true);
184     }
185 
186     @Test
187     public void testMulLast()
188         throws MathIllegalArgumentException, MathIllegalStateException {
189         double[] exp = getArray(getExpMul(), getO()[12][0], getO()[12][1]);
190         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.LAST, exp, false);
191     }
192 
193     @Test
194     public void testMulLastRev()
195         throws MathIllegalArgumentException, MathIllegalStateException {
196         double[] exp = getArray(getExpMulRev(), getO()[13][0], getO()[13][1]);
197         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.LAST, exp, true);
198     }
199 
200     @Test
201     public void testMulBoth()
202         throws MathIllegalArgumentException, MathIllegalStateException {
203         double[] exp = getArray(getExpMul(), getO()[14][0], getO()[14][1]);
204         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.BOTH, exp, false);
205     }
206 
207     @Test
208     public void testMulBothRev()
209         throws MathIllegalArgumentException, MathIllegalStateException {
210         double[] exp = getArray(getExpMulRev(), getO()[15][0], getO()[15][1]);
211         doTest(StepNormalizerMode.MULTIPLES, StepNormalizerBounds.BOTH, exp, true);
212     }
213 
214     /**
215      * The actual step normalizer output test code, shared by all the unit
216      * tests.
217      *
218      * @param mode the step normalizer mode to use
219      * @param bounds the step normalizer bounds setting to use
220      * @param expected the expected output (normalized time points)
221      * @param reverse whether to reverse the integration direction
222      * @throws MathIllegalArgumentException
223      * @throws MathIllegalStateException
224      * @throws MathIllegalArgumentException
225      * @throws MathIllegalArgumentException
226      */
227     private void doTest(StepNormalizerMode mode, StepNormalizerBounds bounds,
228                         double[] expected, boolean reverse)
229         throws MathIllegalArgumentException, MathIllegalStateException {
230         // Forward test.
231         ODEIntegrator integ = new GraggBulirschStoerIntegrator(1e-8, 1.0, 1e-5, 1e-5);
232         integ.addStepHandler(new StepNormalizer(0.5, this, mode, bounds));
233         double[] y   = {0.0};
234         double start = reverse ? getEnd()   : getStart();
235         double end   = reverse ? getStart() : getEnd();
236         output       = new ArrayList<Double>();
237         integ.integrate(this, new ODEState(start, y), end);
238         double[] actual = new double[output.size()];
239         for(int i = 0; i < actual.length; i++) {
240             actual[i] = output.get(i);
241         }
242         assertArrayEquals(expected, actual, 1e-5);
243     }
244 
245     /** {@inheritDoc} */
246     public int getDimension() {
247         return 1;
248     }
249 
250     /** {@inheritDoc} */
251     public double[] computeDerivatives(double t, double[] y) {
252         return y;
253     }
254 
255     /** {@inheritDoc} */
256     public void handleStep(ODEStateAndDerivative s, boolean isLast) {
257         output.add(s.getTime());
258     }
259 
260 }