fredrikj.net / blog /

Hypergeometric functions in Arb

November 9, 2014

The git master of Arb now supports evaluating complex-valued hypergeometric functions. Currently, the following can be done:

To have something pretty to show, here is a plot of J14i(z)J_{-1-4i}(z) as a function of zz on [10,10]+[10,10]i[-10,10] + [-10,10] i, and a plot of Jν(14i)J_{\nu}(-1-4i) as a function of ν\nu (see this earlier post for the plotting code):

Bessel J of z Bessel J of nu

Before you get too excited, please note that the following important features (all found in mpmath, but of course without error bounds) are not available:

Also, no asymptotically fast algorithms (binary splitting, bit-burst evaluation, summation using fast multipoint evaluation) have been implemented yet. But note that Arb already does feature binary splitting evaluation of hypergeometric series with purely rational coefficients, used for high-precision computation of constants such as π\pi.

As mentioned above, I've already implemented the error function and the first Bessel function. Other functions that can be implemented in a similar way using the available tools include: exponential/trigonometric/logarithmic integrals, various scaled error functions, the Bessel function Iν(z)I_{\nu}(z), Airy functions, upper and lower incomplete gamma functions, and a few others. Some other hypergeometric special functions can not be implemented as straightforwardly: Kn(z)K_n(z) is an example; another is the Legendre function Pν(z)P_{\nu}(z) for noninteger ν\nu, which requires analytic continuation of 2F1{}_2F_1 unless z1|z| \ll 1.

The mandatory benchmark shootout is between MPFR 3.1.2 (real arguments only), mpmath in Sage-6.3, and Arb. Here are timings in seconds for computing erf(z)\operatorname{erf}(z):

zz Digits MPFR mpmath Arb
π\pi 10 0.000021 0.00011 0.000030
π\pi 100 0.00020 0.00033 0.00011
π\pi 1000 0.012 0.0048 0.0014
π\pi 10000 1.3 0.76 0.071
10π10 \pi 10 0.00000023 0.000011 0.0000062
10π10 \pi 100 0.00000026 0.000011 0.0000061
10π10 \pi 1000 0.089 0.061 0.0040
10π10 \pi 10000 4.1 1.7 0.15
(10+10i)π(10+10i) \pi 10 - 0.00036 0.000013
(10+10i)π(10+10i) \pi 100 - 0.00042 0.000070
(10+10i)π(10+10i) \pi 1000 - 0.10 0.019
(10+10i)π(10+10i) \pi 10000 - 17 0.26

Unsurprisingly, MPFR is faster at low precision and when the result is indistinguishable from 1, since it uses non-generic code with less overhead. Arb is faster at higher precision mainly due to using rectangular splitting for series summation.

I did cheat a bit with the complex input z=(10+10i)πz = (10+10i) \pi in this benchmark. The way the error function is implemented right now, it computes with the same internal precision as the target precision. At 10 and 100 digits, the asymptotic expansion is used for this input, which gives full accuracy. But the asymptotic expansion only gives up to 850 digit accuracy for this input. So at 1000 and 10000 digits, the convergent 1F1{}_1F_1 series is used. However, this loses some 850 digits due to cancellation in the summation. So for this benchmark, I increased the precision by 3000 bits to get timings for actually computing a result accurate to 1000 and 10000 digits respectively. The code could be improved to automatically estimate the amount of cancellation and adjust the precision accordingly. This is only a problem near the "diagonals" in the complex plane: near the imaginary and real axes, erf is computed using cancellation-free series.

Here is a plot of erf on [10,10]+[10,10]i[-10,10] + [-10,10] i. To generate it, I edited the plotting code to automatically repeat with higher precision on any point near the diagonal where the output turned out have poor accuracy at the initial precision of 128 bits. The possibility to easily detect and correct such errors is a luxury that comes with ball or interval arithmetic!

Error function

Below are three plots generated only using a single algorithm and a precision of 128 bits, with a gray pixel inserted whenever this failed to give more than 3 bits of accuracy. Left: the 1F1{}_1F_1 series, middle: the 1F1{}_1F_1 series with Kummer's transformation, right: the asymptotic series.

Error function, 1F1 a Error function, 1F1 b Error function, asymptotic series

To conclude, here are timings for computing the Bessel function Jν(z)J_{\nu}(z). MPFR only supports integer ν\nu and real zz.

ν\nu zz Digits MPFR mpmath Arb
2 π\pi 10 0.0000058 0.00017 0.0000098
2 π\pi 100 0.000037 0.00027 0.000046
2 π\pi 1000 0.0022 0.0020 0.00060
2 π\pi 10000 0.41 0.33 0.032
2 106π10^6 \pi 10 0.000013 0.00040 0.000014
2 106π10^6 \pi 100 0.000064 0.00036 0.000073
2 106π10^6 \pi 1000 0.0054 0.012 0.0020
2 106π10^6 \pi 10000 0.64 1.1 0.19
2+3i (10+10i)π(10+10i) \pi 10 - 0.00080 0.000045
2+3i (10+10i)π(10+10i) \pi 100 - 0.0022 0.00033
2+3i (10+10i)π(10+10i) \pi 1000 - 0.95 0.014
2+3i (10+10i)π(10+10i) \pi 10000 - - 3.8
(1+i)π(1+i)\pi (100+100i)π(100+100i) \pi 10 - 0.00075 0.000042
(1+i)π(1+i)\pi (100+100i)π(100+100i) \pi 100 - 0.0019 0.00063
(1+i)π(1+i)\pi (100+100i)π(100+100i) \pi 1000 - 0.64 0.079
(1+i)π(1+i)\pi (100+100i)π(100+100i) \pi 10000 - - 12.2


fredrikj.net  |  Blog index  |  RSS feed  |  Follow me on Mastodon  |  Become a sponsor