FLINT3.7.0-dev

Carlson symmetric integrals

Synopsis#include <flint/acb_elliptic.h>
void acb_elliptic_rf(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec)source

Sets res to the Carlson symmetric integral of the first kind RF(x,y,z)=12∫0∞((t+x)(t+y)(t+z))−1/2 dtR_F(x, y, z) = \frac12 \int_0^\infty ((t+x)(t+y)(t+z))^{-1/2} \, dt, by duplication steps followed by a Taylor series in the elementary symmetric polynomials of the deviations. The result is indeterminate if more than one argument contains zero.

void acb_elliptic_rg(acb_t res, const acb_t x, const acb_t y, const acb_t z, int flags, slong prec)source

Sets res to the Carlson symmetric integral of the second kind RGR_G, computed from RFR_F and RDR_D. There are no restrictions on the arguments.

void acb_elliptic_rj(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec)source
void acb_elliptic_rj_carlson(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec)source
void acb_elliptic_rj_integration(acb_t res, const acb_t x, const acb_t y, const acb_t z, const acb_t p, int flags, slong prec)source

Set res to the Carlson symmetric integral of the third kind RJ(x,y,z,p)=32∫0∞(t+p)−1((t+x)(t+y)(t+z))−1/2 dtR_J(x, y, z, p) = \frac32 \int_0^\infty (t+p)^{-1} ((t+x)(t+y)(t+z))^{-1/2} \, dt. The carlson version uses the duplication algorithm, which can give wrong values for some complex arguments; the integration version moves the arguments to the right half-plane by numerical integration; the default version uses the duplication algorithm when it is known to be correct (including the case p=zp = z, which computes RD(x,y,z)R_D(x, y, z)) and integration otherwise.

void acb_elliptic_rc1(acb_t res, const acb_t x, slong prec)source

Sets res to RC(1,1+x)=atan⁡(x)/xR_C(1, 1+x) = \operatorname{atan}(\sqrt{x})/\sqrt{x}, a helper for RJR_J, using a short Taylor series for small ∣x∣|x|.

Carlson's symmetric integrals are

RF(x,y,z)=12∫0∞dt(t+x)(t+y)(t+z),RJ(x,y,z,p)=32∫0∞dt(t+p)(t+x)(t+y)(t+z),R_F(x,y,z) = \frac{1}{2} \int_0^{\infty} \frac{dt}{\sqrt{(t+x)(t+y)(t+z)}}, \qquad R_J(x,y,z,p) = \frac{3}{2} \int_0^{\infty} \frac{dt}{(t+p)\sqrt{(t+x)(t+y)(t+z)}},
RG(x,y,z)=14∫0∞t(t+x)(t+y)(t+z)(xt+x+yt+y+zt+z)dt,R_G(x,y,z) = \frac{1}{4} \int_0^{\infty} \frac{t}{\sqrt{(t+x)(t+y)(t+z)}} \left( \frac{x}{t+x} + \frac{y}{t+y} + \frac{z}{t+z}\right) dt,

with the special cases RC(x,y)=RF(x,y,y)R_C(x, y) = R_F(x, y, y) and RD(x,y,z)=RJ(x,y,z,z)R_D(x, y, z) = R_J(x, y, z, z). The square root is the continuous branch that is positive for large tt [NIST2012, §19.16]. Every elliptic integral, and in particular every Legendre integral of Legendre incomplete elliptic integrals, can be written in terms of RFR_F, RDR_D, RJR_J and RGR_G; the symmetric forms have simpler transformation laws and, unlike the Legendre forms, a uniform algorithm. The definitions and algorithms follow [Car1995] and [NIST2012, Ch. 19], with the high-order Taylor expansion of [Joh2019].

Domains#

The integral for RFR_F is well defined for x,y,zx, y, z in C∖(−∞,0)\mathbb{C} \setminus (-\infty, 0) with at most one of them zero; it is extended to the negative real axis by the same formula, which then depends on the side of the cut chosen by the principal square root. The integral for RJR_J also requires p∉(−∞,0]p \notin (-\infty, 0]. The functions return indeterminate results when more than one of x,y,zx, y, z, or when pp, contains zero, and when an input is not finite. RGR_G has no restrictions on its arguments: acb_elliptic_rg uses the formula [NIST2012, 19.21.10]

