1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.hipparchus.ode;
19
20 import org.hipparchus.complex.Complex;
21 import org.hipparchus.ode.nonstiff.LutherIntegrator;
22 import org.hipparchus.util.FastMath;
23 import org.junit.jupiter.api.Test;
24
25 import static org.junit.jupiter.api.Assertions.assertEquals;
26
27
28 class ComplexODEConverterTest {
29
30 @Test
31 void testDoubleDimension() {
32 ComplexODEConverter converter = new ComplexODEConverter();
33 for (int i = 1; i < 10; ++i) {
34 assertEquals(2 * i, converter.convertEquations(new Circle(i, 0.2)).getDimension());
35 }
36 }
37
38 @Test
39 void testPrimaryEquation() {
40 final double omega = 0.2;
41 ComplexODEConverter converter = new ComplexODEConverter();
42 ComplexOrdinaryDifferentialEquation circle = new Circle(1, omega);
43 ComplexODEState initial = new ComplexODEState(0.0, new Complex[] { Complex.ONE });
44 ComplexODEStateAndDerivative der = new ComplexODEStateAndDerivative(initial.getTime(),
45 initial.getPrimaryState(),
46 circle.computeDerivatives(initial.getTime(),
47 initial.getPrimaryState()));
48 assertEquals(initial.getTime(), der.getTime(), 1.0e-15);
49 assertEquals(initial.getPrimaryState()[0], der.getPrimaryState()[0]);
50 assertEquals(initial.getPrimaryState()[0], der.getCompleteState()[0]);
51 assertEquals(initial.getPrimaryState()[0].multiply(((Circle) circle).iOmega),
52 der.getSecondaryDerivative(0)[0]);
53 assertEquals(initial.getPrimaryState()[0].multiply(((Circle) circle).iOmega),
54 der.getCompleteDerivative()[0]);
55 LutherIntegrator integrator = new LutherIntegrator(1.0e-3);
56 final ComplexODEStateAndDerivative finalstate =
57 converter.convertState(integrator.integrate(converter.convertEquations(circle),
58 converter.convertState(initial),
59 FastMath.PI / omega));
60 assertEquals(0, finalstate.getNumberOfSecondaryStates());
61 assertEquals(1, finalstate.getPrimaryStateDimension());
62 assertEquals(FastMath.PI / omega, finalstate.getTime(), 1.0e-15);
63 assertEquals(-1.0, finalstate.getPrimaryState()[0].getReal(), 1.0e-12);
64 assertEquals( 0.0, finalstate.getPrimaryState()[0].getImaginary(), 1.0e-12);
65 assertEquals( 0.0, finalstate.getPrimaryDerivative()[0].getReal(), 1.0e-12);
66 assertEquals(-omega, finalstate.getPrimaryDerivative()[0].getImaginary(), 1.0e-12);
67 }
68
69 @Test
70 void testSecondaryEquation() {
71 final double omegaP = 0.2;
72 final double omegaS0 = omegaP * 0.5;
73 final double omegaS1 = omegaP * 2;
74 ComplexODEConverter converter = new ComplexODEConverter();
75 ComplexOrdinaryDifferentialEquation primary = new Circle(1, omegaP);
76 ComplexSecondaryODE secondary0 = new Circle(1, omegaS0);
77 ComplexSecondaryODE secondary1 = new Circle(1, omegaS1);
78 ExpandableODE expandable = new ExpandableODE(converter.convertEquations(primary));
79 expandable.addSecondaryEquations(converter.convertSecondaryEquations(secondary0));
80 expandable.addSecondaryEquations(converter.convertSecondaryEquations(secondary1));
81 ComplexODEState initial = new ComplexODEState(0.0, new Complex[] { Complex.ONE },
82 new Complex[][] {
83 { Complex.ONE },
84 { Complex.ONE }
85 });
86 ComplexODEStateAndDerivative der = new ComplexODEStateAndDerivative(initial.getTime(),
87 initial.getPrimaryState(),
88 primary.computeDerivatives(initial.getTime(),
89 initial.getPrimaryState()),
90 new Complex[][] {
91 initial.getSecondaryState(0),
92 initial.getSecondaryState(1)
93 },
94 new Complex[][] {
95 secondary0.computeDerivatives(initial.getTime(),
96 initial.getPrimaryState(),
97 primary.computeDerivatives(initial.getTime(),
98 initial.getPrimaryState()),
99 initial.getSecondaryState(0)),
100 secondary1.computeDerivatives(initial.getTime(),
101 initial.getPrimaryState(),
102 primary.computeDerivatives(initial.getTime(),
103 initial.getPrimaryState()),
104 initial.getSecondaryState(1))
105 });
106 assertEquals(initial.getTime(), der.getTime(), 1.0e-15);
107 assertEquals(initial.getPrimaryState()[0], der.getPrimaryState()[0]);
108 assertEquals(initial.getPrimaryState()[0], der.getCompleteState()[0]);
109 assertEquals(initial.getSecondaryState(0)[0], der.getCompleteState()[1]);
110 assertEquals(initial.getSecondaryState(1)[0], der.getCompleteState()[2]);
111 assertEquals(initial.getPrimaryState()[0].multiply(((Circle) primary).iOmega),
112 der.getSecondaryDerivative(0)[0]);
113 assertEquals(initial.getPrimaryState()[0].multiply(((Circle) primary).iOmega),
114 der.getCompleteDerivative()[0]);
115 assertEquals(initial.getSecondaryState(0)[0].multiply(((Circle) secondary0).iOmega),
116 der.getCompleteDerivative()[1]);
117 assertEquals(initial.getSecondaryState(1)[0].multiply(((Circle) secondary1).iOmega),
118 der.getCompleteDerivative()[2]);
119 LutherIntegrator integrator = new LutherIntegrator(1.0e-3);
120 final ComplexODEStateAndDerivative finalstate =
121 converter.convertState(integrator.integrate(expandable,
122 converter.convertState(initial),
123 FastMath.PI / omegaP));
124 assertEquals(2, finalstate.getNumberOfSecondaryStates());
125 assertEquals(1, finalstate.getPrimaryStateDimension());
126 assertEquals(FastMath.PI / omegaP, finalstate.getTime(), 1.0e-15);
127 assertEquals(-1.0, finalstate.getPrimaryState()[0].getReal(), 1.0e-12);
128 assertEquals( 0.0, finalstate.getPrimaryState()[0].getImaginary(), 1.0e-12);
129 assertEquals( 0.0, finalstate.getPrimaryDerivative()[0].getReal(), 1.0e-12);
130 assertEquals(-omegaP, finalstate.getPrimaryDerivative()[0].getImaginary(), 1.0e-12);
131 assertEquals( 0.0, finalstate.getSecondaryState(1)[0].getReal(), 1.0e-12);
132 assertEquals( 1.0, finalstate.getSecondaryState(1)[0].getImaginary(), 1.0e-12);
133 assertEquals(-omegaS0, finalstate.getSecondaryDerivative(1)[0].getReal(), 1.0e-12);
134 assertEquals( 0.0, finalstate.getSecondaryDerivative(1)[0].getImaginary(), 1.0e-12);
135 assertEquals( 1.0, finalstate.getSecondaryState(2)[0].getReal(), 1.0e-12);
136 assertEquals( 0.0, finalstate.getSecondaryState(2)[0].getImaginary(), 2.0e-12);
137 assertEquals( 0.0, finalstate.getSecondaryDerivative(2)[0].getReal(), 1.0e-12);
138 assertEquals( omegaS1, finalstate.getSecondaryDerivative(2)[0].getImaginary(), 1.0e-12);
139 }
140
141 private static class Circle
142 implements ComplexOrdinaryDifferentialEquation, ComplexSecondaryODE {
143
144 private int n;
145 private Complex iOmega;
146
147 public Circle(int n, double omega) {
148 this.n = n;
149 this.iOmega = new Complex(0.0, omega);
150 }
151
152 public int getDimension() {
153 return n;
154 }
155
156 public Complex[] computeDerivatives(double t, Complex[] y) {
157 final Complex[] yDot = new Complex[y.length];
158 for (int i = 0; i < yDot.length; ++i) {
159 yDot[i] = iOmega.multiply(y[i]);
160 }
161 return yDot;
162 }
163
164 public Complex[] computeDerivatives(double t, Complex[] primary, Complex[] primaryDot, Complex[] secondary) {
165 return computeDerivatives(t, secondary);
166 }
167
168 }
169
170 }