The Gauss hypergeometric function
#include <flint/acb_hypgeom.h>void acb_hypgeom_2f1(acb_t res, const acb_t a, const acb_t b, const acb_t c, const acb_t z, int flags, slong prec)sourceSets res to , or if flags contains ACB_HYPGEOM_2F1_REGULARIZED, with an automatic choice of algorithm. The other flags declare that a parameter difference is an exact integer even if the input balls are inexact, so that the correct limit is computed where a transformation formula is singular.
The flags ACB_HYPGEOM_2F1_AB () and ACB_HYPGEOM_2F1_ABC () are used in this way; AC and BC are accepted but currently unused. For example, to evaluate , set ACB_HYPGEOM_2F1_ABC; otherwise the transformation divides by computed on a ball containing zero and the result is indeterminate. If the parameters are exact (including exact integers and half-integers), the limits are detected automatically and the flags are unnecessary.
The function handles special parameters first (terminating series, and , or for , reduction to a polynomial by the Pfaff transformation when or is a nonpositive integer), then chooses with acb_hypgeom_2f1_choose between direct summation, one of five transformations and the corner case, and retries real arguments with arb_hypgeom_2f1_integration if the result is inaccurate. See The Gauss hypergeometric function and The Gauss hypergeometric function.
acb_hypgeom_2f1 computes the Gauss hypergeometric function , or the regularized function if the flag ACB_HYPGEOM_2F1_REGULARIZED is set, for all complex , with the branch cut . arb_hypgeom_2f1 is the real version and accepts the same flags. The series converges only for , and slowly near ; the function covers the plane with five linear fractional transformations, evaluates the limits of these formulas at integer parameter differences, continues analytically along a path near the two points that no transformation reaches, and falls back to numerical integration for real arguments. The algorithms are described in The Gauss hypergeometric function.
Algorithm selection#
- Non-finite input gives an indeterminate result; gives 1 (or ).
- For with a nonpositive integer , the result is 0 if or is a nonpositive integer at least (the series terminates before the poles). If or , the regularized function is or .
- If or is a nonpositive integer with , the function is a polynomial of degree , summed directly for any .
- If is exact and (or ) is a nonpositive integer, the Pfaff transformation turns the function into a polynomial.
- At , Gauss's formula is used if ; otherwise the result is indeterminate.
- Otherwise
acb_hypgeom_2f1_chooseselects direct summation, one of the transformations , , , , ofacb_hypgeom_2f1_transform, or the corner caseacb_hypgeom_2f1_corner, by minimizing the modulus of the new argument (direct summation is preferred for ). - If the result has less than half the requested accuracy and less than half the accuracy of the inputs, and all arguments are real and smaller than ,
arb_hypgeom_2f1_integrationis tried and the better enclosure is returned.
Integer parameter differences#
The transformations to and divide by , and those to and by , which vanish when the parameter difference is an integer; the function then computes the limit (by differentiating with respect to a perturbation of ). It recognizes an integer difference only if it can prove it from the balls, which works for exact parameters but not, for instance, for and , whose computed difference is an inexact ball containing . The flags ACB_HYPGEOM_2F1_AB and ACB_HYPGEOM_2F1_ABC declare that or is an exact integer; the caller is responsible for this being true. The flags ACB_HYPGEOM_2F1_AC and ACB_HYPGEOM_2F1_BC are accepted but currently not used.
Example#
With known only as a ball, the transformation to needed at fails unless the flag is given; near the corner case (method 6) is used; on the branch cut, the value is the limit from the lower half-plane:
#include <flint/acb.h>
#include <flint/acb_hypgeom.h>
int main(void)
{
acb_t a, b, c, z, r;
acb_init(a);
acb_init(b);
acb_init(c);
acb_init(z);
acb_init(r);
/* a = sqrt(2) + i/2, b = 1/2, c = a + b + 1: c - a - b = 1 exactly,
but not as balls */
acb_set_ui(a, 2);
acb_sqrt(a, a, 64);
arb_set_d(acb_imagref(a), 0.5);
acb_set_d(b, 0.5);
acb_add_ui(c, a, 1, 64);
acb_add(c, c, b, 64);
acb_set_ui(z, 9);
acb_div_ui(z, z, 10, 64);
acb_hypgeom_2f1(r, a, b, c, z, 0, 64);
flint_printf("no flags : "); acb_printn(r, 15, 0); flint_printf("\n");
acb_hypgeom_2f1(r, a, b, c, z, ACB_HYPGEOM_2F1_ABC, 64);
flint_printf("ABC flag : "); acb_printn(r, 15, 0); flint_printf("\n");
/* near exp(pi i/3) none of the transformations converges well */
acb_set_d(a, 0.25);
acb_set_d(b, 1.5);
acb_set_ui(c, 3);
acb_set_d_d(z, 0.5, 0.875);
flint_printf("method : %d\n", acb_hypgeom_2f1_choose(z));
acb_hypgeom_2f1(r, a, b, c, z, 0, 64);
flint_printf("corner : "); acb_printn(r, 15, 0); flint_printf("\n");
/* on the branch cut (1, +inf): the limit from the lower half-plane */
acb_set_ui(z, 3);
acb_hypgeom_2f1(r, a, b, c, z, 0, 64);
flint_printf("z = 3 : "); acb_printn(r, 15, 0); flint_printf("\n");
acb_clear(a);
acb_clear(b);
acb_clear(c);
acb_clear(z);
acb_clear(r);
flint_cleanup();
return 0;
}no flags : nan + nan*I ABC flag : [1.45790187393845 +/- 4.64e-15] + [0.110163228098910 +/- 3.70e-16]*I method : 6 corner : [1.01464883732715 +/- 1.70e-15] + [0.134531649059307 +/- 4.70e-16]*I z = 3 : [0.995480256475680 +/- 1.90e-16] + [-0.581843941733150 +/- 3.74e-16]*I
For real parameters, the first call would not fail: acb_hypgeom_2f1 would fall back to arb_hypgeom_2f1_integration, which needs no transformation. With a complex parameter, as here, only the flag helps.
The FLINT team, “The Gauss hypergeometric function (acb_hypgeom.h),” FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev, 2026. https://flintlib.org/doc/acb_hypgeom/2f1.html (generated 2026-11-02).
@misc{flint-doc-acb-hypgeom-2f1,
author = {{The FLINT team}},
title = {{The Gauss hypergeometric function (acb\_hypgeom.h)}},
howpublished = {FLINT: Fast Library for Number Theory, documentation, version 3.7.0-dev},
year = {2026},
url = {https://flintlib.org/doc/acb_hypgeom/2f1.html},
note = {Generated 2026-11-02}
}