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 java.util.function.DoubleFunction;
20  import java.util.function.Function;
21  
22  import org.hipparchus.CalculusFieldElement;
23  import org.hipparchus.analysis.CalculusFieldUnivariateFunction;
24  import org.hipparchus.complex.Complex;
25  import org.hipparchus.complex.ComplexUnivariateIntegrator;
26  import org.hipparchus.complex.FieldComplex;
27  import org.hipparchus.complex.FieldComplexUnivariateIntegrator;
28  import org.hipparchus.special.elliptic.carlson.CarlsonEllipticIntegral;
29  import org.hipparchus.util.FastMath;
30  import org.hipparchus.util.MathUtils;
31  
32  /** Complete and incomplete elliptic integrals in Legendre form.
33   * <p>
34   * The elliptic integrals are related to Jacobi elliptic functions.
35   * </p>
36   * <p>
37   * <em>
38   * Beware that when computing elliptic integrals in the complex plane,
39   * many issues arise due to branch cuts. See the
40   * <a href="https://www.hipparchus.org/hipparchus-core/special.html#Elliptic_functions_and_integrals">user guide</a>
41   * for a thorough explanation.
42   * </em>
43   * </p>
44   * <p>
45   * There are different conventions to interpret the arguments of
46   * Legendre elliptic integrals. In mathematical texts, these conventions show
47   * up using the separator between arguments. So for example for the incomplete
48   * integral of the first kind F we have:
49   * </p>
50   * <ul>
51   *   <li>F(φ, k): the first argument φ is an angle and the second argument k
52   *       is the elliptic modulus: this is the trigonometric form of the integral</li>
53   *   <li>F(φ; m): the first argument φ is an angle and the second argument m=k²
54   *       is the parameter: this is also a trigonometric form of the integral</li>
55   *   <li>F(x|m): the first argument x=sin(φ) is not an angle anymore and the
56   *       second argument m=k² is the parameter: this is the Legendre form</li>
57   *   <li>F(φ\α): the first argument φ is an angle and the second argument α is the
58   *       modular angle</li>
59   * </ul>
60   * <p>
61   * As we have no separator in a method call, we have to adopt one convention
62   * and stick to it. In Hipparchus, we adopted the Legendre form (i.e. F(x|m),
63   * with x=sin(φ) and m=k². These conventions are consistent with Wolfram Alpha
64   * functions EllipticF, EllipticE, ElliptiPI…
65   * </p>
66   * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
67   * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
68   * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheSecondKind.html">Complete Elliptic Integrals of the Second Kind (MathWorld)</a>
69   * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
70   * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
71   * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
72   * @since 2.0
73   */
74  public class LegendreEllipticIntegral {
75  
76      /** Private constructor for a utility class.
77       */
78      private LegendreEllipticIntegral() {
79          // nothing to do
80      }
81  
82      /** Get the nome q.
83       * @param m parameter (m=k² where k is the elliptic modulus)
84       * @return nome q
85       */
86      public static double nome(final double m) {
87          if (m < 1.0e-16) {
88              // first terms of infinite series in Abramowitz and Stegun 17.3.21
89              final double m16 = m * 0.0625;
90              return m16 * (1 + 8 * m16);
91          } else {
92              return FastMath.exp(-FastMath.PI * bigKPrime(m) / bigK(m));
93          }
94      }
95  
96      /** Get the nome q.
97       * @param m parameter (m=k² where k is the elliptic modulus)
98       * @param <T> the type of the field elements
99       * @return nome q
100      */
101     public static <T extends CalculusFieldElement<T>> T nome(final T m) {
102         final T one = m.getField().getOne();
103         if (m.norm() < 100 * one.ulp().getReal()) {
104             // first terms of infinite series in Abramowitz and Stegun 17.3.21
105             final T m16 = m.multiply(0.0625);
106             return m16.multiply(m16.multiply(8).add(1));
107         } else {
108             return FastMath.exp(bigKPrime(m).divide(bigK(m)).multiply(one.getPi().negate()));
109         }
110     }
111 
112     /** Get the complete elliptic integral of the first kind K(m).
113      * <p>
114      * The complete elliptic integral of the first kind K(m) is
115      * \[
116      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
117      * \]
118      * it corresponds to the real quarter-period of Jacobi elliptic functions
119      * </p>
120      * <p>
121      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
122      * Carlson elliptic integrals}.
123      * </p>
124      * @param m parameter (m=k² where k is the elliptic modulus)
125      * @return complete elliptic integral of the first kind K(m)
126      * @see #bigKPrime(double)
127      * @see #bigF(double, double)
128      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
129      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
130      */
131     public static double bigK(final double m) {
132         if (m < 1.0e-8) {
133             // first terms of infinite series in Abramowitz and Stegun 17.3.11
134             return (1 + 0.25 * m) * MathUtils.SEMI_PI;
135         } else {
136             return CarlsonEllipticIntegral.rF(0, 1.0 - m, 1);
137         }
138     }
139 
140     /** Get the complete elliptic integral of the first kind K(m).
141      * <p>
142      * The complete elliptic integral of the first kind K(m) is
143      * \[
144      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
145      * \]
146      * it corresponds to the real quarter-period of Jacobi elliptic functions
147      * </p>
148      * <p>
149      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
150      * Carlson elliptic integrals}.
151      * </p>
152      * @param m parameter (m=k² where k is the elliptic modulus)
153      * @param <T> the type of the field elements
154      * @return complete elliptic integral of the first kind K(m)
155      * @see #bigKPrime(CalculusFieldElement)
156      * @see #bigF(CalculusFieldElement, CalculusFieldElement)
157      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
158      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
159      */
160     public static <T extends CalculusFieldElement<T>> T bigK(final T m) {
161         final T zero = m.getField().getZero();
162         final T one  = m.getField().getOne();
163         if (m.norm() < 1.0e7 * one.ulp().getReal()) {
164 
165             // first terms of infinite series in Abramowitz and Stegun 17.3.11
166             return one.add(m.multiply(0.25)).multiply(zero.getPi().multiply(0.5));
167 
168         } else {
169             return CarlsonEllipticIntegral.rF(zero, one.subtract(m), one);
170         }
171     }
172 
173     /** Get the complete elliptic integral of the first kind K(m).
174      * <p>
175      * The complete elliptic integral of the first kind K(m) is
176      * \[
177      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
178      * \]
179      * it corresponds to the real quarter-period of Jacobi elliptic functions
180      * </p>
181      * <p>
182      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
183      * Carlson elliptic integrals}.
184      * </p>
185      * @param m parameter (m=k² where k is the elliptic modulus)
186      * @return complete elliptic integral of the first kind K(m)
187      * @see #bigKPrime(Complex)
188      * @see #bigF(Complex, Complex)
189      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
190      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
191      */
192     public static Complex bigK(final Complex m) {
193         if (m.norm() < 1.0e-8) {
194             // first terms of infinite series in Abramowitz and Stegun 17.3.11
195             return Complex.ONE.add(m.multiply(0.25)).multiply(MathUtils.SEMI_PI);
196         } else {
197             return CarlsonEllipticIntegral.rF(Complex.ZERO, Complex.ONE.subtract(m), Complex.ONE);
198         }
199     }
200 
201     /** Get the complete elliptic integral of the first kind K(m).
202      * <p>
203      * The complete elliptic integral of the first kind K(m) is
204      * \[
205      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
206      * \]
207      * it corresponds to the real quarter-period of Jacobi elliptic functions
208      * </p>
209      * <p>
210      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
211      * Carlson elliptic integrals}.
212      * </p>
213      * @param m parameter (m=k² where k is the elliptic modulus)
214      * @param <T> the type of the field elements
215      * @return complete elliptic integral of the first kind K(m)
216      * @see #bigKPrime(FieldComplex)
217      * @see #bigF(FieldComplex, FieldComplex)
218      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
219      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
220      */
221     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigK(final FieldComplex<T> m) {
222         final FieldComplex<T> zero = m.getField().getZero();
223         final FieldComplex<T> one  = m.getField().getOne();
224         if (m.norm() < 1.0e7 * one.ulp().getReal()) {
225 
226             // first terms of infinite series in Abramowitz and Stegun 17.3.11
227             return one.add(m.multiply(0.25)).multiply(zero.getPi().multiply(0.5));
228 
229         } else {
230             return CarlsonEllipticIntegral.rF(zero, one.subtract(m), one);
231         }
232     }
233 
234     /** Get the complete elliptic integral of the first kind K'(m).
235      * <p>
236      * The complete elliptic integral of the first kind K'(m) is
237      * \[
238      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-(1-m) \sin^2\theta}}
239      * \]
240      * it corresponds to the imaginary quarter-period of Jacobi elliptic functions
241      * </p>
242      * <p>
243      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
244      * Carlson elliptic integrals}.
245      * </p>
246      * @param m parameter (m=k² where k is the elliptic modulus)
247      * @return complete elliptic integral of the first kind K'(m)
248      * @see #bigK(double)
249      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
250      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
251      */
252     public static double bigKPrime(final double m) {
253         return CarlsonEllipticIntegral.rF(0, m, 1);
254     }
255 
256     /** Get the complete elliptic integral of the first kind K'(m).
257      * <p>
258      * The complete elliptic integral of the first kind K'(m) is
259      * \[
260      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-(1-m) \sin^2\theta}}
261      * \]
262      * it corresponds to the imaginary quarter-period of Jacobi elliptic functions
263      * </p>
264      * <p>
265      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
266      * Carlson elliptic integrals}.
267      * </p>
268      * @param m parameter (m=k² where k is the elliptic modulus)
269      * @param <T> the type of the field elements
270      * @return complete elliptic integral of the first kind K'(m)
271      * @see #bigK(CalculusFieldElement)
272      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
273      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
274      */
275     public static <T extends CalculusFieldElement<T>> T bigKPrime(final T m) {
276         final T zero = m.getField().getZero();
277         final T one  = m.getField().getOne();
278         return CarlsonEllipticIntegral.rF(zero, m, one);
279     }
280 
281     /** Get the complete elliptic integral of the first kind K'(m).
282      * <p>
283      * The complete elliptic integral of the first kind K'(m) is
284      * \[
285      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-(1-m) \sin^2\theta}}
286      * \]
287      * it corresponds to the imaginary quarter-period of Jacobi elliptic functions
288      * </p>
289      * <p>
290      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
291      * Carlson elliptic integrals}.
292      * </p>
293      * @param m parameter (m=k² where k is the elliptic modulus)
294      * @return complete elliptic integral of the first kind K'(m)
295      * @see #bigK(Complex)
296      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
297      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
298      */
299     public static Complex bigKPrime(final Complex m) {
300         return CarlsonEllipticIntegral.rF(Complex.ZERO, m, Complex.ONE);
301     }
302 
303     /** Get the complete elliptic integral of the first kind K'(m).
304      * <p>
305      * The complete elliptic integral of the first kind K'(m) is
306      * \[
307      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-(1-m) \sin^2\theta}}
308      * \]
309      * it corresponds to the imaginary quarter-period of Jacobi elliptic functions
310      * </p>
311      * <p>
312      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
313      * Carlson elliptic integrals}.
314      * </p>
315      * @param m parameter (m=k² where k is the elliptic modulus)
316      * @param <T> the type of the field elements
317      * @return complete elliptic integral of the first kind K'(m)
318      * @see #bigK(FieldComplex)
319      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheFirstKind.html">Complete Elliptic Integrals of the First Kind (MathWorld)</a>
320      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
321      */
322     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigKPrime(final FieldComplex<T> m) {
323         final FieldComplex<T> zero = m.getField().getZero();
324         final FieldComplex<T> one  = m.getField().getOne();
325         return CarlsonEllipticIntegral.rF(zero, m, one);
326     }
327 
328     /** Get the complete elliptic integral of the second kind E(m).
329      * <p>
330      * The complete elliptic integral of the second kind E(m) is
331      * \[
332      *    \int_0^{\frac{\pi}{2}} \sqrt{1-m \sin^2\theta} d\theta
333      * \]
334      * </p>
335      * <p>
336      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
337      * Carlson elliptic integrals}.
338      * </p>
339      * @param m parameter (m=k² where k is the elliptic modulus)
340      * @return complete elliptic integral of the second kind E(m)
341      * @see #bigE(double, double)
342      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheSecondKind.html">Complete Elliptic Integrals of the Second Kind (MathWorld)</a>
343      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
344      */
345     public static double bigE(final double m) {
346         return CarlsonEllipticIntegral.rG(0, 1 - m, 1) * 2;
347     }
348 
349     /** Get the complete elliptic integral of the second kind E(m).
350      * <p>
351      * The complete elliptic integral of the second kind E(m) is
352      * \[
353      *    \int_0^{\frac{\pi}{2}} \sqrt{1-m \sin^2\theta} d\theta
354      * \]
355      * </p>
356      * <p>
357      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
358      * Carlson elliptic integrals}.
359      * </p>
360      * @param m parameter (m=k² where k is the elliptic modulus)
361      * @param <T> the type of the field elements
362      * @return complete elliptic integral of the second kind E(m)
363      * @see #bigE(CalculusFieldElement, CalculusFieldElement)
364      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheSecondKind.html">Complete Elliptic Integrals of the Second Kind (MathWorld)</a>
365      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
366      */
367     public static <T extends CalculusFieldElement<T>> T bigE(final T m) {
368         final T zero = m.getField().getZero();
369         final T one  = m.getField().getOne();
370         return CarlsonEllipticIntegral.rG(zero, one.subtract(m), one).multiply(2);
371     }
372 
373     /** Get the complete elliptic integral of the second kind E(m).
374      * <p>
375      * The complete elliptic integral of the second kind E(m) is
376      * \[
377      *    \int_0^{\frac{\pi}{2}} \sqrt{1-m \sin^2\theta} d\theta
378      * \]
379      * </p>
380      * <p>
381      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
382      * Carlson elliptic integrals}.
383      * </p>
384      * @param m parameter (m=k² where k is the elliptic modulus)
385      * @return complete elliptic integral of the second kind E(m)
386      * @see #bigE(Complex, Complex)
387      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheSecondKind.html">Complete Elliptic Integrals of the Second Kind (MathWorld)</a>
388      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
389      */
390     public static Complex bigE(final Complex m) {
391         return CarlsonEllipticIntegral.rG(Complex.ZERO,
392                                           Complex.ONE.subtract(m),
393                                           Complex.ONE).multiply(2);
394     }
395 
396     /** Get the complete elliptic integral of the second kind E(m).
397      * <p>
398      * The complete elliptic integral of the second kind E(m) is
399      * \[
400      *    \int_0^{\frac{\pi}{2}} \sqrt{1-m \sin^2\theta} d\theta
401      * \]
402      * </p>
403      * <p>
404      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
405      * Carlson elliptic integrals}.
406      * </p>
407      * @param m parameter (m=k² where k is the elliptic modulus)
408      * @param <T> the type of the field elements
409      * @return complete elliptic integral of the second kind E(m)
410      * @see #bigE(FieldComplex, FieldComplex)
411      * @see <a href="https://mathworld.wolfram.com/CompleteEllipticIntegraloftheSecondKind.html">Complete Elliptic Integrals of the Second Kind (MathWorld)</a>
412      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
413      */
414     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigE(final FieldComplex<T> m) {
415         final FieldComplex<T> zero = m.getField().getZero();
416         final FieldComplex<T> one  = m.getField().getOne();
417         return CarlsonEllipticIntegral.rG(zero, one.subtract(m), one).multiply(2);
418     }
419 
420     /** Get the complete elliptic integral D(m) = [K(m) - E(m)]/m.
421      * <p>
422      * The complete elliptic integral D(m) is
423      * \[
424      *    \int_0^{\frac{\pi}{2}} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
425      * \]
426      * </p>
427      * <p>
428      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
429      * Carlson elliptic integrals}.
430      * </p>
431      * @param m parameter (m=k² where k is the elliptic modulus)
432      * @return complete elliptic integral D(m)
433      * @see #bigD(double, double)
434      */
435     public static double bigD(final double m) {
436         return CarlsonEllipticIntegral.rD(0, 1 - m, 1) / 3;
437     }
438 
439     /** Get the complete elliptic integral D(m) = [K(m) - E(m)]/m.
440      * <p>
441      * The complete elliptic integral D(m) is
442      * \[
443      *    \int_0^{\frac{\pi}{2}} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
444      * \]
445      * </p>
446      * <p>
447      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
448      * Carlson elliptic integrals}.
449      * </p>
450      * @param m parameter (m=k² where k is the elliptic modulus)
451      * @param <T> the type of the field elements
452      * @return complete elliptic integral D(m)
453      * @see #bigD(CalculusFieldElement, CalculusFieldElement)
454      */
455     public static <T extends CalculusFieldElement<T>> T bigD(final T m) {
456         final T zero = m.getField().getZero();
457         final T one  = m.getField().getOne();
458         return CarlsonEllipticIntegral.rD(zero, one.subtract(m), one).divide(3);
459     }
460 
461     /** Get the complete elliptic integral D(m) = [K(m) - E(m)]/m.
462      * <p>
463      * The complete elliptic integral D(m) is
464      * \[
465      *    \int_0^{\frac{\pi}{2}} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
466      * \]
467      * </p>
468      * <p>
469      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
470      * Carlson elliptic integrals}.
471      * </p>
472      * @param m parameter (m=k² where k is the elliptic modulus)
473      * @return complete elliptic integral D(m)
474      * @see #bigD(Complex, Complex)
475      */
476     public static Complex bigD(final Complex m) {
477         return CarlsonEllipticIntegral.rD(Complex.ZERO, Complex.ONE.subtract(m), Complex.ONE).divide(3);
478     }
479 
480     /** Get the complete elliptic integral D(m) = [K(m) - E(m)]/m.
481      * <p>
482      * The complete elliptic integral D(m) is
483      * \[
484      *    \int_0^{\frac{\pi}{2}} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
485      * \]
486      * </p>
487      * <p>
488      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
489      * Carlson elliptic integrals}.
490      * </p>
491      * @param m parameter (m=k² where k is the elliptic modulus)
492      * @param <T> the type of the field elements
493      * @return complete elliptic integral D(m)
494      * @see #bigD(FieldComplex, FieldComplex)
495      */
496     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigD(final FieldComplex<T> m) {
497         final FieldComplex<T> zero = m.getField().getZero();
498         final FieldComplex<T> one  = m.getField().getOne();
499         return CarlsonEllipticIntegral.rD(zero, one.subtract(m), one).divide(3);
500     }
501 
502     /** Get the complete elliptic integral of the third kind Π(n, m).
503      * <p>
504      * The complete elliptic integral of the third kind Π(n, m) is
505      * \[
506      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
507      * \]
508      * </p>
509      * <p>
510      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
511      * Carlson elliptic integrals}.
512      * </p>
513      * @param n elliptic characteristic
514      * @param m parameter (m=k² where k is the elliptic modulus)
515      * @return complete elliptic integral of the third kind Π(n, m)
516      * @see #bigPi(double, double, double)
517      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
518      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
519      */
520     public static double bigPi(final double n, final double m) {
521         final double kPrime2 = 1 - m;
522         final double delta   = n * (m - n) * (n - 1);
523         return CarlsonEllipticIntegral.rF(0, kPrime2, 1) +
524                CarlsonEllipticIntegral.rJ(0, kPrime2, 1, 1 - n, delta) * n / 3;
525     }
526 
527     /** Get the complete elliptic integral of the third kind Π(n, m).
528      * <p>
529      * The complete elliptic integral of the third kind Π(n, m) is
530      * \[
531      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
532      * \]
533      * </p>
534      * <p>
535      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
536      * Carlson elliptic integrals}.
537      * </p>
538      * @param n elliptic characteristic
539      * @param m parameter (m=k² where k is the elliptic modulus)
540      * @param <T> the type of the field elements
541      * @return complete elliptic integral of the third kind Π(n, m)
542      * @see #bigPi(CalculusFieldElement, CalculusFieldElement, CalculusFieldElement)
543      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
544      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
545      */
546     public static <T extends CalculusFieldElement<T>> T bigPi(final T n, final T m) {
547         final T zero    = m.getField().getZero();
548         final T one     = m.getField().getOne();
549         final T kPrime2 = one.subtract(m);
550         final T delta   = n.multiply(m.subtract(n)).multiply(n.subtract(1));
551         return CarlsonEllipticIntegral.rF(zero, kPrime2, one).
552                add(CarlsonEllipticIntegral.rJ(zero, kPrime2, one, one.subtract(n), delta).multiply(n).divide(3));
553     }
554 
555     /** Get the complete elliptic integral of the third kind Π(n, m).
556      * <p>
557      * The complete elliptic integral of the third kind Π(n, m) is
558      * \[
559      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
560      * \]
561      * </p>
562      * <p>
563      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
564      * Carlson elliptic integrals}.
565      * </p>
566      * @param n elliptic characteristic
567      * @param m parameter (m=k² where k is the elliptic modulus)
568      * @return complete elliptic integral of the third kind Π(n, m)
569      * @see #bigPi(Complex, Complex, Complex)
570      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
571      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
572      */
573     public static Complex bigPi(final Complex n, final Complex m) {
574         final Complex kPrime2 = Complex.ONE.subtract(m);
575         final Complex delta   = n.multiply(m.subtract(n)).multiply(n.subtract(1));
576         return CarlsonEllipticIntegral.rF(Complex.ZERO, kPrime2, Complex.ONE).
577                add(CarlsonEllipticIntegral.rJ(Complex.ZERO, kPrime2, Complex.ONE, Complex.ONE.subtract(n), delta).multiply(n).divide(3));
578     }
579 
580     /** Get the complete elliptic integral of the third kind Π(n, m).
581      * <p>
582      * The complete elliptic integral of the third kind Π(n, m) is
583      * \[
584      *    \int_0^{\frac{\pi}{2}} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
585      * \]
586      * </p>
587      * <p>
588      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
589      * Carlson elliptic integrals}.
590      * </p>
591      * @param n elliptic characteristic
592      * @param m parameter (m=k² where k is the elliptic modulus)
593      * @param <T> the type of the field elements
594      * @return complete elliptic integral of the third kind Π(n, m)
595      * @see #bigPi(FieldComplex, FieldComplex, FieldComplex)
596      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
597      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
598      */
599     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigPi(final FieldComplex<T> n, final FieldComplex<T> m) {
600         final FieldComplex<T> zero    = m.getField().getZero();
601         final FieldComplex<T> one     = m.getField().getOne();
602         final FieldComplex<T> kPrime2 = one.subtract(m);
603         final FieldComplex<T> delta   = n.multiply(m.subtract(n)).multiply(n.subtract(1));
604         return CarlsonEllipticIntegral.rF(zero, kPrime2, one).
605                add(CarlsonEllipticIntegral.rJ(zero, kPrime2, one, one.subtract(n), delta).multiply(n).divide(3));
606     }
607 
608     /** Get the incomplete elliptic integral of the first kind F(φ, m).
609      * <p>
610      * The incomplete elliptic integral of the first kind F(φ, m) is
611      * \[
612      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
613      * \]
614      * </p>
615      * <p>
616      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
617      * Carlson elliptic integrals}.
618      * </p>
619      * @param phi amplitude (i.e. upper bound of the integral)
620      * @param m parameter (m=k² where k is the elliptic modulus)
621      * @return incomplete elliptic integral of the first kind F(φ, m)
622      * @see #bigK(double)
623      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
624      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
625      */
626     public static double bigF(final double phi, final double m) {
627 
628         // argument reduction
629         final DoubleArgumentReduction ar = new DoubleArgumentReduction(phi, m, n -> bigK(n));
630 
631         // integrate part between 0 and π/2
632         final double cM1 = ar.csc2 - 1.0;
633         final double cMm = ar.csc2 - m;
634         final double incomplete =  CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2);
635 
636         // combine complete and incomplete parts
637         return ar.negate ? ar.complete - incomplete : ar.complete + incomplete;
638 
639     }
640 
641     /** Get the incomplete elliptic integral of the first kind F(φ, m).
642      * <p>
643      * The incomplete elliptic integral of the first kind F(φ, m) is
644      * \[
645      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
646      * \]
647      * </p>
648      * <p>
649      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
650      * Carlson elliptic integrals}.
651      * </p>
652      * @param phi amplitude (i.e. upper bound of the integral)
653      * @param m parameter (m=k² where k is the elliptic modulus)
654      * @param <T> the type of the field elements
655      * @return incomplete elliptic integral of the first kind F(φ, m)
656      * @see #bigK(CalculusFieldElement)
657      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
658      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
659      */
660     public static <T extends CalculusFieldElement<T>> T bigF(final T phi, final T m) {
661 
662         // argument reduction
663         final FieldArgumentReduction<T> ar = new FieldArgumentReduction<>(phi, m, n -> bigK(n));
664 
665         // integrate part between 0 and π/2
666         final T cM1        = ar.csc2.subtract(1);
667         final T cMm        = ar.csc2.subtract(m);
668         final T incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2);
669 
670         // combine complete and incomplete parts
671         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
672 
673     }
674 
675     /** Get the incomplete elliptic integral of the first kind F(φ, m).
676      * <p>
677      * <em>
678      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
679      * are considered experimental for now, they have known issues.
680      * </em>
681      * </p>
682      * <p>
683      * The incomplete elliptic integral of the first kind F(φ, m) is
684      * \[
685      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
686      * \]
687      * </p>
688      * <p>
689      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
690      * Carlson elliptic integrals}.
691      * </p>
692      * @param phi amplitude (i.e. upper bound of the integral)
693      * @param m parameter (m=k² where k is the elliptic modulus)
694      * @return incomplete elliptic integral of the first kind F(φ, m)
695      * @see #bigK(Complex)
696      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
697      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
698      */
699     public static Complex bigF(final Complex phi, final Complex m) {
700 
701         // argument reduction
702         final FieldArgumentReduction<Complex> ar = new FieldArgumentReduction<>(phi, m, n -> bigK(n));
703 
704         // integrate part between 0 and π/2
705         final Complex cM1        = ar.csc2.subtract(1);
706         final Complex cMm        = ar.csc2.subtract(m);
707         final Complex incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2);
708 
709         // combine complete and incomplete parts
710         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
711 
712     }
713 
714     /** Get the incomplete elliptic integral of the first kind F(φ, m) using numerical integration.
715      * <p>
716      * <em>
717      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
718      * are considered experimental for now, they have known issues.
719      * </em>
720      * </p>
721      * <p>
722      * The incomplete elliptic integral of the first kind F(φ, m) is
723      * \[
724      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
725      * \]
726      * </p>
727      * <p>
728      * The algorithm for evaluating the functions is based on numerical integration.
729      * If integration path comes too close to a pole of the integrand, then integration will fail
730      * with a {@link org.hipparchus.exception.MathIllegalStateException MathIllegalStateException}
731      * even for very large {@code maxEval}. This is normal behavior.
732      * </p>
733      * @param phi amplitude (i.e. upper bound of the integral)
734      * @param m parameter (m=k² where k is the elliptic modulus)
735      * @param integrator integrator to use
736      * @param maxEval maximum number of evaluations (real and imaginary
737      * parts are evaluated separately, so up to twice this number may be used)
738      * @return incomplete elliptic integral of the first kind F(φ, m)
739      * @see #bigK(Complex)
740      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
741      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
742      */
743     public static Complex bigF(final Complex phi, final Complex m,
744                                final ComplexUnivariateIntegrator integrator, final int maxEval) {
745         return integrator.integrate(maxEval, new First<>(m), phi.getField().getZero(), phi);
746     }
747 
748     /** Get the incomplete elliptic integral of the first kind F(φ, m).
749      * <p>
750      * <em>
751      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
752      * are considered experimental for now, they have known issues.
753      * </em>
754      * </p>
755      * <p>
756      * The incomplete elliptic integral of the first kind F(φ, m) is
757      * \[
758      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
759      * \]
760      * </p>
761      * <p>
762      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
763      * Carlson elliptic integrals}.
764      * </p>
765      * @param phi amplitude (i.e. upper bound of the integral)
766      * @param m parameter (m=k² where k is the elliptic modulus)
767      * @param <T> the type of the field elements
768      * @return incomplete elliptic integral of the first kind F(φ, m)
769      * @see #bigK(CalculusFieldElement)
770      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
771      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
772      */
773     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigF(final FieldComplex<T> phi, final FieldComplex<T> m) {
774 
775         // argument reduction
776         final FieldArgumentReduction<FieldComplex<T>> ar = new FieldArgumentReduction<>(phi, m, n -> bigK(n));
777 
778         // integrate part between 0 and π/2
779         final FieldComplex<T> cM1        = ar.csc2.subtract(1);
780         final FieldComplex<T> cMm        = ar.csc2.subtract(m);
781         final FieldComplex<T> incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2);
782 
783         // combine complete and incomplete parts
784         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
785 
786     }
787 
788     /** Get the incomplete elliptic integral of the first kind F(φ, m).
789      * <p>
790      * <em>
791      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
792      * are considered experimental for now, they have known issues.
793      * </em>
794      * </p>
795      * <p>
796      * The incomplete elliptic integral of the first kind F(φ, m) is
797      * \[
798      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}}
799      * \]
800      * </p>
801      * <p>
802      * The algorithm for evaluating the functions is based on numerical integration.
803      * If integration path comes too close to a pole of the integrand, then integration will fail
804      * with a {@link org.hipparchus.exception.MathIllegalStateException MathIllegalStateException}
805      * even for very large {@code maxEval}. This is normal behavior.
806      * </p>
807      * @param phi amplitude (i.e. upper bound of the integral)
808      * @param m parameter (m=k² where k is the elliptic modulus)
809      * @param integrator integrator to use
810      * @param maxEval maximum number of evaluations (real and imaginary
811      * parts are evaluated separately, so up to twice this number may be used)
812      * @param <T> the type of the field elements
813      * @return incomplete elliptic integral of the first kind F(φ, m)
814      * @see #bigK(CalculusFieldElement)
815      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheFirstKind.html">Elliptic Integrals of the First Kind (MathWorld)</a>
816      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
817      */
818     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigF(final FieldComplex<T> phi, final FieldComplex<T> m,
819                                                                            final FieldComplexUnivariateIntegrator<T> integrator,
820                                                                            final int maxEval) {
821         return integrator.integrate(maxEval, new First<>(m), phi.getField().getZero(), phi);
822     }
823 
824     /** Get the incomplete elliptic integral of the second kind E(φ, m).
825      * <p>
826      * The incomplete elliptic integral of the second kind E(φ, m) is
827      * \[
828      *    \int_0^{\phi} \sqrt{1-m \sin^2\theta} d\theta
829      * \]
830      * </p>
831      * <p>
832      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
833      * Carlson elliptic integrals}.
834      * </p>
835      * @param phi amplitude (i.e. upper bound of the integral)
836      * @param m parameter (m=k² where k is the elliptic modulus)
837      * @return incomplete elliptic integral of the second kind E(φ, m)
838      * @see #bigE(double)
839      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
840      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
841      */
842     public static double bigE(final double phi, final double m) {
843 
844         // argument reduction
845         final DoubleArgumentReduction ar = new DoubleArgumentReduction(phi, m, n -> bigE(n));
846 
847         // integrate part between 0 and π/2
848         final double cM1        = ar.csc2 - 1.0;
849         final double cMm        = ar.csc2 - m;
850         final double incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2) -
851                                   CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2) * (m / 3);
852 
853         // combine complete and incomplete parts
854         return ar.negate ? ar.complete - incomplete : ar.complete + incomplete;
855 
856     }
857 
858     /** Get the incomplete elliptic integral of the second kind E(φ, m).
859      * <p>
860      * The incomplete elliptic integral of the second kind E(φ, m) is
861      * \[
862      *    \int_0^{\phi} \sqrt{1-m \sin^2\theta} d\theta
863      * \]
864      * </p>
865      * <p>
866      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
867      * Carlson elliptic integrals}.
868      * </p>
869      * @param phi amplitude (i.e. upper bound of the integral)
870      * @param m parameter (m=k² where k is the elliptic modulus)
871      * @param <T> the type of the field elements
872      * @return incomplete elliptic integral of the second kind E(φ, m)
873      * @see #bigE(CalculusFieldElement)
874      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
875      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
876      */
877     public static <T extends CalculusFieldElement<T>> T bigE(final T phi, final T m) {
878 
879         // argument reduction
880         final FieldArgumentReduction<T> ar = new FieldArgumentReduction<>(phi, m, n -> bigE(n));
881 
882         // integrate part between 0 and π/2
883         final T cM1        = ar.csc2.subtract(1);
884         final T cMm        = ar.csc2.subtract(m);
885         final T incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2).
886                              subtract(CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2).multiply(m.divide(3)));
887 
888         // combine complete and incomplete parts
889         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
890 
891     }
892 
893     /** Get the incomplete elliptic integral of the second kind E(φ, m).
894      * <p>
895      * <em>
896      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
897      * are considered experimental for now, they have known issues.
898      * </em>
899      * </p>
900      * <p>
901      * The incomplete elliptic integral of the second kind E(φ, m) is
902      * \[
903      *    \int_0^{\phi} \sqrt{1-m \sin^2\theta} d\theta
904      * \]
905      * </p>
906      * <p>
907      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
908      * Carlson elliptic integrals}.
909      * </p>
910      * @param phi amplitude (i.e. upper bound of the integral)
911      * @param m parameter (m=k² where k is the elliptic modulus)
912      * @return incomplete elliptic integral of the second kind E(φ, m)
913      * @see #bigE(Complex)
914      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
915      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
916      */
917     public static Complex bigE(final Complex phi, final Complex m) {
918 
919         // argument reduction
920         final FieldArgumentReduction<Complex> ar = new FieldArgumentReduction<>(phi, m, n -> bigE(n));
921 
922         // integrate part between 0 and π/2
923         final Complex cM1        = ar.csc2.subtract(1);
924         final Complex cMm        = ar.csc2.subtract(m);
925         final Complex incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2).
926                                    subtract(CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2).multiply(m.divide(3)));
927 
928         // combine complete and incomplete parts
929         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
930 
931     }
932 
933     /** Get the incomplete elliptic integral of the second kind E(φ, m) using numerical integration.
934      * <p>
935      * <em>
936      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
937      * are considered experimental for now, they have known issues.
938      * </em>
939      * </p>
940      * <p>
941      * The incomplete elliptic integral of the second kind E(φ, m) is
942      * \[
943      *    \int_0^{\phi} \sqrt{1-m \sin^2\theta} d\theta
944      * \]
945      * </p>
946      * <p>
947      * The algorithm for evaluating the functions is based on numerical integration.
948      * If integration path comes too close to a pole of the integrand, then integration will fail
949      * with a {@link org.hipparchus.exception.MathIllegalStateException MathIllegalStateException}
950      * even for very large {@code maxEval}. This is normal behavior.
951      * </p>
952      * @param phi amplitude (i.e. upper bound of the integral)
953      * @param m parameter (m=k² where k is the elliptic modulus)
954      * @param integrator integrator to use
955      * @param maxEval maximum number of evaluations (real and imaginary
956      * parts are evaluated separately, so up to twice this number may be used)
957      * @return incomplete elliptic integral of the second kind E(φ, m)
958      * @see #bigE(Complex)
959      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
960      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
961      */
962     public static Complex bigE(final Complex phi, final Complex m,
963                                final ComplexUnivariateIntegrator integrator, final int maxEval) {
964         return integrator.integrate(maxEval, new Second<>(m), phi.getField().getZero(), phi);
965     }
966 
967     /** Get the incomplete elliptic integral of the second kind E(φ, m).
968      * <p>
969      * <em>
970      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
971      * are considered experimental for now, they have known issues.
972      * </em>
973      * </p>
974      * <p>
975      * The incomplete elliptic integral of the second kind E(φ, m) is
976      * \[
977      *    \int_0^{\phi} \sqrt{1-m \sin^2\theta} d\theta
978      * \]
979      * </p>
980      * <p>
981      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
982      * Carlson elliptic integrals}.
983      * </p>
984      * @param phi amplitude (i.e. upper bound of the integral)
985      * @param m parameter (m=k² where k is the elliptic modulus)
986      * @param <T> the type of the field elements
987      * @return incomplete elliptic integral of the second kind E(φ, m)
988      * @see #bigE(FieldComplex)
989      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
990      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
991      */
992     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigE(final FieldComplex<T> phi, final FieldComplex<T> m) {
993 
994         // argument reduction
995         final FieldArgumentReduction<FieldComplex<T>> ar = new FieldArgumentReduction<>(phi, m, n -> bigE(n));
996 
997         // integrate part between 0 and π/2
998         final FieldComplex<T> cM1        = ar.csc2.subtract(1);
999         final FieldComplex<T> cMm        = ar.csc2.subtract(m);
1000         final FieldComplex<T> incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2).
1001                                            subtract(CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2).multiply(m.divide(3)));
1002 
1003         // combine complete and incomplete parts
1004         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1005 
1006     }
1007 
1008     /** Get the incomplete elliptic integral of the second kind E(φ, m).
1009      * <p>
1010      * <em>
1011      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1012      * are considered experimental for now, they have known issues.
1013      * </em>
1014      * </p>
1015      * <p>
1016      * The incomplete elliptic integral of the second kind E(φ, m) is
1017      * \[
1018      *    \int_0^{\phi} \sqrt{1-m \sin^2\theta} d\theta
1019      * \]
1020      * </p>
1021      * <p>
1022      * The algorithm for evaluating the functions is based on numerical integration.
1023      * If integration path comes too close to a pole of the integrand, then integration will fail
1024      * with a {@link org.hipparchus.exception.MathIllegalStateException MathIllegalStateException}
1025      * even for very large {@code maxEval}. This is normal behavior.
1026      * </p>
1027      * @param phi amplitude (i.e. upper bound of the integral)
1028      * @param m parameter (m=k² where k is the elliptic modulus)
1029      * @param integrator integrator to use
1030      * @param maxEval maximum number of evaluations (real and imaginary
1031      * parts are evaluated separately, so up to twice this number may be used)
1032      * @param <T> the type of the field elements
1033      * @return incomplete elliptic integral of the second kind E(φ, m)
1034      * @see #bigE(FieldComplex)
1035      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheSecondKind.html">Elliptic Integrals of the Second Kind (MathWorld)</a>
1036      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1037      */
1038     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigE(final FieldComplex<T> phi, final FieldComplex<T> m,
1039                                                                            final FieldComplexUnivariateIntegrator<T> integrator,
1040                                                                            final int maxEval) {
1041         return integrator.integrate(maxEval, new Second<>(m), phi.getField().getZero(), phi);
1042     }
1043 
1044     /** Get the incomplete elliptic integral D(φ, m) = [F(φ, m) - E(φ, m)]/m.
1045      * <p>
1046      * The incomplete elliptic integral D(φ, m) is
1047      * \[
1048      *    \int_0^{\phi} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
1049      * \]
1050      * </p>
1051      * <p>
1052      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1053      * Carlson elliptic integrals}.
1054      * </p>
1055      * @param phi amplitude (i.e. upper bound of the integral)
1056      * @param m parameter (m=k² where k is the elliptic modulus)
1057      * @return incomplete elliptic integral D(φ, m)
1058      * @see #bigD(double)
1059      */
1060     public static double bigD(final double phi, final double m) {
1061 
1062         // argument reduction
1063         final DoubleArgumentReduction ar = new DoubleArgumentReduction(phi, m, n -> bigD(n));
1064 
1065         // integrate part between 0 and π/2
1066         final double cM1        = ar.csc2 - 1.0;
1067         final double cMm        = ar.csc2 - m;
1068         final double incomplete = CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2) / 3;
1069 
1070         // combine complete and incomplete parts
1071         return ar.negate ? ar.complete - incomplete : ar.complete + incomplete;
1072 
1073     }
1074 
1075     /** Get the incomplete elliptic integral D(φ, m) = [F(φ, m) - E(φ, m)]/m.
1076      * <p>
1077      * The incomplete elliptic integral D(φ, m) is
1078      * \[
1079      *    \int_0^{\phi} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
1080      * \]
1081      * </p>
1082      * <p>
1083      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1084      * Carlson elliptic integrals}.
1085      * </p>
1086      * @param phi amplitude (i.e. upper bound of the integral)
1087      * @param m parameter (m=k² where k is the elliptic modulus)
1088      * @param <T> the type of the field elements
1089      * @return incomplete elliptic integral D(φ, m)
1090      * @see #bigD(CalculusFieldElement)
1091      */
1092     public static <T extends CalculusFieldElement<T>> T bigD(final T phi, final T m) {
1093 
1094         // argument reduction
1095         final FieldArgumentReduction<T> ar = new FieldArgumentReduction<>(phi, m, n -> bigD(n));
1096 
1097         // integrate part between 0 and π/2
1098         final T cM1        = ar.csc2.subtract(1);
1099         final T cMm        = ar.csc2.subtract(m);
1100         final T incomplete = CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2).divide(3);
1101 
1102         // combine complete and incomplete parts
1103         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1104 
1105     }
1106 
1107     /** Get the incomplete elliptic integral D(φ, m) = [F(φ, m) - E(φ, m)]/m.
1108      * <p>
1109      * <em>
1110      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1111      * are considered experimental for now, they have known issues.
1112      * </em>
1113      * </p>
1114      * <p>
1115      * The incomplete elliptic integral D(φ, m) is
1116      * \[
1117      *    \int_0^{\phi} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
1118      * \]
1119      * </p>
1120      * <p>
1121      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1122      * Carlson elliptic integrals}.
1123      * </p>
1124      * @param phi amplitude (i.e. upper bound of the integral)
1125      * @param m parameter (m=k² where k is the elliptic modulus)
1126      * @return incomplete elliptic integral D(φ, m)
1127      * @see #bigD(Complex)
1128      */
1129     public static Complex bigD(final Complex phi, final Complex m) {
1130 
1131         // argument reduction
1132         final FieldArgumentReduction<Complex> ar = new FieldArgumentReduction<>(phi, m, n -> bigD(n));
1133 
1134         // integrate part between 0 and π/2
1135         final Complex cM1        = ar.csc2.subtract(1);
1136         final Complex cMm        = ar.csc2.subtract(m);
1137         final Complex incomplete = CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2).divide(3);
1138 
1139         // combine complete and incomplete parts
1140         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1141 
1142     }
1143 
1144     /** Get the incomplete elliptic integral D(φ, m) = [F(φ, m) - E(φ, m)]/m.
1145      * <p>
1146      * <em>
1147      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1148      * are considered experimental for now, they have known issues.
1149      * </em>
1150      * </p>
1151      * <p>
1152      * The incomplete elliptic integral D(φ, m) is
1153      * \[
1154      *    \int_0^{\phi} \frac{\sin^2\theta}{\sqrt{1-m \sin^2\theta}} d\theta
1155      * \]
1156      * </p>
1157      * <p>
1158      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1159      * Carlson elliptic integrals}.
1160      * </p>
1161      * @param phi amplitude (i.e. upper bound of the integral)
1162      * @param m parameter (m=k² where k is the elliptic modulus)
1163      * @param <T> the type of the field elements
1164      * @return incomplete elliptic integral D(φ, m)
1165      * @see #bigD(CalculusFieldElement)
1166      */
1167     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigD(final FieldComplex<T> phi, final FieldComplex<T> m) {
1168 
1169         // argument reduction
1170         final FieldArgumentReduction<FieldComplex<T>> ar = new FieldArgumentReduction<>(phi, m, n -> bigD(n));
1171 
1172         // integrate part between 0 and π/2
1173         final FieldComplex<T> cM1        = ar.csc2.subtract(1);
1174         final FieldComplex<T> cMm        = ar.csc2.subtract(m);
1175         final FieldComplex<T> incomplete = CarlsonEllipticIntegral.rD(cM1, cMm, ar.csc2).divide(3);
1176 
1177         // combine complete and incomplete parts
1178         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1179 
1180     }
1181 
1182     /** Get the incomplete elliptic integral of the third kind Π(n, φ, m).
1183      * <p>
1184      * The incomplete elliptic integral of the third kind Π(n, φ, m) is
1185      * \[
1186      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
1187      * \]
1188      * </p>
1189      * <p>
1190      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1191      * Carlson elliptic integrals}.
1192      * </p>
1193      * @param n elliptic characteristic
1194      * @param phi amplitude (i.e. upper bound of the integral)
1195      * @param m parameter (m=k² where k is the elliptic modulus)
1196      * @return incomplete elliptic integral of the third kind Π(n, φ, m)
1197      * @see #bigPi(double, double)
1198      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
1199      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1200      */
1201     public static double bigPi(final double n, final double phi, final double m) {
1202 
1203         // argument reduction
1204         final DoubleArgumentReduction ar = new DoubleArgumentReduction(phi, m, parameter -> bigPi(n, parameter));
1205 
1206         // integrate part between 0 and π/2
1207         final double cM1        = ar.csc2 - 1.0;
1208         final double cMm        = ar.csc2 - m;
1209         final double cMn        = ar.csc2 - n;
1210         final double delta      = n * (m - n) * (n - 1);
1211         final double incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2) +
1212                                   CarlsonEllipticIntegral.rJ(cM1, cMm, ar.csc2, cMn, delta) * n / 3;
1213 
1214         // combine complete and incomplete parts
1215         return ar.negate ? ar.complete - incomplete : ar.complete + incomplete;
1216 
1217     }
1218 
1219     /** Get the incomplete elliptic integral of the third kind Π(n, φ, m).
1220      * <p>
1221      * The incomplete elliptic integral of the third kind Π(n, φ, m) is
1222      * \[
1223      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
1224      * \]
1225      * </p>
1226      * <p>
1227      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1228      * Carlson elliptic integrals}.
1229      * </p>
1230      * @param n elliptic characteristic
1231      * @param phi amplitude (i.e. upper bound of the integral)
1232      * @param m parameter (m=k² where k is the elliptic modulus)
1233      * @param <T> the type of the field elements
1234      * @return incomplete elliptic integral of the third kind Π(n, φ, m)
1235      * @see #bigPi(CalculusFieldElement, CalculusFieldElement)
1236      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
1237      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1238      */
1239     public static <T extends CalculusFieldElement<T>> T bigPi(final T n, final T phi, final T m) {
1240 
1241         // argument reduction
1242         final FieldArgumentReduction<T> ar = new FieldArgumentReduction<>(phi, m, parameter -> bigPi(n, parameter));
1243 
1244         // integrate part between 0 and π/2
1245         final T cM1        = ar.csc2.subtract(1);
1246         final T cMm        = ar.csc2.subtract(m);
1247         final T cMn        = ar.csc2.subtract(n);
1248         final T delta      = n.multiply(m.subtract(n)).multiply(n.subtract(1));
1249         final T incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2).
1250                              add(CarlsonEllipticIntegral.rJ(cM1, cMm, ar.csc2, cMn, delta).multiply(n).divide(3));
1251 
1252         // combine complete and incomplete parts
1253         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1254 
1255     }
1256 
1257     /** Get the incomplete elliptic integral of the third kind Π(n, φ, m).
1258      * <p>
1259      * <em>
1260      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1261      * are considered experimental for now, they have known issues.
1262      * </em>
1263      * </p>
1264      * <p>
1265      * The incomplete elliptic integral of the third kind Π(n, φ, m) is
1266      * \[
1267      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
1268      * \]
1269      * </p>
1270      * <p>
1271      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1272      * Carlson elliptic integrals}.
1273      * </p>
1274      * @param n elliptic characteristic
1275      * @param phi amplitude (i.e. upper bound of the integral)
1276      * @param m parameter (m=k² where k is the elliptic modulus)
1277      * @return incomplete elliptic integral of the third kind Π(n, φ, m)
1278      * @see #bigPi(Complex, Complex)
1279      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
1280      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1281      */
1282     public static Complex bigPi(final Complex n, final Complex phi, final Complex m) {
1283 
1284         // argument reduction
1285         final FieldArgumentReduction<Complex> ar = new FieldArgumentReduction<>(phi, m, parameter -> bigPi(n, parameter));
1286 
1287         // integrate part between 0 and π/2
1288         final Complex cM1        = ar.csc2.subtract(1);
1289         final Complex cMm        = ar.csc2.subtract(m);
1290         final Complex cMn        = ar.csc2.subtract(n);
1291         final Complex delta      = n.multiply(m.subtract(n)).multiply(n.subtract(1));
1292         final Complex incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2).
1293                                    add(CarlsonEllipticIntegral.rJ(cM1, cMm, ar.csc2, cMn, delta).multiply(n).divide(3));
1294 
1295         // combine complete and incomplete parts
1296         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1297 
1298     }
1299 
1300     /** Get the incomplete elliptic integral of the third kind Π(n, φ, m) using numerical integration.
1301      * <p>
1302      * <em>
1303      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1304      * are considered experimental for now, they have known issues.
1305      * </em>
1306      * </p>
1307      * <p>
1308      * The incomplete elliptic integral of the third kind Π(n, φ, m) is
1309      * \[
1310      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
1311      * \]
1312      * </p>
1313      * <p>
1314      * The algorithm for evaluating the functions is based on numerical integration.
1315      * If integration path comes too close to a pole of the integrand, then integration will fail
1316      * with a {@link org.hipparchus.exception.MathIllegalStateException MathIllegalStateException}
1317      * even for very large {@code maxEval}. This is normal behavior.
1318      * </p>
1319      * @param n elliptic characteristic
1320      * @param phi amplitude (i.e. upper bound of the integral)
1321      * @param m parameter (m=k² where k is the elliptic modulus)
1322      * @param integrator integrator to use
1323      * @param maxEval maximum number of evaluations (real and imaginary
1324      * @return incomplete elliptic integral of the third kind Π(n, φ, m)
1325      * @see #bigPi(Complex, Complex)
1326      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
1327      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1328      */
1329     public static Complex bigPi(final Complex n, final Complex phi, final Complex m,
1330                                 final ComplexUnivariateIntegrator integrator, final int maxEval) {
1331          return integrator.integrate(maxEval, new Third<>(n, m), phi.getField().getZero(), phi);
1332     }
1333 
1334     /** Get the incomplete elliptic integral of the third kind Π(n, φ, m).
1335      * <p>
1336      * <em>
1337      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1338      * are considered experimental for now, they have known issues.
1339      * </em>
1340      * </p>
1341      * <p>
1342      * The incomplete elliptic integral of the third kind Π(n, φ, m) is
1343      * \[
1344      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
1345      * \]
1346      * </p>
1347      * <p>
1348      * The algorithm for evaluating the functions is based on {@link CarlsonEllipticIntegral
1349      * Carlson elliptic integrals}.
1350      * </p>
1351      * @param n elliptic characteristic
1352      * @param phi amplitude (i.e. upper bound of the integral)
1353      * @param m parameter (m=k² where k is the elliptic modulus)
1354      * @param <T> the type of the field elements
1355      * @return incomplete elliptic integral of the third kind Π(n, φ, m)
1356      * @see #bigPi(FieldComplex, FieldComplex)
1357      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
1358      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1359      */
1360     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigPi(final FieldComplex<T> n,
1361                                                                             final FieldComplex<T> phi,
1362                                                                             final FieldComplex<T> m) {
1363 
1364         // argument reduction
1365         final FieldArgumentReduction<FieldComplex<T>> ar = new FieldArgumentReduction<>(phi, m, parameter -> bigPi(n, parameter));
1366 
1367         // integrate part between 0 and π/2
1368         final FieldComplex<T> cM1        = ar.csc2.subtract(1);
1369         final FieldComplex<T> cMm        = ar.csc2.subtract(m);
1370         final FieldComplex<T> cMn        = ar.csc2.subtract(n);
1371         final FieldComplex<T> delta      = n.multiply(m.subtract(n)).multiply(n.subtract(1));
1372         final FieldComplex<T> incomplete = CarlsonEllipticIntegral.rF(cM1, cMm, ar.csc2).
1373                                            add(CarlsonEllipticIntegral.rJ(cM1, cMm, ar.csc2, cMn, delta).multiply(n).divide(3));
1374 
1375         // combine complete and incomplete parts
1376         return ar.negate ? ar.complete.subtract(incomplete) : ar.complete.add(incomplete);
1377 
1378     }
1379 
1380     /** Get the incomplete elliptic integral of the third kind Π(n, φ, m).
1381      * <p>
1382      * <em>
1383      * BEWARE! Elliptic integrals for complex numbers in the incomplete case
1384      * are considered experimental for now, they have known issues.
1385      * </em>
1386      * </p>
1387      * <p>
1388      * The incomplete elliptic integral of the third kind Π(n, φ, m) is
1389      * \[
1390      *    \int_0^{\phi} \frac{d\theta}{\sqrt{1-m \sin^2\theta}(1-n \sin^2\theta)}
1391      * \]
1392      * </p>
1393      * <p>
1394      * The algorithm for evaluating the functions is based on numerical integration.
1395      * If integration path comes too close to a pole of the integrand, then integration will fail
1396      * with a {@link org.hipparchus.exception.MathIllegalStateException MathIllegalStateException}
1397      * even for very large {@code maxEval}. This is normal behavior.
1398      * </p>
1399      * @param n elliptic characteristic
1400      * @param phi amplitude (i.e. upper bound of the integral)
1401      * @param m parameter (m=k² where k is the elliptic modulus)
1402      * @param integrator integrator to use
1403      * @param maxEval maximum number of evaluations (real and imaginary
1404      * parts are evaluated separately, so up to twice this number may be used)
1405      * @param <T> the type of the field elements
1406      * @return incomplete elliptic integral of the third kind Π(n, φ, m)
1407      * @see #bigPi(FieldComplex, FieldComplex)
1408      * @see <a href="https://mathworld.wolfram.com/EllipticIntegraloftheThirdKind.html">Elliptic Integrals of the Third Kind (MathWorld)</a>
1409      * @see <a href="https://en.wikipedia.org/wiki/Elliptic_integral">Elliptic Integrals (Wikipedia)</a>
1410      */
1411     public static <T extends CalculusFieldElement<T>> FieldComplex<T> bigPi(final FieldComplex<T> n,
1412                                                                             final FieldComplex<T> phi,
1413                                                                             final FieldComplex<T> m,
1414                                                                             final FieldComplexUnivariateIntegrator<T> integrator,
1415                                                                             final int maxEval) {
1416         return integrator.integrate(maxEval, new Third<>(n, m), phi.getField().getZero(), phi);
1417     }
1418 
1419     /** Argument reduction for an incomplete integral. */
1420     private static class DoubleArgumentReduction {
1421 
1422         /** Complete part. */
1423         private final double complete;
1424 
1425         /** Squared cosecant of the Jacobi amplitude. */
1426         private final double csc2;
1427 
1428         /** Indicator for negated Jacobi amplitude. */
1429         private boolean negate;
1430 
1431         /** Simple constructor.
1432          * @param phi amplitude (i.e. upper bound of the integral)
1433          * @param m parameter (m=k² where k is the elliptic modulus)
1434          * @param integral provider for complete integral
1435          */
1436         DoubleArgumentReduction(final double phi, final double m, final DoubleFunction<Double> integral) {
1437             final double sin = FastMath.sin(phi);
1438             final int    p   = (int) FastMath.rint(phi / FastMath.PI);
1439             complete         = p == 0 ? 0 : integral.apply(m) * 2 * p;
1440             negate           = sin < 0 ^ (p & 0x1) == 1;
1441             csc2             = 1.0 / (sin * sin);
1442         }
1443 
1444     }
1445 
1446     /** Argument reduction for an incomplete integral.
1447      * @param <T> type fo the field elements
1448      */
1449     private static class FieldArgumentReduction<T extends CalculusFieldElement<T>> {
1450 
1451         /** Complete part. */
1452         private final T complete;
1453 
1454         /** Squared cosecant of the Jacobi amplitude. */
1455         private final T csc2;
1456 
1457         /** Indicator for negated Jacobi amplitude. */
1458         private boolean negate;
1459 
1460         /** Simple constructor.
1461          * @param phi amplitude (i.e. upper bound of the integral)
1462          * @param m parameter (m=k² where k is the elliptic modulus)
1463          * @param integral provider for complete integral
1464          */
1465         FieldArgumentReduction(final T phi, final T m, final Function<T, T> integral) {
1466             final T   sin = FastMath.sin(phi);
1467             final int p   = (int) FastMath.rint(phi.getReal() / FastMath.PI);
1468             complete      = p == 0 ? phi.getField().getZero() : integral.apply(m).multiply(2 * p);
1469             negate        = sin.getReal() < 0 ^ (p & 0x1) == 1;
1470             csc2          = sin.multiply(sin).reciprocal();
1471         }
1472 
1473     }
1474 
1475     /** Integrand for elliptic integrals of the first kind.
1476      * @param <T> type of the field elements
1477      */
1478     private static class First<T extends CalculusFieldElement<T>> implements CalculusFieldUnivariateFunction<T> {
1479 
1480         /** Parameter. */
1481         private final T m;
1482 
1483         /** Simple constructor.
1484          * @param m parameter (m=k² where k is the elliptic modulus)
1485          */
1486         First(final T m) {
1487             this.m = m;
1488         }
1489 
1490         /** {@inheritDoc} */
1491         @Override
1492         public T value(final T theta) {
1493             final T sin  = theta.sin();
1494             final T sin2 = sin.multiply(sin);
1495             return sin2.multiply(m).negate().add(1).sqrt().reciprocal();
1496         }
1497 
1498     }
1499 
1500     /** Integrand for elliptic integrals of the second kind.
1501      * @param <T> type of the field elements
1502      */
1503     private static class Second<T extends CalculusFieldElement<T>> implements CalculusFieldUnivariateFunction<T> {
1504 
1505         /** Parameter. */
1506         private final T m;
1507 
1508         /** Simple constructor.
1509          * @param m parameter (m=k² where k is the elliptic modulus)
1510          */
1511         Second(final T m) {
1512             this.m = m;
1513         }
1514 
1515         /** {@inheritDoc} */
1516         @Override
1517         public T value(final T theta) {
1518             final T sin = theta.sin();
1519             final T sin2 = sin.multiply(sin);
1520             return sin2.multiply(m).negate().add(1).sqrt();
1521         }
1522 
1523     }
1524 
1525     /** Integrand for elliptic integrals of the third kind.
1526      * @param <T> type of the field elements
1527      */
1528     private static class Third<T extends CalculusFieldElement<T>> implements CalculusFieldUnivariateFunction<T> {
1529 
1530         /** Elliptic characteristic. */
1531         private final T n;
1532 
1533         /** Parameter. */
1534         private final T m;
1535 
1536         /** Simple constructor.
1537          * @param n elliptic characteristic
1538          * @param m parameter (m=k² where k is the elliptic modulus)
1539          */
1540         Third(final T n, final T m) {
1541             this.n = n;
1542             this.m = m;
1543         }
1544 
1545         /** {@inheritDoc} */
1546         @Override
1547         public T value(final T theta) {
1548             final T sin  = theta.sin();
1549             final T sin2 = sin.multiply(sin);
1550             final T d1   = sin2.multiply(m).negate().add(1).sqrt();
1551             final T da   = sin2.multiply(n).negate().add(1);
1552             return d1.multiply(da).reciprocal();
1553         }
1554 
1555     }
1556 }