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