View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) 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 ASF 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  /*
19   * This is not the original file distributed by the Apache Software Foundation
20   * It has been modified by the Hipparchus project
21   */
22  
23  package org.hipparchus.ode;
24  
25  
26  import org.hipparchus.Field;
27  import org.hipparchus.CalculusFieldElement;
28  import org.hipparchus.exception.MathIllegalArgumentException;
29  import org.hipparchus.util.Binary64Field;
30  import org.hipparchus.util.MathArrays;
31  import org.junit.Assert;
32  import org.junit.Test;
33  
34  public class FieldExpandableODETest {
35  
36      @Test
37      public void testOnlyMainEquation() {
38          doTestOnlyMainEquation(Binary64Field.getInstance());
39      }
40  
41      private <T extends CalculusFieldElement<T>> void doTestOnlyMainEquation(final Field<T> field) {
42          FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
43          FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
44          Assert.assertEquals(main.getDimension(), equation.getMapper().getTotalDimension());
45          Assert.assertEquals(1, equation.getMapper().getNumberOfEquations());
46          T t0 = field.getZero().add(10);
47          T t  = field.getZero().add(100);
48          T[] complete    = MathArrays.buildArray(field, equation.getMapper().getTotalDimension());
49          for (int i = 0; i < complete.length; ++i) {
50              complete[i] = field.getZero().add(i);
51          }
52          T[] completeDot = equation.computeDerivatives(t0, complete);
53          equation.init(equation.getMapper().mapStateAndDerivative(t0, complete, completeDot), t);
54          FieldODEStateAndDerivative<T> state = equation.getMapper().mapStateAndDerivative(t0, complete, completeDot);
55          Assert.assertEquals(0, state.getNumberOfSecondaryStates());
56          T[] mainState    = state.getPrimaryState();
57          T[] mainStateDot = state.getPrimaryDerivative();
58          Assert.assertEquals(main.getDimension(), mainState.length);
59          for (int i = 0; i < main.getDimension(); ++i) {
60              Assert.assertEquals(i, mainState[i].getReal(),   1.0e-15);
61              Assert.assertEquals(i, mainStateDot[i].getReal(), 1.0e-15);
62              Assert.assertEquals(i, completeDot[i].getReal(),  1.0e-15);
63          }
64      }
65  
66      @Test
67      public void testPrimaryAndSecondary() {
68          doTestPrimaryAndSecondary(Binary64Field.getInstance());
69      }
70  
71      private <T extends CalculusFieldElement<T>> void doTestPrimaryAndSecondary(final Field<T> field) {
72  
73          FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
74          FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
75          FieldSecondaryODE<T> secondary1 = new Linear<T>(field, 3, main.getDimension());
76          int i1 = equation.addSecondaryEquations(secondary1);
77          FieldSecondaryODE<T> secondary2 = new Linear<T>(field, 5, main.getDimension() + secondary1.getDimension());
78          int i2 = equation.addSecondaryEquations(secondary2);
79          Assert.assertEquals(main.getDimension() + secondary1.getDimension() + secondary2.getDimension(),
80                              equation.getMapper().getTotalDimension());
81          Assert.assertEquals(3, equation.getMapper().getNumberOfEquations());
82          Assert.assertEquals(1, i1);
83          Assert.assertEquals(2, i2);
84  
85          T t0 = field.getZero().add(10);
86          T t  = field.getZero().add(100);
87          T[] complete    = MathArrays.buildArray(field, equation.getMapper().getTotalDimension());
88          for (int i = 0; i < complete.length; ++i) {
89              complete[i] = field.getZero().add(i);
90          }
91          T[] completeDot = equation.computeDerivatives(t0, complete);
92          equation.init(equation.getMapper().mapStateAndDerivative(t0, complete, completeDot), t);
93  
94          T[] mainState    = equation.getMapper().extractEquationData(0,  complete);
95          T[] mainStateDot = equation.getMapper().extractEquationData(0,  completeDot);
96          Assert.assertEquals(main.getDimension(), mainState.length);
97          for (int i = 0; i < main.getDimension(); ++i) {
98              Assert.assertEquals(i, mainState[i].getReal(),   1.0e-15);
99              Assert.assertEquals(i, mainStateDot[i].getReal(), 1.0e-15);
100             Assert.assertEquals(i, completeDot[i].getReal(),  1.0e-15);
101         }
102 
103         T[] secondaryState1    = equation.getMapper().extractEquationData(i1,  complete);
104         T[] secondaryState1Dot = equation.getMapper().extractEquationData(i1,  completeDot);
105         Assert.assertEquals(secondary1.getDimension(), secondaryState1.length);
106         for (int i = 0; i < secondary1.getDimension(); ++i) {
107             Assert.assertEquals(i + main.getDimension(), secondaryState1[i].getReal(),   1.0e-15);
108             Assert.assertEquals(-i, secondaryState1Dot[i].getReal(), 1.0e-15);
109             Assert.assertEquals(-i, completeDot[i + main.getDimension()].getReal(),  1.0e-15);
110         }
111 
112         T[] secondaryState2    = equation.getMapper().extractEquationData(i2,  complete);
113         T[] secondaryState2Dot = equation.getMapper().extractEquationData(i2,  completeDot);
114         Assert.assertEquals(secondary2.getDimension(), secondaryState2.length);
115         for (int i = 0; i < secondary2.getDimension(); ++i) {
116             Assert.assertEquals(i + main.getDimension() + secondary1.getDimension(), secondaryState2[i].getReal(),   1.0e-15);
117             Assert.assertEquals(-i, secondaryState2Dot[i].getReal(), 1.0e-15);
118             Assert.assertEquals(-i, completeDot[i + main.getDimension() + secondary1.getDimension()].getReal(),  1.0e-15);
119         }
120 
121     }
122 
123     @Test
124     public void testMap() {
125         doTestMap(Binary64Field.getInstance());
126     }
127 
128     private <T extends CalculusFieldElement<T>> void doTestMap(final Field<T> field) {
129 
130         FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
131         FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
132         FieldSecondaryODE<T> secondary1 = new Linear<T>(field, 3, main.getDimension());
133         int i1 = equation.addSecondaryEquations(secondary1);
134         FieldSecondaryODE<T> secondary2 = new Linear<T>(field, 5, main.getDimension() + secondary1.getDimension());
135         int i2 = equation.addSecondaryEquations(secondary2);
136         Assert.assertEquals(main.getDimension() + secondary1.getDimension() + secondary2.getDimension(),
137                             equation.getMapper().getTotalDimension());
138         Assert.assertEquals(3, equation.getMapper().getNumberOfEquations());
139         Assert.assertEquals(1, i1);
140         Assert.assertEquals(2, i2);
141 
142         T t0 = field.getZero().add(10);
143         T t  = field.getZero().add(100);
144         T[] complete    = MathArrays.buildArray(field, equation.getMapper().getTotalDimension());
145         for (int i = 0; i < complete.length; ++i) {
146             complete[i]    = field.getZero().add(i);
147         }
148         T[] completeDot = equation.computeDerivatives(t0, complete);
149         equation.init(equation.getMapper().mapStateAndDerivative(t0, complete, completeDot), t);
150 
151         try {
152             equation.getMapper().mapStateAndDerivative(t0, MathArrays.buildArray(field, complete.length + 1), completeDot);
153             Assert.fail("an exception should have been thrown");
154         } catch (MathIllegalArgumentException dme) {
155             // expected
156         }
157         try {
158             equation.getMapper().mapStateAndDerivative(t0, complete, MathArrays.buildArray(field, completeDot.length + 1));
159             Assert.fail("an exception should have been thrown");
160         } catch (MathIllegalArgumentException dme) {
161             // expected
162         }
163         FieldODEStateAndDerivative<T> state = equation.getMapper().mapStateAndDerivative(t0, complete, completeDot);
164         Assert.assertEquals(2, state.getNumberOfSecondaryStates());
165         Assert.assertEquals(main.getDimension(),       state.getSecondaryStateDimension(0));
166         Assert.assertEquals(secondary1.getDimension(), state.getSecondaryStateDimension(i1));
167         Assert.assertEquals(secondary2.getDimension(), state.getSecondaryStateDimension(i2));
168 
169         T[] mainState             = state.getPrimaryState();
170         T[] mainStateDot          = state.getPrimaryDerivative();
171         T[] mainStateAlternate    = state.getSecondaryState(0);
172         T[] mainStateDotAlternate = state.getSecondaryDerivative(0);
173         Assert.assertEquals(main.getDimension(), mainState.length);
174         for (int i = 0; i < main.getDimension(); ++i) {
175             Assert.assertEquals(i, mainState[i].getReal(),             1.0e-15);
176             Assert.assertEquals(i, mainStateDot[i].getReal(),          1.0e-15);
177             Assert.assertEquals(i, mainStateAlternate[i].getReal(),    1.0e-15);
178             Assert.assertEquals(i, mainStateDotAlternate[i].getReal(), 1.0e-15);
179             Assert.assertEquals(i, completeDot[i].getReal(),           1.0e-15);
180         }
181 
182         T[] secondaryState1    = state.getSecondaryState(i1);
183         T[] secondaryState1Dot = state.getSecondaryDerivative(i1);
184         Assert.assertEquals(secondary1.getDimension(), secondaryState1.length);
185         for (int i = 0; i < secondary1.getDimension(); ++i) {
186             Assert.assertEquals(i + main.getDimension(), secondaryState1[i].getReal(),   1.0e-15);
187             Assert.assertEquals(-i, secondaryState1Dot[i].getReal(), 1.0e-15);
188             Assert.assertEquals(-i, completeDot[i + main.getDimension()].getReal(),  1.0e-15);
189         }
190 
191         T[] secondaryState2    = state.getSecondaryState(i2);
192         T[] secondaryState2Dot = state.getSecondaryDerivative(i2);
193         Assert.assertEquals(secondary2.getDimension(), secondaryState2.length);
194         for (int i = 0; i < secondary2.getDimension(); ++i) {
195             Assert.assertEquals(i + main.getDimension() + secondary1.getDimension(), secondaryState2[i].getReal(),   1.0e-15);
196             Assert.assertEquals(-i, secondaryState2Dot[i].getReal(), 1.0e-15);
197             Assert.assertEquals(-i, completeDot[i + main.getDimension() + secondary1.getDimension()].getReal(),  1.0e-15);
198         }
199 
200         T[] remappedState = state.getCompleteState();
201         T[] remappedDerivative = state.getCompleteDerivative();
202         Assert.assertEquals(equation.getMapper().getTotalDimension(), remappedState.length);
203         Assert.assertEquals(equation.getMapper().getTotalDimension(), remappedDerivative.length);
204         for (int i = 0; i < remappedState.length; ++i) {
205             Assert.assertEquals(complete[i].getReal(),    remappedState[i].getReal(),      1.0e-15);
206             Assert.assertEquals(completeDot[i].getReal(), remappedDerivative[i].getReal(), 1.0e-15);
207         }
208     }
209 
210     @Test(expected=MathIllegalArgumentException.class)
211     public void testExtractDimensionMismatch() {
212         doTestExtractDimensionMismatch(Binary64Field.getInstance());
213     }
214 
215     private <T extends CalculusFieldElement<T>> void doTestExtractDimensionMismatch(final Field<T> field)
216         throws MathIllegalArgumentException {
217 
218         FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
219         FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
220         FieldSecondaryODE<T> secondary1 = new Linear<T>(field, 3, main.getDimension());
221         int i1 = equation.addSecondaryEquations(secondary1);
222         T[] tooShort    = MathArrays.buildArray(field, main.getDimension());
223         equation.getMapper().extractEquationData(i1, tooShort);
224     }
225 
226     @Test(expected=MathIllegalArgumentException.class)
227     public void testInsertTooShortComplete() {
228         doTestInsertTooShortComplete(Binary64Field.getInstance());
229     }
230 
231     private <T extends CalculusFieldElement<T>> void doTestInsertTooShortComplete(final Field<T> field)
232         throws MathIllegalArgumentException {
233 
234         FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
235         FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
236         FieldSecondaryODE<T> secondary1 = new Linear<T>(field, 3, main.getDimension());
237         int i1 = equation.addSecondaryEquations(secondary1);
238         T[] equationData = MathArrays.buildArray(field, secondary1.getDimension());
239         T[] tooShort     = MathArrays.buildArray(field, main.getDimension());
240         equation.getMapper().insertEquationData(i1, equationData, tooShort);
241     }
242 
243     @Test(expected=MathIllegalArgumentException.class)
244     public void testInsertWrongEquationData() {
245         doTestInsertWrongEquationData(Binary64Field.getInstance());
246     }
247 
248     private <T extends CalculusFieldElement<T>> void doTestInsertWrongEquationData(final Field<T> field)
249         throws MathIllegalArgumentException {
250 
251         FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
252         FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
253         FieldSecondaryODE<T> secondary1 = new Linear<T>(field, 3, main.getDimension());
254         int i1 = equation.addSecondaryEquations(secondary1);
255         T[] wrongEquationData = MathArrays.buildArray(field, secondary1.getDimension() + 1);
256         T[] complete          = MathArrays.buildArray(field, equation.getMapper().getTotalDimension());
257         equation.getMapper().insertEquationData(i1, wrongEquationData, complete);
258     }
259 
260     @Test(expected=MathIllegalArgumentException.class)
261     public void testNegativeIndex() {
262         doTestNegativeIndex(Binary64Field.getInstance());
263     }
264 
265     private <T extends CalculusFieldElement<T>> void doTestNegativeIndex(final Field<T> field)
266         throws MathIllegalArgumentException {
267 
268         FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
269         FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
270         T[] complete = MathArrays.buildArray(field, equation.getMapper().getTotalDimension());
271         equation.getMapper().extractEquationData(-1, complete);
272     }
273 
274     @Test(expected=MathIllegalArgumentException.class)
275     public void testTooLargeIndex() {
276         doTestTooLargeIndex(Binary64Field.getInstance());
277     }
278 
279     private <T extends CalculusFieldElement<T>> void doTestTooLargeIndex(final Field<T> field)
280         throws MathIllegalArgumentException {
281 
282         FieldOrdinaryDifferentialEquation<T> main = new Linear<T>(field, 3, 0);
283         FieldExpandableODE<T> equation = new FieldExpandableODE<T>(main);
284         T[] complete = MathArrays.buildArray(field, equation.getMapper().getTotalDimension());
285         equation.getMapper().extractEquationData(+1, complete);
286     }
287 
288     private static class  Linear<T extends CalculusFieldElement<T>>
289         implements  FieldOrdinaryDifferentialEquation<T>, FieldSecondaryODE<T> {
290 
291         private final Field<T> field;
292         private final int dimension;
293         private final int start;
294 
295         private Linear(final Field<T> field, final int dimension, final int start) {
296             this.field     = field;
297             this.dimension = dimension;
298             this.start     = start;
299         }
300 
301         public int getDimension() {
302             return dimension;
303         }
304 
305         public void init(final T t0, final T[] y0, final T finalTime) {
306             Assert.assertEquals(dimension, y0.length);
307             Assert.assertEquals(10.0,  t0.getReal(), 1.0e-15);
308             Assert.assertEquals(100.0, finalTime.getReal(), 1.0e-15);
309             for (int i = 0; i < y0.length; ++i) {
310                 Assert.assertEquals(i, y0[i].getReal(), 1.0e-15);
311             }
312         }
313 
314         public T[] computeDerivatives(final T t, final T[] y) {
315             final T[] yDot = MathArrays.buildArray(field, dimension);
316             for (int i = 0; i < dimension; ++i) {
317                 yDot[i] = field.getZero().add(i);
318             }
319             return yDot;
320         }
321 
322         public void init(final T t0, final T[] primary0, final T[] secondary0, final T finalTime) {
323             Assert.assertEquals(dimension, secondary0.length);
324             Assert.assertEquals(10.0,  t0.getReal(), 1.0e-15);
325             Assert.assertEquals(100.0, finalTime.getReal(), 1.0e-15);
326             for (int i = 0; i < primary0.length; ++i) {
327                 Assert.assertEquals(i, primary0[i].getReal(), 1.0e-15);
328             }
329             for (int i = 0; i < secondary0.length; ++i) {
330                 Assert.assertEquals(start + i, secondary0[i].getReal(), 1.0e-15);
331             }
332         }
333 
334         public T[] computeDerivatives(final T t, final T[] primary, final T[] primaryDot, final T[] secondary) {
335             final T[] secondaryDot = MathArrays.buildArray(field, dimension);
336             for (int i = 0; i < dimension; ++i) {
337                 secondaryDot[i] = field.getZero().subtract(i);
338             }
339             return secondaryDot;
340         }
341 
342     }
343 
344 }