back to table · edit · history · where entries came from · files · download
3261 bytes, as of the version from 2026-09-20 02:29 (current). Recorded here, not run.
"""Values of the incomplete elliptic integral of the first kind F(phi, m) -- numberdb.org/T349
The table stores real principal values of
F(phi, m) = int_0^phi dtheta / sqrt(1 - m sin(theta)^2),
with phi = t*pi and with m the elliptic parameter, not the modulus.
Run it with SageMath:
$ sage -pip install numberdb # once
$ sage -python generate.py # check the table against this code
$ sage -python generate.py --publish # fill the draft, with NUMBERDB_API_KEY set
The range follows numberdb-data#166: twelve amplitudes from pi/24 to pi/2,
and every reduced m = a/b in [0, 1) with b <= 12. The endpoint phi = pi/2
checks against the complete integral K(m), and the row m = 0 checks against
rational multiples of pi.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.complex_arb import ComplexBallField
from sage.rings.rational_field import QQ
TABLE = os.environ.get("NUMBERDB_TABLE") or "T349"
WORKING_GUARD = 64
AMPLITUDES = (
QQ(1) / QQ(24),
QQ(1) / QQ(12),
QQ(1) / QQ(8),
QQ(1) / QQ(6),
QQ(5) / QQ(24),
QQ(1) / QQ(4),
QQ(7) / QQ(24),
QQ(1) / QQ(3),
QQ(3) / QQ(8),
QQ(5) / QQ(12),
QQ(11) / QQ(24),
QQ(1) / QQ(2),
)
def _key_from_stdin():
if os.environ.get("NUMBERDB_KEY_FROM_STDIN") != "1":
return
token = sys.stdin.read().strip()
if "=" in token and token.split("=", 1)[0].isupper():
token = token.split("=", 1)[1].strip().strip("'\"")
if token:
os.environ["NUMBERDB_API_KEY"] = token
def _m_values(denominator=12):
for b in range(1, denominator + 1):
for a in range(0, denominator + 1):
m = QQ(a) / QQ(b)
if m >= 1 or m.denominator() != b:
continue
yield m
def _field(digits):
return ComplexBallField(numberdb.bits(digits, losing=WORKING_GUARD))
class IncompleteEllipticF(numberdb.Generator):
table = TABLE
parameters = ("phi", "m")
type = "R"
digits = 100
rigour = "proven"
def enumerate(self, denominator=12):
for phi in AMPLITUDES:
for m in _m_values(denominator):
yield {"phi": str(phi), "m": str(m)}
def value(self, params, digits):
field = _field(digits)
phi = field.pi() * field(QQ(params["phi"]))
m = field(QQ(params["m"]))
value = phi.elliptic_f(m)
if not (value.real().is_finite() and value.imag().is_finite()):
raise ArithmeticError(
"F(%s*pi, %s) produced a non-finite ball: %s"
% (params["phi"], params["m"], value))
if not value.imag().contains_zero():
raise ArithmeticError(
"F(%s*pi, %s) came back with a non-real imaginary part: %s"
% (params["phi"], params["m"], value.imag()))
return value.real()
if __name__ == "__main__":
_key_from_stdin()
generator = IncompleteEllipticF()
if os.environ.get("NUMBERDB_PUBLISH") == "1" or "--publish" in sys.argv:
print(generator.publish(
message="values of incomplete elliptic F in ball arithmetic"))
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)