1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.hipparchus.special.elliptic.legendre;
18
19 import org.hipparchus.CalculusFieldElement;
20 import org.hipparchus.Field;
21 import org.hipparchus.special.elliptic.carlson.CarlsonEllipticIntegral;
22 import org.hipparchus.util.Binary64Field;
23 import org.hipparchus.util.FastMath;
24 import org.hipparchus.util.MathUtils;
25 import org.junit.Assert;
26 import org.junit.Test;
27
28 public class FieldLegendreEllipticIntegralTest {
29
30 @Test
31 public void testNoConvergence() {
32 doTestNoConvergence(Binary64Field.getInstance());
33 }
34
35 private <T extends CalculusFieldElement<T>> void doTestNoConvergence(final Field<T> field) {
36 Assert.assertTrue(LegendreEllipticIntegral.bigK(field.getZero().newInstance(Double.NaN)).isNaN());
37 }
38
39 @Test
40 public void testComplementary() {
41 doTestComplementary(Binary64Field.getInstance());
42 }
43
44 private <T extends CalculusFieldElement<T>> void doTestComplementary(final Field<T> field) {
45 for (double m = 0.01; m < 1; m += 0.01) {
46 T k1 = LegendreEllipticIntegral.bigK(field.getZero().newInstance(m));
47 T k2 = LegendreEllipticIntegral.bigKPrime(field.getZero().newInstance(1 - m));
48 Assert.assertEquals(k1.getReal(), k2.getReal(), FastMath.ulp(k1).getReal());
49 }
50 }
51
52 @Test
53 public void testAbramowitzStegunExample3() {
54 doTestAbramowitzStegunExample3(Binary64Field.getInstance());
55 }
56
57 private <T extends CalculusFieldElement<T>> void doTestAbramowitzStegunExample3(final Field<T> field) {
58 T k = LegendreEllipticIntegral.bigK(field.getZero().newInstance(80.0 / 81.0));
59 Assert.assertEquals(3.591545001, k.getReal(), 2.0e-9);
60 }
61
62 public void testAbramowitzStegunExample4() {
63 doTestBigE(Binary64Field.getInstance(), 80.0 / 81.0, 1.019106060, 2.0e-8);
64 }
65
66 @Test
67 public void testAbramowitzStegunExample8() {
68 final double m = 1.0 / 5.0;
69 doTestBigF(Binary64Field.getInstance(), FastMath.acos(FastMath.sqrt(2) / 3.0), m, 1.115921, 1.0e-6);
70 doTestBigF(Binary64Field.getInstance(), FastMath.acos(FastMath.sqrt(2) / 2.0), m, 0.800380, 1.0e-6);
71 }
72
73 @Test
74 public void testAbramowitzStegunExample9() {
75 final double m = 1.0 / 2.0;
76 doTestBigF(Binary64Field.getInstance(), MathUtils.SEMI_PI, m, 1.854075, 1.0e-6);
77 doTestBigF(Binary64Field.getInstance(), FastMath.PI / 6.0, m, 0.535623, 1.0e-6);
78 }
79
80 @Test
81 public void testAbramowitzStegunExample10() {
82 final double m = 4.0 / 5.0;
83 doTestBigF(Binary64Field.getInstance(), FastMath.PI / 6.0, m, 0.543604, 1.0e-6);
84 }
85
86 @Test
87 public void testAbramowitzStegunExample14() {
88 final double k = 3.0 / 5.0;
89 doTestBigE(Binary64Field.getInstance(), FastMath.asin(FastMath.sqrt(5.0) / 3.0), k * k, 0.80904, 1.0e-5);
90 doTestBigE(Binary64Field.getInstance(), FastMath.asin(5.0 / (3.0 * FastMath.sqrt(17.0))), k * k, 0.41192, 1.0e-5);
91 }
92
93 @Test
94 public void testAbramowitzStegunTable175() {
95 final double sinAlpha1 = FastMath.sin(FastMath.toRadians(32));
96 doTestBigF(Binary64Field.getInstance(), FastMath.toRadians(15), sinAlpha1 * sinAlpha1, 0.26263487, 1.0e-8);
97 final double sinAlpha2 = FastMath.sin(FastMath.toRadians(46));
98 doTestBigF(Binary64Field.getInstance(), FastMath.toRadians(80), sinAlpha2 * sinAlpha2, 1.61923762, 1.0e-8);
99 }
100
101 @Test
102 public void testAbramowitzStegunTable176() {
103 final double sinAlpha1 = FastMath.sin(FastMath.toRadians(64));
104 doTestBigE(Binary64Field.getInstance(), FastMath.toRadians(25), sinAlpha1 * sinAlpha1, 0.42531712, 1.0e-8);
105 final double sinAlpha2 = FastMath.sin(FastMath.toRadians(76));
106 doTestBigE(Binary64Field.getInstance(), FastMath.toRadians(70), sinAlpha2 * sinAlpha2, 0.96208074, 1.0e-8);
107 }
108
109 @Test
110 public void testAbramowitzStegunTable179() {
111 final double sinAlpha1 = FastMath.sin(FastMath.toRadians(15));
112 doTestBigPi(Binary64Field.getInstance(), FastMath.toRadians(75), 0.4, sinAlpha1 * sinAlpha1, 1.62298, 1.0e-5);
113 final double sinAlpha2 = FastMath.sin(FastMath.toRadians(60));
114 doTestBigPi(Binary64Field.getInstance(), FastMath.toRadians(45), 0.8, sinAlpha2 * sinAlpha2, 1.03076, 1.0e-5);
115 final double sinAlpha3 = FastMath.sin(FastMath.toRadians(15));
116 doTestBigPi(Binary64Field.getInstance(), FastMath.toRadians(75), 0.9, sinAlpha3 * sinAlpha3, 2.79990, 1.0e-5);
117 }
118
119 @Test
120 public void testCompleteVsIncompleteF() {
121 doTestCompleteVsIncompleteF(Binary64Field.getInstance());
122 }
123
124 @Test
125 public void testCompleteVsIncompleteE() {
126 doTestCompleteVsIncompleteE(Binary64Field.getInstance());
127 }
128
129 @Test
130 public void testCompleteVsIncompleteD() {
131 doTestCompleteVsIncompleteD(Binary64Field.getInstance());
132 }
133
134 @Test
135 public void testCompleteVsIncompletePi() {
136 doTestCompleteVsIncompletePi(Binary64Field.getInstance());
137 }
138
139 @Test
140 public void testNomeMediumParameter() {
141 doTestNomeMediumParameter(Binary64Field.getInstance());
142 }
143
144 @Test
145 public void testNomeSmallParameter() {
146 doTestNomeSmallParameter(Binary64Field.getInstance());
147 }
148
149 @Test
150 public void testPrecomputedDelta() {
151 doTestPrecomputedDelta(Binary64Field.getInstance());
152 }
153
154 @Test
155 public void testIntegralsSmallParameter() {
156 doTestIntegralsSmallParameter(Binary64Field.getInstance());
157 }
158
159 private <T extends CalculusFieldElement<T>> void doTestBigE(final Field<T> field, final double m,
160 final double expected, final double tol) {
161 Assert.assertEquals(expected,
162 LegendreEllipticIntegral.bigE(field.getZero().newInstance(m)).getReal(),
163 tol);
164 }
165
166 private <T extends CalculusFieldElement<T>> void doTestBigE(final Field<T> field,
167 final double phi, final double m,
168 final double expected, final double tol) {
169 Assert.assertEquals(expected,
170 LegendreEllipticIntegral.bigE(field.getZero().newInstance(phi),
171 field.getZero().newInstance(m)).getReal(),
172 tol);
173 }
174
175 private <T extends CalculusFieldElement<T>> void doTestBigF(final Field<T> field,
176 final double phi, final double m,
177 final double expected, final double tol) {
178 Assert.assertEquals(expected,
179 LegendreEllipticIntegral.bigF(field.getZero().newInstance(phi),
180 field.getZero().newInstance(m)).getReal(),
181 tol);
182 }
183
184 private <T extends CalculusFieldElement<T>> void doTestBigPi(final Field<T> field,
185 final double phi, final double alpha2, final double m,
186 final double expected, final double tol) {
187 Assert.assertEquals(expected,
188 LegendreEllipticIntegral.bigPi(field.getZero().newInstance(alpha2),
189 field.getZero().newInstance(phi),
190 field.getZero().newInstance(m)).getReal(),
191 tol);
192 }
193
194 private <T extends CalculusFieldElement<T>> void doTestCompleteVsIncompleteF(final Field<T> field) {
195 for (double m = 0.01; m < 1; m += 0.01) {
196 double complete = LegendreEllipticIntegral.bigK(field.getZero().newInstance(m)).getReal();
197 double incomplete = LegendreEllipticIntegral.bigF(field.getZero().newInstance(MathUtils.SEMI_PI),
198 field.getZero().newInstance(m)).getReal();
199 Assert.assertEquals(complete, incomplete, FastMath.ulp(complete));
200 }
201 }
202
203 private <T extends CalculusFieldElement<T>> void doTestCompleteVsIncompleteE(final Field<T> field) {
204 for (double m = 0.01; m < 1; m += 0.01) {
205 double complete = LegendreEllipticIntegral.bigE(field.getZero().newInstance(m)).getReal();
206 double incomplete = LegendreEllipticIntegral.bigE(field.getZero().newInstance(MathUtils.SEMI_PI),
207 field.getZero().newInstance(m)).getReal();
208 Assert.assertEquals(complete, incomplete, 4 * FastMath.ulp(complete));
209 }
210 }
211
212 private <T extends CalculusFieldElement<T>> void doTestCompleteVsIncompleteD(final Field<T> field) {
213 for (double m = 0.01; m < 1; m += 0.01) {
214 double complete = LegendreEllipticIntegral.bigD(field.getZero().newInstance(m)).getReal();
215 double incomplete = LegendreEllipticIntegral.bigD(field.getZero().newInstance(MathUtils.SEMI_PI),
216 field.getZero().newInstance(m)).getReal();
217 Assert.assertEquals(complete, incomplete, FastMath.ulp(complete));
218 }
219 }
220
221 private <T extends CalculusFieldElement<T>> void doTestCompleteVsIncompletePi(final Field<T> field) {
222 for (double alpha2 = 0.01; alpha2 < 1; alpha2 += 0.01) {
223 for (double m = 0.01; m < 1; m += 0.01) {
224 double complete = LegendreEllipticIntegral.bigPi(field.getZero().newInstance(alpha2),
225 field.getZero().newInstance(m)).getReal();
226 double incomplete = LegendreEllipticIntegral.bigPi(field.getZero().newInstance(alpha2),
227 field.getZero().newInstance(MathUtils.SEMI_PI),
228 field.getZero().newInstance(m)).getReal();
229 Assert.assertEquals(complete, incomplete, FastMath.ulp(complete));
230 }
231 }
232 }
233
234 private <T extends CalculusFieldElement<T>> void doTestNomeMediumParameter(final Field<T> field) {
235 Assert.assertEquals(0.0857957337021947665168, LegendreEllipticIntegral.nome(field.getZero().newInstance(0.75)).getReal(), 1.0e-15);
236 }
237
238 private <T extends CalculusFieldElement<T>> void doTestNomeSmallParameter(final Field<T> field) {
239 Assert.assertEquals(5.9375e-18, LegendreEllipticIntegral.nome(field.getZero().newInstance(0.95e-16)).getReal(), 1.0e-22);
240 }
241
242 private <T extends CalculusFieldElement<T>> void doTestIntegralsSmallParameter(final Field<T> field) {
243 Assert.assertEquals(7.8539816428e-10,
244 LegendreEllipticIntegral.bigK(field.getZero().newInstance(2.0e-9)).getReal() - MathUtils.SEMI_PI,
245 1.0e-15);
246 }
247
248 private <T extends CalculusFieldElement<T>> void doTestPrecomputedDelta(final Field<T> field) {
249
250 T n = field.getZero().newInstance(0.7);
251 T m = field.getZero().newInstance(0.2);
252 T phi = field.getZero().newInstance(1.2);
253 T ref = field.getZero().newInstance(1.8264362537906997);
254 Assert.assertEquals(0.0, LegendreEllipticIntegral.bigPi(n, phi, m).subtract(ref).getReal(), 1.0e-15);
255
256
257 final T csc = phi.sin().reciprocal();
258 final T csc2 = csc.multiply(csc);
259 final T cM1 = csc2.subtract(1);
260 final T cMm = csc2.subtract(m);
261 final T cMn = csc2.subtract(n);
262 final T pinphim = CarlsonEllipticIntegral.rF(cM1, cMm, csc2).
263 add(CarlsonEllipticIntegral.rJ(cM1, cMm, csc2, cMn).multiply(n).divide(3));
264 Assert.assertEquals(0.0, pinphim.subtract(ref).getReal(), 1.0e-15);
265
266 }
267
268 }