1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
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
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
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 }