2RG(x,y,z)=zRF(x,y,z)−13(x−z)(y−z)RD(x,y,z)+xy/z,2 R_G(x, y, z) = z R_F(x, y, z) - \tfrac13 (x - z)(y - z) R_D(x, y, z) + \sqrt{x y / z},

after permuting the arguments so that zz does not contain zero (the cases where two arguments are exactly zero give w/2\sqrt{w}/2 directly).

Method#

acb_elliptic_rf and acb_elliptic_rj_carlson use Carlson's duplication algorithm. The duplication theorem

RF(x,y,z)=RF ⁣(x+λ4,y+λ4,z+λ4),λ=xy+yz+zx,R_F(x, y, z) = R_F\!\left(\tfrac{x + \lambda}{4}, \tfrac{y + \lambda}{4}, \tfrac{z + \lambda}{4}\right), \qquad \lambda = \sqrt{x}\sqrt{y} + \sqrt{y}\sqrt{z} + \sqrt{z}\sqrt{x},

(and its analogue for RJR_J, which adds a sum of RCR_C terms, computed with acb_elliptic_rc1) brings the arguments closer together by a factor about 4 per step. Once the relative deviations from their mean are small, a multivariate Taylor series in the elementary symmetric polynomials of the deviations is summed. Instead of Carlson's fixed series of degree 5 or 7 and many duplication steps, FLINT sums about 2.1p0.42.1 p^{0.4} terms (real arguments) or 2.5p0.42.5 p^{0.4} terms (complex arguments) at precision pp, capped at 500, which balances the two costs at high precision, with exact rational coefficients and a rigorous bound for the tail. The working precision is lowered to the relative accuracy of the inputs plus 20 bits when the inputs are inexact. The details and proofs are in Elliptic integrals, elliptic functions and modular forms.

Correctness of the duplication algorithm for RJR_J#

For RFR_F the duplication algorithm with principal square roots is valid everywhere. For RJR_J it is not: the square roots and the RCR_C terms can cross branch cuts, and then acb_elliptic_rj_carlson returns a wrong value with a small radius. According to [Car1995], a sufficient condition for correctness is that x,y,zx, y, z have nonnegative real part and pp has positive real part. acb_elliptic_rj_carlson does not check anything.

acb_elliptic_rj uses the duplication algorithm when one of the following sufficient conditions holds, and acb_elliptic_rj_integration otherwise:

  • one of x,y,zx, y, z is equal to pp, that is, the function is RDR_D (the duplication algorithm for RDR_D is valid everywhere);
  • x,y,zx, y, z have nonnegative real part and pp has positive real part;
  • all four arguments are real;
  • Re⁡(p)≥0\operatorname{Re}(p) \ge 0 or Im⁡(p)≠0\operatorname{Im}(p) \ne 0, and one of x,y,zx, y, z is real and nonnegative while the other two are complex conjugates.

Before integrating, it returns an indeterminate result if some argument straddles the negative real axis. acb_elliptic_rj_integration chooses NN with x+N,y+N,z+N,p+Nx + N, y + N, z + N, p + N in the right half-plane and writes

RJ(x,y,z,p)=32∫0Ndt(t+p)(t+x)(t+y)(t+z)+RJ(x+N,y+N,z+N,p+N),R_J(x, y, z, p) = \frac32 \int_0^N \frac{dt}{(t+p)\sqrt{(t+x)(t+y)(t+z)}} + R_J(x+N, y+N, z+N, p+N),

computing the integral with acb_calc_integrate along a path deformed into the upper or lower half-plane (and substituting t→t2t \to t^2 when an argument is zero) and the second term by duplication. This is reliable but much slower than the duplication algorithm alone.

Example#

