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 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
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
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 }