High-precision calculations for one- and two-valence atomic systems
Hypergeometric.hpp
1#pragma once
2#include <complex>
3
4//! Hypergeometric functions
5namespace Hypergeometric {
6
7//! True if compiled with FLINT support; complex H1f1 returns zero otherwise
8constexpr bool has_flint =
9#if defined(AMPSCI_USE_FLINT3) || defined(AMPSCI_USE_FLINT2)
10 true;
11#else
12 false;
13#endif
14
15/*!
16 @brief Scaled confluent hypergeometric function: e^{s} * 1F1(a, b, z)
17 @details
18 - @p a and @p z may be complex (via template). @p s and @p b must be real
19
20 @p T (template param) may be double or std::complex<double>.
21
22 Real (double) arguments: evaluated with GSL (double precision); the scale
23 e^{s} is applied as an ordinary double factor.
24
25 Complex arguments: first attempts a fast double-precision evaluation
26 (Maclaurin series at small |z|, asymptotic expansion at large |z|, each
27 with a running error estimate); this covers most continuum-state calls at
28 ~100x the speed of ball arithmetic. Where the estimated error is too
29 large (strong cancellation: large Im(a) with moderate |z|), falls back to
30 FLINT ball arithmetic, increasing the working precision until the result
31 is accurate to (at least) full double precision. The scale e^{s} is
32 applied inside the evaluation, so exponentially small 1F1 values (e.g.
33 like e^{-pi*nu/2} for continuum Coulomb functions) can be paired with
34 their compensating normalisation factors without under/overflowing
35 double.
36
37 @note Requires FLINT library to work with complex values.
38 Compile with `-lflint` and set `-DAMPSCI_USE_FLINT3` (FLINT 3+), or with
39 `-lflint-arb -lflint` and `-DAMPSCI_USE_FLINT2` (FLINT 2.x + Arb)
40 (done automatically by Makefile/configure.sh)
41
42 @warning Uses IFDEF to allow compilation if FLINT is not available.
43 However, functions must not be called if FLINT is not installed.
44 Will abort, or return nan if called without FLINT.
45 Always use `if constexpr (Hypergeometric::has_flint) {}` in code,
46 to check if available; see @ref Hypergeometric::has_flint
47*/
48template <typename T>
49T H1f1(T a, double b, T z, double s = 0.0);
50
51} // namespace Hypergeometric
Hypergeometric functions.
Definition Hypergeometric.cpp:32
constexpr bool has_flint
True if compiled with FLINT support; complex H1f1 returns zero otherwise.
Definition Hypergeometric.hpp:8
T H1f1(T a, double b, T z, double s)
Scaled confluent hypergeometric function: e^{s} * 1F1(a, b, z)
Definition Hypergeometric.cpp:214