The program computes RF(0,1,2)=Γ(1/4)2/(42π)R_F(0, 1, 2) = \Gamma(1/4)^2 / (4 \sqrt{2\pi}), checks the Legendre relation E(m)=RF(0,1−m,1)−m3RD(0,1−m,1)E(m) = R_F(0, 1-m, 1) - \frac{m}{3} R_D(0, 1-m, 1) against acb_elliptic_e, and evaluates an RJR_J at complex arguments where the duplication algorithm alone gives a wrong value.

Exampleacb_elliptic_carlson.cchecked by make checkdoc
#include <flint/acb.h>
#include <flint/acb_elliptic.h>

int main(void)
{
    acb_t x, y, z, p, r, s, m;
    slong prec = 128;

    acb_init(x); acb_init(y); acb_init(z); acb_init(p);
    acb_init(r); acb_init(s); acb_init(m);

    acb_set_ui(y, 1);
    acb_set_ui(z, 2);
    acb_elliptic_rf(r, x, y, z, 0, prec);
    flint_printf("R_F(0,1,2)    = "); acb_printn(r, 30, 0); flint_printf("\n");

    /* E(m) = R_F(0, 1-m, 1) - (m/3) R_D(0, 1-m, 1) with m = 3/4 */
    acb_set_d(m, 0.75);
    acb_sub_ui(y, m, 1, prec);
    acb_neg(y, y);
    acb_one(z);
    acb_elliptic_rf(r, x, y, z, 0, prec);
    acb_elliptic_rj(s, x, y, z, z, 0, prec);
    acb_mul(s, s, m, prec);
    acb_div_ui(s, s, 3, prec);
    acb_sub(r, r, s, prec);
    flint_printf("via R_F, R_D  = "); acb_printn(r, 30, 0); flint_printf("\n");
    acb_elliptic_e(r, m, prec);
    flint_printf("E(3/4)        = "); acb_printn(r, 30, 0); flint_printf("\n");

    acb_set_d_d(x, 2.0, 3.0);
    acb_set_d_d(y, -1.0, -1.0);
    acb_set_d_d(z, -2.0, -1.0);
    acb_set_d_d(p, -4.0, 1.0);
    acb_elliptic_rj(r, x, y, z, p, 0, 64);
    flint_printf("R_J           = "); acb_printn(r, 10, 0); flint_printf("\n");
    acb_elliptic_rj_carlson(r, x, y, z, p, 0, 64);
    flint_printf("R_J (carlson) = "); acb_printn(r, 10, 0); flint_printf("\n");

    acb_clear(x); acb_clear(y); acb_clear(z); acb_clear(p);
    acb_clear(r); acb_clear(s); acb_clear(m);
    return 0;
}
Output
R_F(0,1,2)    = [1.31102877714605990523241979495 +/- 4.45e-30]
via R_F, R_D  = [1.21105602756845952480356289955 +/- 1.03e-30]
E(3/4)        = [1.21105602756845952480356289955 +/- 1.03e-30]
R_J           = [0.1948611350 +/- 1.75e-11] + [-1.020158039 +/- 3.81e-10]*I
R_J (carlson) = [-0.9832009839 +/- 1.42e-11] + [1.009854664 +/- 2.79e-10]*I

The value from acb_elliptic_rj agrees with a direct numerical evaluation of the defining integral, 0.1948611…−1.0201580…i0.1948611\ldots - 1.0201580\ldots i; the duplication algorithm, applied outside its domain of validity, returns a different number with a tight but wrong enclosure.

References#

  • [NIST2012] National Institute of Standards and Technology, Digital Library of Mathematical Functions (2012), https://dlmf.nist.gov/
  • [Car1995] B. C. Carlson, "Numerical computation of real or complex elliptic integrals". Numerical Algorithms, 10(1):13-26 (1995).
  • [Joh2019] F. Johansson. Numerical evaluation of elliptic functions, elliptic integrals and modular forms. In J. Blümlein, C. Schneider and P. Paule (eds.), Elliptic Integrals, Elliptic Functions and Modular Forms in Quantum Field Theory, Texts & Monographs in Symbolic Computation, Springer, 2019, 269–293. https://arxiv.org/abs/1806.06725
Cite this page

The FLINT team, “Carlson symmetric integrals (acb_elliptic.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/acb_elliptic/carlson.html (generated 2026-11-02).