acb.hBranch cuts
The complex logarithm, square root, powers, inverse trigonometric and inverse hyperbolic functions, the polylogarithm, the log-gamma function and others are multivalued. The functions of acb return their principal values, defined by branch cuts that follow the conventions of the DLMF [NIST2012] and of most computer algebra systems.
The principal branches#
| Function | Branch cut | Value on the cut |
|---|---|---|
acb_log, acb_arg | (-\infty, 0] | continuous from above: \arg x = \pi for x < 0 |
acb_sqrt, acb_rsqrt, acb_root_ui, acb_pow | (-\infty, 0) | continuous from above: \sqrt{-1} = i |
acb_asin, acb_acos | (-\infty, -1) \cup (1, +\infty) | |
acb_atan | (-i\infty, -i) \cup (i, +i\infty) | |
acb_asinh | (-i\infty, -i) \cup (i, +i\infty) | |
acb_acosh | (-\infty, 1) | |
acb_atanh | (-\infty, -1) \cup (1, +\infty) | |
acb_lgamma, acb_log_barnes_g | (-\infty, 0] | |
acb_polylog | (1, +\infty) | |
acb_agm1 | (-\infty, 0) | continuous from above |
acb_lambertw | see [CGHJK1996] |
The inverse functions are defined by formulas in terms of the logarithm and the square root, so their branch cuts follow from those of acb_log and acb_sqrt; the definitions are given with each function on the module page.
Rectangles on and across a cut#
A function evaluated at a point exactly on a branch cut returns the value given by the convention above. A rectangle that only touches or crosses the cut contains points on both sides, where the function values differ by a jump, so the result must enclose both values: the imaginary part of acb_log of a rectangle that crosses the negative real axis encloses [-\pi, \pi], and the square root of a rectangle around -4 encloses both 2i and -2i.
#include <flint/flint.h>
#include <flint/acb.h>
#define SHOW(label, x) do { flint_printf("%-26s", label); \
acb_printn(x, 8, 0); flint_printf("\n"); } while (0)
int main(void)
{
acb_t z, w, w2;
slong prec = 64;
acb_init(z); acb_init(w); acb_init(w2);
acb_set_si(z, -4); /* on the cut */
acb_sqrt(w, z, prec); SHOW("sqrt(-4)", w);
acb_log(w, z, prec); SHOW("log(-4)", w);
arb_set_str(acb_imagref(z), "-1e-10", prec); /* just below it */
acb_sqrt(w, z, prec); SHOW("sqrt(-4 - 1e-10 i)", w);
arb_set_str(acb_imagref(z), "[+/- 1e-10]", prec); /* across it */
acb_sqrt(w, z, prec); SHOW("sqrt(-4 + [+/- 1e-10] i)", w);
acb_sqrt_analytic(w, z, 1, prec); SHOW("analytic version", w);
acb_sqrts(w, w2, z, prec); SHOW("sqrts, first", w);
SHOW("sqrts, second", w2);
acb_clear(z); acb_clear(w); acb_clear(w2);
flint_cleanup();
return 0;
}sqrt(-4) 2.0000000*I log(-4) [1.3862944 +/- 3.89e-8] + [3.1415927 +/- 4.65e-8]*I sqrt(-4 - 1e-10 i) [2.5000000e-11 +/- 9.66e-31] + [-2.0000000 +/- 3.50e-21]*I sqrt(-4 + [+/- 1e-10] i) [+/- 2.51e-11] + [+/- 2.01]*I analytic version nan + nan*I sqrts, first [+/- 2.51e-11] + [2.0000000 +/- 1.57e-22]*I sqrts, second [+/- 2.51e-11] + [-2.0000000 +/- 1.57e-22]*I
This is a frequent source of unexpectedly wide results: a quantity that is mathematically a negative real number but computed with a tiny imaginary error term [\pm \varepsilon] i straddles the cut. When the imaginary part is known to be zero, set it to zero exactly (arb_zero(acb_imagref(z))) before calling the function.
Analytic variants#
Rigorous integration (acb_calc_integrate) and other algorithms that rely on analyticity must know when the integrand is not analytic on the input. The functions acb_sqrt_analytic, acb_rsqrt_analytic, acb_log_analytic and acb_pow_analytic take a flag analytic; when it is set and the input rectangle touches the branch cut (including a point exactly on it), they return an indeterminate result instead of an enclosure of both branches. The piecewise real functions acb_real_abs, acb_real_sgn, acb_real_floor, acb_real_max and others behave in the same way at their discontinuities. Most special functions in acb_hypgeom and elsewhere do not detect branch cuts automatically; their documentation states the cuts, and an integrand that uses them near a cut must check this itself.
Avoiding branch cuts#
acb_sqrtsreturns both square roots, with no loss of accuracy near the cut, when the choice of branch does not matter or is made later.acb_log_sin_piandacb_lgammaimplement \log \sin(\pi z) and \log \Gamma(z) with the branch structure that makes functional equations hold everywhere, rather than as \log of the function.acb_agm1andacb_agmchoose the optimal square root at each step of the AGM iteration and are continuous except on a single cut.acb_lambertwprovides nonstandard branches (ACB_LAMBERTW_LEFTandACB_LAMBERTW_MIDDLE) that are continuous across the standard cuts.
References#
- [NIST2012] National Institute of Standards and Technology, Digital Library of Mathematical Functions (2012), https://dlmf.nist.gov/
- [CGHJK1996] R. M. Corless, G. H. Gonnet, D. E. Hare, D. J. Jeffrey and D. E. Knuth, "On the Lambert W function", Advances in Computational Mathematics, 5(1) (1996), 329-359
The FLINT team, “Branch cuts (acb.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/acb/branch-cuts.html (generated 2026-10-20).
@misc{flint-doc-acb-branch-cuts,
author = {{The FLINT team}},
title = {{Branch cuts (acb.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/acb/branch-cuts.html},
note = {Generated 2026-10-20}
}