back to table · edit · history · where entries came from · files · download
3993 bytes, as of the version from 2026-10-26 12:36. Recorded here, not run.
"""Values of the Scorer function Hi -- numberdb.org/T515.
Run with SageMath (or passagemath with real and complex Arb support):
sage -pip install numberdb
sage -python generate.py # verify every stored entry
sage -python checks.py # independent numerical checks
sage -python generate.py --fill # fill the draft using NUMBERDB_API_KEY
The --fill operation sends entries and source attachments; it does not make
this draft public. On the campaign builder, NUMBERDB_KEY_FROM_STDIN=1 reads
the key from stdin and NUMBERDB_PUBLISH=1 selects the same fill operation.
The standard Hi of DLMF 9.12.20 is used, without scaling or subtraction.
Only the nine reference arguments agreed in the family are enumerated.
The parameters describe all rational arguments, not just this selection.
For y=sum(c_k*x^k), y''-x*y=1/pi gives c_2=1/(2*pi) and
c_(k+3)=c_k/((k+3)*(k+2)). The initial c_0 and c_1 are DLMF 9.12.6-7.
All arithmetic, gamma evaluations, and positive real powers use Arb balls.
Each residue class modulo 3 is summed separately. After index k, the ratio
of absolute terms is at most q=abs(x)^3/((k+3)*(k+2)); subsequent ratios
are smaller. Once q<1, the entire omitted tail is bounded by
abs(term)*q/(1-q), which is explicitly added to the ball radius.
The working precision is digits+100 decimal digits, rounded up to bits;
each of the three tails is below 10^(-digits-50). At 100 requested digits
this is 665 bits. checks.py measures the final relative accuracy, tests
certified independent integration, and compares mpmath at 150 and 200 dps.
No claim of rigorous accuracy relies on mpmath.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
ARGUMENTS = ('0', '1/2', '-1/2', '1', '-1', '2', '-2', '10', '-10')
WORKING_GUARD_DIGITS = 100
TAIL_GUARD_DIGITS = 50
def scorer_hi(x, digits=100):
"""Enclose Hi(x) from its entire Taylor series at exact rational x."""
field = RealBallField(numberdb.bits(digits + WORKING_GUARD_DIGITS, losing=0))
x = field(QQ(x))
pi = field.pi()
coefficients = (
2 / (field(3)**(QQ(7)/6) * field(QQ(2)/3).gamma()),
2 / (field(3)**(QQ(5)/6) * field(QQ(1)/3).gamma()),
1 / (2*pi),
)
cutoff = field(10)**(-digits-TAIL_GUARD_DIGITS)
total = field(0)
for residue, coefficient in enumerate(coefficients):
k = residue
term = coefficient * x**k
subtotal = term
while True:
denominator = (k+3)*(k+2)
q = abs(x)**3 / denominator
if q < 1:
tail = abs(term)*q/(1-q)
if tail < cutoff:
subtotal = subtotal.add_error(tail)
break
term = term*x**3 / denominator
subtotal += term
k += 3
if k > 100000:
raise ArithmeticError('Taylor tail did not contract')
total += subtotal
assert total.is_finite()
assert total > 0
assert total.accuracy() >= numberdb.bits(digits, losing=20)
return total
class ScorerHi(numberdb.Generator):
table = 'T515'
parameters = ('x',)
type = 'R'
digits = 100
rigour = 'proven'
files = ('generate.py', 'checks.py', 'check.py', 'dry_run.py', 'evidence.json')
def enumerate(self):
for x in ARGUMENTS:
yield {'x': x}
def value(self, params, digits):
return scorer_hi(params['x'], digits)
if __name__ == '__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
numberdb.configure(api_key=sys.stdin.read().strip())
generator = ScorerHi()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
print(generator.publish(message='Fill nine Scorer Hi values with certified Taylor enclosures'))
else:
report = generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)