back to table · edit · history · where entries came from · files · download
2376 bytes, as of the version from 2026-10-26 08:43. Recorded here, not run.
"""Values of the Kelvin function kei_nu(x) -- numberdb.org/T509.
Run with SageMath (or a compatible passagemath installation):
sage -pip install numberdb
sage -python generate.py # verify every stored entry
sage -python generate.py --fill # fill an authorized draft
The fill command requires NUMBERDB_API_KEY. It writes entries and attaches
this source; it does not publish the draft or offer it for review.
DLMF 10.61.2 fixes the principal-branch definition:
kei_nu(x) = Im(exp(-nu*pi*i/2) K_nu(x exp(pi*i/4))).
The phase is exact at the integer orders stored here. Rational arguments and
the rotation are enclosed in complex balls. The 64-bit guard is measured by
checks.py, which also checks all values by independent certified quadrature.
The finite selection is the family #205 rectangle of low integer orders at
simple integer, half-, third-, and quarter-unit arguments through x=20.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.complex_arb import ComplexBallField
WORKING_GUARD = 64
class KelvinKei(numberdb.Generator):
table = "T509"
parameters = ("nu", "x")
type = "R"
digits = 100
rigour = "proven"
def enumerate(self):
arguments = sorted({QQ(a)/QQ(b) for b in range(1, 5)
for a in range(1, 20*b+1)})
for nu in range(3):
for x in arguments:
yield {"nu": str(nu), "x": str(x)}
def value(self, params, digits):
nu = QQ(params["nu"])
if nu.denominator() != 1:
raise ValueError("This generator uses the exact integer-order phase.")
C = ComplexBallField(numberdb.bits(digits, losing=WORKING_GUARD))
z = C(QQ(params["x"])) * C(1, 1) / C(2).sqrt()
return (C(0, -1)**int(nu) * z.bessel_K(C(nu))).imag()
if __name__ == "__main__":
if os.environ.get("NUMBERDB_KEY_FROM_STDIN") == "1":
os.environ["NUMBERDB_API_KEY"] = sys.stdin.read().strip()
generator = KelvinKei()
if "--fill" in sys.argv or os.environ.get("NUMBERDB_PUBLISH") == "1":
outcome = generator.publish(message="Fill Kelvin kei values with certified 100-digit enclosures")
print(outcome)
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)