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.nonstiff;
19  
20  import org.hipparchus.Field;
21  import org.hipparchus.complex.Complex;
22  import org.hipparchus.complex.ComplexField;
23  import org.hipparchus.ode.*;
24  import org.hipparchus.util.FastMath;
25  import org.hipparchus.util.FieldSinCos;
26  import org.hipparchus.util.MathArrays;
27  import org.hipparchus.util.SinCos;
28  import org.junit.Assert;
29  import org.junit.Test;
30  
31  public class FieldExplicitRungeKuttaIntegratorTest {
32  
33      @Test
34      public void testFraction() {
35          // GIVEN
36          final int p = 2;
37          final int q = 3;
38          final Field<Complex> field = ComplexField.getInstance();
39          // WHEN
40          final Complex actualFraction = FieldExplicitRungeKuttaIntegrator.fraction(field, p, q);
41          // THEN
42          final Complex expectedFraction = FieldExplicitRungeKuttaIntegrator.fraction(field, (double) p, (double) q);
43          Assert.assertEquals(expectedFraction.getReal(), actualFraction.getReal(), 0);
44      }
45  
46      @Test
47      public void testVersusNonField() {
48          // GIVEN
49          final TestFieldEquations testFieldEquations = new TestFieldEquations();
50          final FieldExpandableODE<Complex> fieldExpandableODE = new FieldExpandableODE<>(testFieldEquations);
51  
52          final ComplexField field = ComplexField.getInstance();
53          final Complex t0 = Complex.ZERO;
54          final Complex[] y0 = new Complex[] { Complex.ONE, Complex.ZERO };
55          final Complex h = new Complex(0.1);
56          final FieldButcherArrayProvider<Complex> fieldExplicitRungeKutta = new ThreeEighthesFieldIntegrator<>(field,
57                  Complex.NaN);
58  
59          // WHEN
60          final Complex[][] yDotK = MathArrays.buildArray(field, 4, 2);
61          yDotK[0] = fieldExpandableODE.computeDerivatives(t0, y0);
62          FieldExplicitRungeKuttaIntegrator.applyInternalButcherWeights(fieldExpandableODE, t0, y0, h,
63                  fieldExplicitRungeKutta.getA(), fieldExplicitRungeKutta.getC(), yDotK);
64          final Complex[] actualState = FieldExplicitRungeKuttaIntegrator.applyExternalButcherWeights(y0, yDotK, h,
65                  fieldExplicitRungeKutta.getB());
66  
67          // THEN
68          final double[] y0Real = new double[] { y0[0].getReal(), y0[1].getReal() };
69          final double[][] yDotKReal = new double[yDotK.length][yDotK[0].length];
70          final ExpandableODE expandableODE = new ExpandableODE(new TestEquations());
71          yDotKReal[0] = expandableODE.computeDerivatives(t0.getReal(), y0Real);
72          final ButcherArrayProvider explicitRungeKutta = new ThreeEighthesIntegrator(Double.NaN);
73          ExplicitRungeKuttaIntegrator.applyInternalButcherWeights(expandableODE, t0.getReal(), y0Real, h.getReal(),
74                  explicitRungeKutta.getA(), explicitRungeKutta.getC(), yDotKReal);
75          final double[] expectedState = ExplicitRungeKuttaIntegrator.applyExternalButcherWeights(y0Real, yDotKReal, h.getReal(),
76                  explicitRungeKutta.getB());
77          for (int i = 0; i < expectedState.length; i++) {
78              Assert.assertEquals(expectedState[i], actualState[i].getReal(), 0);
79          }
80      }
81  
82      @Test
83      public void testRealCoefficientsVersusField() {
84          // GIVEN
85          final TestFieldEquations testFieldEquations = new TestFieldEquations();
86          final FieldExpandableODE<Complex> fieldExpandableODE = new FieldExpandableODE<>(testFieldEquations);
87          final ComplexField field = ComplexField.getInstance();
88          final Complex t0 = Complex.ZERO;
89          final Complex[] y0 = new Complex[] { Complex.ONE, Complex.ZERO };
90          final Complex h = new Complex(0.1);
91          final FieldExplicitRungeKuttaIntegrator<Complex> fieldExplicitRungeKutta = new ThreeEighthesFieldIntegrator<>(field,
92                  Complex.NaN);
93  
94          // WHEN
95          final Complex[][] yDotK = MathArrays.buildArray(field, 4, 2);
96          yDotK[0] = fieldExpandableODE.computeDerivatives(t0, y0);
97          FieldExplicitRungeKuttaIntegrator.applyInternalButcherWeights(fieldExpandableODE, t0, y0, h,
98                  fieldExplicitRungeKutta.getA(), fieldExplicitRungeKutta.getC(), yDotK);
99          final Complex[] actualState = FieldExplicitRungeKuttaIntegrator.applyExternalButcherWeights(y0, yDotK, h,
100                 fieldExplicitRungeKutta.getB());
101 
102         // THEN
103         FieldExplicitRungeKuttaIntegrator.applyInternalButcherWeights(fieldExpandableODE, t0, y0, h,
104                 fieldExplicitRungeKutta.getRealA(), fieldExplicitRungeKutta.getRealC(), yDotK);
105         final Complex[] expectedState = FieldExplicitRungeKuttaIntegrator.applyExternalButcherWeights(y0, yDotK, h,
106                 fieldExplicitRungeKutta.getRealB());
107         for (int i = 0; i < expectedState.length; i++) {
108             Assert.assertEquals(expectedState[i], actualState[i]);
109         }
110     }
111 
112     private static class TestFieldEquations implements FieldOrdinaryDifferentialEquation<Complex> {
113 
114         @Override
115         public int getDimension() {
116             return 2;
117         }
118 
119         @Override
120         public Complex[] computeDerivatives(Complex t, Complex[] y) {
121 
122             final FieldSinCos<Complex> sinCos = FastMath.sinCos(t);
123             return new Complex[] { sinCos.sin(), sinCos.cos().multiply(y[0]) };
124         }
125 
126     }
127 
128     private static class TestEquations implements OrdinaryDifferentialEquation {
129 
130         @Override
131         public int getDimension() {
132             return 2;
133         }
134 
135         @Override
136         public double[] computeDerivatives(double t, double[] y) {
137             final SinCos sinCos = FastMath.sinCos(t);
138             return new double[] { sinCos.sin(), sinCos.cos() * y[0] };
139         }
140     } 
141     
142 }