View Javadoc
1   /*
2    * Licensed to the Hipparchus project 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 Hipparchus project 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  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 }