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  import org.hipparchus.exception.MathIllegalArgumentException;
26  import org.junit.jupiter.api.Test;
27  
28  import static org.junit.jupiter.api.Assertions.assertEquals;
29  import static org.junit.jupiter.api.Assertions.assertThrows;
30  import static org.junit.jupiter.api.Assertions.fail;
31  
32  class ExpandableODETest {
33  
34      @Test
35      void testOnlyMainEquation() {
36          OrdinaryDifferentialEquation main = new Linear(3, 0);
37          ExpandableODE equation = new ExpandableODE(main);
38          assertEquals(main.getDimension(), equation.getMapper().getTotalDimension());
39          assertEquals(1, equation.getMapper().getNumberOfEquations());
40          double t0 = 10;
41          double t  = 100;
42          double[] complete    = new double[equation.getMapper().getTotalDimension()];
43          for (int i = 0; i < complete.length; ++i) {
44              complete[i] = i;
45          }
46          double[] completeDot = equation.computeDerivatives(t0, complete);
47          equation.init(equation.getMapper().mapStateAndDerivative(t0, complete, completeDot), t);
48          ODEStateAndDerivative state = equation.getMapper().mapStateAndDerivative(t0, complete, completeDot);
49          assertEquals(0, state.getNumberOfSecondaryStates());
50          double[] mainState    = state.getPrimaryState();
51          double[] mainStateDot = state.getPrimaryDerivative();
52          assertEquals(main.getDimension(), mainState.length);
53          for (int i = 0; i < main.getDimension(); ++i) {
54              assertEquals(i, mainState[i],   1.0e-15);
55              assertEquals(i, mainStateDot[i], 1.0e-15);
56              assertEquals(i, completeDot[i],  1.0e-15);
57          }
58      }
59  
60      @Test
61      void testPrimaryAndSecondary() {
62          OrdinaryDifferentialEquation main = new Linear(3, 0);
63          ExpandableODE equation = new ExpandableODE(main);
64          SecondaryODE secondary1 = new Linear(3, main.getDimension());
65          int i1 = equation.addSecondaryEquations(secondary1);
66          SecondaryODE secondary2 = new Linear(5, main.getDimension() + secondary1.getDimension());
67          int i2 = equation.addSecondaryEquations(secondary2);
68          assertEquals(main.getDimension() + secondary1.getDimension() + secondary2.getDimension(),
69                              equation.getMapper().getTotalDimension());
70          assertEquals(3, equation.getMapper().getNumberOfEquations());
71          assertEquals(1, i1);
72          assertEquals(2, i2);
73  
74          double t0 = 10;
75          double t  = 100;
76          double[] complete    = new double[equation.getMapper().getTotalDimension()];
77          for (int i = 0; i < complete.length; ++i) {
78              complete[i] = i;
79          }
80          double[] completeDot = equation.computeDerivatives(t0, complete);
81          equation.init(equation.getMapper().mapStateAndDerivative(t0, complete, completeDot), t);
82  
83          double[] mainState    = equation.getMapper().extractEquationData(0,  complete);
84          double[] mainStateDot = equation.getMapper().extractEquationData(0,  completeDot);
85          assertEquals(main.getDimension(), mainState.length);
86          for (int i = 0; i < main.getDimension(); ++i) {
87              assertEquals(i, mainState[i],   1.0e-15);
88              assertEquals(i, mainStateDot[i], 1.0e-15);
89              assertEquals(i, completeDot[i],  1.0e-15);
90          }
91  
92          double[] secondaryState1    = equation.getMapper().extractEquationData(i1,  complete);
93          double[] secondaryState1Dot = equation.getMapper().extractEquationData(i1,  completeDot);
94          assertEquals(secondary1.getDimension(), secondaryState1.length);
95          for (int i = 0; i < secondary1.getDimension(); ++i) {
96              assertEquals(i + main.getDimension(), secondaryState1[i],   1.0e-15);
97              assertEquals(-i, secondaryState1Dot[i], 1.0e-15);
98              assertEquals(-i, completeDot[i + main.getDimension()],  1.0e-15);
99          }
100 
101         double[] secondaryState2    = equation.getMapper().extractEquationData(i2,  complete);
102         double[] secondaryState2Dot = equation.getMapper().extractEquationData(i2,  completeDot);
103         assertEquals(secondary2.getDimension(), secondaryState2.length);
104         for (int i = 0; i < secondary2.getDimension(); ++i) {
105             assertEquals(i + main.getDimension() + secondary1.getDimension(), secondaryState2[i],   1.0e-15);
106             assertEquals(-i, secondaryState2Dot[i], 1.0e-15);
107             assertEquals(-i, completeDot[i + main.getDimension() + secondary1.getDimension()],  1.0e-15);
108         }
109 
110     }
111 
112     @Test
113     void testMap() {
114         OrdinaryDifferentialEquation main = new Linear(3, 0);
115         ExpandableODE equation = new ExpandableODE(main);
116         SecondaryODE secondary1 = new Linear(3, main.getDimension());
117         int i1 = equation.addSecondaryEquations(secondary1);
118         SecondaryODE secondary2 = new Linear(5, main.getDimension() + secondary1.getDimension());
119         int i2 = equation.addSecondaryEquations(secondary2);
120         assertEquals(main.getDimension() + secondary1.getDimension() + secondary2.getDimension(),
121                             equation.getMapper().getTotalDimension());
122         assertEquals(3, equation.getMapper().getNumberOfEquations());
123         assertEquals(1, i1);
124         assertEquals(2, i2);
125 
126         double t0 = 10;
127         double t  = 100;
128         double[] complete    = new double[equation.getMapper().getTotalDimension()];
129         for (int i = 0; i < complete.length; ++i) {
130             complete[i]    = i;
131         }
132         double[] completeDot = equation.computeDerivatives(t0, complete);
133         equation.init(equation.getMapper().mapStateAndDerivative(t0, complete, completeDot), t);
134 
135         try {
136             equation.getMapper().mapStateAndDerivative(t0, new double[complete.length + 1], completeDot);
137             fail("an exception should have been thrown");
138         } catch (MathIllegalArgumentException dme) {
139             // expected
140         }
141         try {
142             equation.getMapper().mapStateAndDerivative(t0, complete, new double[completeDot.length + 1]);
143             fail("an exception should have been thrown");
144         } catch (MathIllegalArgumentException dme) {
145             // expected
146         }
147         ODEStateAndDerivative state = equation.getMapper().mapStateAndDerivative(t0, complete, completeDot);
148         assertEquals(2, state.getNumberOfSecondaryStates());
149         assertEquals(main.getDimension(),       state.getSecondaryStateDimension(0));
150         assertEquals(secondary1.getDimension(), state.getSecondaryStateDimension(i1));
151         assertEquals(secondary2.getDimension(), state.getSecondaryStateDimension(i2));
152 
153         double[] mainState             = state.getPrimaryState();
154         double[] mainStateDot          = state.getPrimaryDerivative();
155         double[] mainStateAlternate    = state.getSecondaryState(0);
156         double[] mainStateDotAlternate = state.getSecondaryDerivative(0);
157         assertEquals(main.getDimension(), mainState.length);
158         for (int i = 0; i < main.getDimension(); ++i) {
159             assertEquals(i, mainState[i],             1.0e-15);
160             assertEquals(i, mainStateDot[i],          1.0e-15);
161             assertEquals(i, mainStateAlternate[i],    1.0e-15);
162             assertEquals(i, mainStateDotAlternate[i], 1.0e-15);
163             assertEquals(i, completeDot[i],           1.0e-15);
164         }
165 
166         double[] secondaryState1    = state.getSecondaryState(i1);
167         double[] secondaryState1Dot = state.getSecondaryDerivative(i1);
168         assertEquals(secondary1.getDimension(), secondaryState1.length);
169         for (int i = 0; i < secondary1.getDimension(); ++i) {
170             assertEquals(i + main.getDimension(), secondaryState1[i],   1.0e-15);
171             assertEquals(-i, secondaryState1Dot[i], 1.0e-15);
172             assertEquals(-i, completeDot[i + main.getDimension()],  1.0e-15);
173         }
174 
175         double[] secondaryState2    = state.getSecondaryState(i2);
176         double[] secondaryState2Dot = state.getSecondaryDerivative(i2);
177         assertEquals(secondary2.getDimension(), secondaryState2.length);
178         for (int i = 0; i < secondary2.getDimension(); ++i) {
179             assertEquals(i + main.getDimension() + secondary1.getDimension(), secondaryState2[i],   1.0e-15);
180             assertEquals(-i, secondaryState2Dot[i], 1.0e-15);
181             assertEquals(-i, completeDot[i + main.getDimension() + secondary1.getDimension()],  1.0e-15);
182         }
183 
184         double[] remappedState = state.getCompleteState();
185         double[] remappedDerivative = state.getCompleteDerivative();
186         assertEquals(equation.getMapper().getTotalDimension(), remappedState.length);
187         assertEquals(equation.getMapper().getTotalDimension(), remappedDerivative.length);
188         for (int i = 0; i < remappedState.length; ++i) {
189             assertEquals(complete[i],    remappedState[i],      1.0e-15);
190             assertEquals(completeDot[i], remappedDerivative[i], 1.0e-15);
191         }
192     }
193 
194     @Test
195     void testExtractDimensionMismatch() {
196         assertThrows(MathIllegalArgumentException.class, () -> {
197             OrdinaryDifferentialEquation main = new Linear(3, 0);
198             ExpandableODE equation = new ExpandableODE(main);
199             SecondaryODE secondary1 = new Linear(3, main.getDimension());
200             int i1 = equation.addSecondaryEquations(secondary1);
201             double[] tooShort = new double[main.getDimension()];
202             equation.getMapper().extractEquationData(i1, tooShort);
203         });
204     }
205 
206     @Test
207     void testInsertTooShortComplete() {
208         assertThrows(MathIllegalArgumentException.class, () -> {
209             OrdinaryDifferentialEquation main = new Linear(3, 0);
210             ExpandableODE equation = new ExpandableODE(main);
211             SecondaryODE secondary1 = new Linear(3, main.getDimension());
212             int i1 = equation.addSecondaryEquations(secondary1);
213             double[] equationData = new double[secondary1.getDimension()];
214             double[] tooShort = new double[main.getDimension()];
215             equation.getMapper().insertEquationData(i1, equationData, tooShort);
216         });
217     }
218 
219     @Test
220     void testInsertWrongEquationData() {
221         assertThrows(MathIllegalArgumentException.class, () -> {
222             OrdinaryDifferentialEquation main = new Linear(3, 0);
223             ExpandableODE equation = new ExpandableODE(main);
224             SecondaryODE secondary1 = new Linear(3, main.getDimension());
225             int i1 = equation.addSecondaryEquations(secondary1);
226             double[] wrongEquationData = new double[secondary1.getDimension() + 1];
227             double[] complete = new double[equation.getMapper().getTotalDimension()];
228             equation.getMapper().insertEquationData(i1, wrongEquationData, complete);
229         });
230     }
231 
232     @Test
233     void testNegativeIndex() {
234         assertThrows(MathIllegalArgumentException.class, () -> {
235 
236             OrdinaryDifferentialEquation main = new Linear(3, 0);
237             ExpandableODE equation = new ExpandableODE(main);
238             double[] complete = new double[equation.getMapper().getTotalDimension()];
239             equation.getMapper().extractEquationData(-1, complete);
240         });
241     }
242 
243     @Test
244     void testTooLargeIndex() {
245         assertThrows(MathIllegalArgumentException.class, () -> {
246             OrdinaryDifferentialEquation main = new Linear(3, 0);
247             ExpandableODE equation = new ExpandableODE(main);
248             double[] complete = new double[equation.getMapper().getTotalDimension()];
249             equation.getMapper().extractEquationData(+1, complete);
250         });
251     }
252 
253     private static class  Linear implements  OrdinaryDifferentialEquation, SecondaryODE {
254 
255         private final int dimension;
256         private final int start;
257 
258         private Linear(final int dimension, final int start) {
259             this.dimension = dimension;
260             this.start     = start;
261         }
262 
263         public int getDimension() {
264             return dimension;
265         }
266 
267         public void init(final double t0, final double[] y0, final double finalTime) {
268             assertEquals(dimension, y0.length);
269             assertEquals(10.0,  t0, 1.0e-15);
270             assertEquals(100.0, finalTime, 1.0e-15);
271             for (int i = 0; i < y0.length; ++i) {
272                 assertEquals(i, y0[i], 1.0e-15);
273             }
274         }
275 
276         public double[] computeDerivatives(final double t, final double[] y) {
277             final double[] yDot = new double[dimension];
278             for (int i = 0; i < dimension; ++i) {
279                 yDot[i] = i;
280             }
281             return yDot;
282         }
283 
284         public void init(final double t0, final double[] primary0, final double[] secondary0, final double finalTime) {
285             assertEquals(dimension, secondary0.length);
286             assertEquals(10.0,  t0, 1.0e-15);
287             assertEquals(100.0, finalTime, 1.0e-15);
288             for (int i = 0; i < primary0.length; ++i) {
289                 assertEquals(i, primary0[i], 1.0e-15);
290             }
291             for (int i = 0; i < secondary0.length; ++i) {
292                 assertEquals(start + i, secondary0[i], 1.0e-15);
293             }
294         }
295 
296         public double[] computeDerivatives(final double t, final double[] primary, final double[] primaryDot, final double[] secondary) {
297             final double[] secondaryDot = new double[dimension];
298             for (int i = 0; i < dimension; ++i) {
299                 secondaryDot[i] = -i;
300             }
301             return secondaryDot;
302         }
303 
304     }
305 
306 }