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  package org.hipparchus.special.elliptic.legendre;
18  
19  import org.hipparchus.special.elliptic.carlson.CarlsonEllipticIntegral;
20  import org.hipparchus.util.FastMath;
21  import org.hipparchus.util.MathUtils;
22  import org.junit.Assert;
23  import org.junit.Test;
24  
25  public class LegendreEllipticIntegralTest {
26  
27      @Test
28      public void testNoConvergence() {
29          Assert.assertTrue(Double.isNaN(LegendreEllipticIntegral.bigK(Double.NaN)));
30      }
31  
32      @Test
33      public void testComplementary() {
34          for (double m = 0.01; m < 1; m += 0.01) {
35              double k1 = LegendreEllipticIntegral.bigK(m);
36              double k2 = LegendreEllipticIntegral.bigKPrime(1 - m);
37              Assert.assertEquals(k1, k2, FastMath.ulp(k1));
38          }
39      }
40  
41      @Test
42      public void testAbramowitzStegunExample3() {
43          Assert.assertEquals(3.591545001,
44                              LegendreEllipticIntegral.bigK(80.0 / 81.0),
45                              2.0e-9);
46      }
47  
48      @Test
49      public void testAbramowitzStegunExample4() {
50          Assert.assertEquals(1.019106060,
51                              LegendreEllipticIntegral.bigE(80.0 / 81.0),
52                              2.0e-8);
53      }
54  
55      @Test
56      public void testAbramowitzStegunExample8() {
57          final double m    = 1.0 / 5.0;
58          final double phi1 = FastMath.acos(FastMath.sqrt(2) / 3.0);
59          final double phi2 = FastMath.acos(FastMath.sqrt(2) / 2.0);
60          Assert.assertEquals(1.115921, LegendreEllipticIntegral.bigF(phi1, m), 1.0e-6);
61          Assert.assertEquals(0.800380, LegendreEllipticIntegral.bigF(phi2, m), 1.0e-6);
62      }
63  
64      @Test
65      public void testAbramowitzStegunExample9() {
66          final double m    = 1.0 / 2.0;
67          final double phi1 = MathUtils.SEMI_PI;
68          final double phi2 = FastMath.PI / 6.0;
69          Assert.assertEquals(1.854075, LegendreEllipticIntegral.bigF(phi1, m), 1.0e-6);
70          Assert.assertEquals(0.535623, LegendreEllipticIntegral.bigF(phi2, m), 1.0e-6);
71      }
72  
73      @Test
74      public void testAbramowitzStegunExample10() {
75          final double m    = 4.0 / 5.0;
76          final double phi  = FastMath.PI / 6.0;
77          Assert.assertEquals(0.543604, LegendreEllipticIntegral.bigF(phi, m), 1.0e-6);
78      }
79  
80      @Test
81      public void testAbramowitzStegunExample14() {
82          final double k    = 3.0 / 5.0;
83          final double phi1 = FastMath.asin(FastMath.sqrt(5.0) / 3.0);
84          final double phi2 = FastMath.asin(5.0 / (3.0 * FastMath.sqrt(17.0)));
85          Assert.assertEquals(0.80904, LegendreEllipticIntegral.bigE(phi1, k * k), 1.0e-5);
86          Assert.assertEquals(0.41192, LegendreEllipticIntegral.bigE(phi2, k * k), 1.0e-5);
87      }
88  
89      @Test
90      public void testAbramowitzStegunTable175() {
91          final double sinAlpha1 = FastMath.sin(FastMath.toRadians(32));
92          Assert.assertEquals(0.26263487,
93                              LegendreEllipticIntegral.bigF(FastMath.toRadians(15), sinAlpha1 * sinAlpha1),
94                              1.0e-8);
95          final double sinAlpha2 = FastMath.sin(FastMath.toRadians(46));
96          Assert.assertEquals(1.61923762,
97                              LegendreEllipticIntegral.bigF(FastMath.toRadians(80), sinAlpha2 * sinAlpha2),
98                              1.0e-8);
99      }
100 
101     @Test
102     public void testAbramowitzStegunTable176() {
103         final double sinAlpha1 = FastMath.sin(FastMath.toRadians(64));
104         Assert.assertEquals(0.42531712,
105                             LegendreEllipticIntegral.bigE(FastMath.toRadians(25), sinAlpha1 * sinAlpha1),
106                             1.0e-8);
107         final double sinAlpha2 = FastMath.sin(FastMath.toRadians(76));
108         Assert.assertEquals(0.96208074,
109                             LegendreEllipticIntegral.bigE(FastMath.toRadians(70), sinAlpha2 * sinAlpha2),
110                             1.0e-8);
111     }
112 
113     @Test
114     public void testAbramowitzStegunTable179() {
115         final double sinAlpha1 = FastMath.sin(FastMath.toRadians(15));
116         Assert.assertEquals(1.62298,
117                             LegendreEllipticIntegral.bigPi(0.4, FastMath.toRadians(75), sinAlpha1 * sinAlpha1),
118                             1.0e-5);
119         final double sinAlpha2 = FastMath.sin(FastMath.toRadians(60));
120         Assert.assertEquals(1.03076,
121                             LegendreEllipticIntegral.bigPi(0.8, FastMath.toRadians(45), sinAlpha2 * sinAlpha2),
122                             1.0e-5);
123         final double sinAlpha3 = FastMath.sin(FastMath.toRadians(15));
124         Assert.assertEquals(2.79990,
125                             LegendreEllipticIntegral.bigPi(0.9, FastMath.toRadians(75), sinAlpha3 * sinAlpha3),
126                             1.0e-5);
127     }
128 
129     @Test
130     public void testCompleteVsIncompleteF() {
131         for (double m = 0.01; m < 1; m += 0.01) {
132             double complete   = LegendreEllipticIntegral.bigK(m);
133             double incomplete = LegendreEllipticIntegral.bigF(MathUtils.SEMI_PI, m);
134             Assert.assertEquals(complete, incomplete, FastMath.ulp(complete));
135         }
136     }
137 
138     @Test
139     public void testCompleteVsIncompleteE() {
140         for (double m = 0.01; m < 1; m += 0.01) {
141             double complete   = LegendreEllipticIntegral.bigE(m);
142             double incomplete = LegendreEllipticIntegral.bigE(MathUtils.SEMI_PI, m);
143             Assert.assertEquals(complete, incomplete, 4 * FastMath.ulp(complete));
144         }
145     }
146 
147     @Test
148     public void testCompleteVsIncompleteD() {
149         for (double m = 0.01; m < 1; m += 0.01) {
150             double complete   = LegendreEllipticIntegral.bigD(m);
151             double incomplete = LegendreEllipticIntegral.bigD(MathUtils.SEMI_PI, m);
152             Assert.assertEquals(complete, incomplete, FastMath.ulp(complete));
153         }
154     }
155 
156     @Test
157     public void testCompleteVsIncompletePi() {
158         for (double alpha2 = 0.01; alpha2 < 1; alpha2 += 0.01) {
159             for (double m = 0.01; m < 1; m += 0.01) {
160                 double complete   = LegendreEllipticIntegral.bigPi(alpha2, m);
161                 double incomplete = LegendreEllipticIntegral.bigPi(alpha2, MathUtils.SEMI_PI, m);
162                 Assert.assertEquals(complete, incomplete, FastMath.ulp(complete));
163             }
164         }
165     }
166 
167     @Test
168     public void testNomeMediumParameter() {
169         Assert.assertEquals(0.0857957337021947665168, LegendreEllipticIntegral.nome(0.75), 1.0e-15);
170     }
171 
172     @Test
173     public void testNomeSmallParameter() {
174         Assert.assertEquals(5.9375e-18, LegendreEllipticIntegral.nome(0.95e-16), 1.0e-22);
175     }
176 
177     @Test
178     public void testIntegralsSmallParameter() {
179         Assert.assertEquals(7.8539816428e-10,
180                             LegendreEllipticIntegral.bigK(2.0e-9) - MathUtils.SEMI_PI,
181                             1.0e-15);
182     }
183 
184     @Test
185     public void testPrecomputedDelta() {
186 
187         double n   = 0.7;
188         double m   = 0.2;
189         double phi = 1.2;
190         double ref = 1.8264362537906997;
191         Assert.assertEquals(ref, LegendreEllipticIntegral.bigPi(n, phi, m), 1.0e-15);
192 
193         // no argument reduction and no precomputed delta
194         final double csc     = 1.0 / FastMath.sin(phi);
195         final double csc2    = csc * csc;
196         final double cM1     = csc2 - 1;
197         final double cMm     = csc2 - m;
198         final double cMn     = csc2 - n;
199         final double pinphim = CarlsonEllipticIntegral.rF(cM1, cMm, csc2) +
200                                CarlsonEllipticIntegral.rJ(cM1, cMm, csc2, cMn) * n / 3;
201         Assert.assertEquals(ref, pinphim, 1.0e-15);
202 
203     }
204 
205 }