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