back to table · edit · history · where entries came from · files · download
7425 bytes, as of the version from 2026-10-25 18:59 (current). Recorded here, not run.
"""Independent checks for Fourier Lebesgue constants -- numberdb.org/T499.
Run: sage -python checks.py
Needs generate.py, check.py and the three attached OEIS b-files beside it.
To repeat on downloaded website values: sage -python checks.py stored-table.json
The JSON file must be the response to GET /api/table?id=T499.
No key is needed for offline checks; this script makes no network requests.
An independent formula integrates the finite cosine expansion of the Dirichlet
kernel, with its sign fixed on each interval between consecutive zeros.
Writing u=t/pi, the normalized primitive is
A(u) = u + (2/pi)*sum(sin(pi*k*u)/k, k=1..n).
The endpoints are 0, 2/(2n+1), ..., 2n/(2n+1), 1, and the signs alternate,
starting positive. A(0)=0 and A(1)=1 exactly. This shares neither tangent
calls nor the generator's summation formula. All comparisons require finite
balls and radii less than 10^-110. A known-answer control checks L_0 and L_1
before the range is examined. OEIS comparisons use all 104/100/100 supplied
digits, interpreted as decimal truncations rather than rounded midpoints.
"""
import json
import pathlib
import sys
import time
from decimal import Decimal
from fractions import Fraction
from importlib.metadata import version, PackageNotFoundError
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from numberdb._write import to_text
from generate import lebesgue_fourier, LebesgueFourier, MAX_DEGREE
from check import exactness, measure, names_its_rings, agrees_with
R = RealBallField(640)
HERE = pathlib.Path(__file__).resolve().parent
def exact_decimal(text):
f = Fraction(Decimal(text))
return QQ(f.numerator)/f.denominator
def narrow(value):
value = R(value)
assert value.is_finite(), 'nonfinite ball'
assert value.rad_as_ball() < R(10)**(-110), 'comparison ball too wide'
return value
def agree(left, right):
left, right = narrow(left), narrow(right)
assert left.overlaps(right), (str(left), str(right))
def integral_by_primitive(n):
"""Integrate |D_n| using the primitive of its finite cosine expansion."""
pi = R.pi()
m = 2*n + 1
previous = R(0)
total = R(0)
for j in range(1, n+2):
if j == n+1:
primitive = R(1)
else:
u = R(2*j)/m
primitive = u + 2/pi*sum(((pi*k*u).sin()/k for k in range(1,n+1)), R(0))
total += (-1)**(j-1)*(primitive-previous)
previous = primitive
return narrow(total)
def written_contains(text, value):
"""The entire computed ball must fit the displayed one-ULP enclosure."""
if '.' not in text and 'e' not in text.lower():
assert value.is_exact() and value == R(QQ(text))
return
decimal = Decimal(text)
center = exact_decimal(text)
ulp = QQ(10)**decimal.as_tuple().exponent
assert abs(narrow(value)-R(center)) < R(ulp), text
def main(stored_path=None):
started = time.monotonic()
# These known answers test the checker before it can validate any data.
agree(integral_by_primitive(0), R(1))
agree(integral_by_primitive(1), R(1)/3 + 2*R(3).sqrt()/R.pi())
print('PASS controls: L_0=1 and L_1=1/3+2*sqrt(3)/pi', flush=True)
values = {n: lebesgue_fourier(n) for n in range(MAX_DEGREE+1)}
assert not exactness(values)
assert not names_its_rings(str(HERE/'generate.py'))
independent = {n: integral_by_primitive(n) for n in values}
for n, v in values.items():
agree(v, independent[n])
agree(v, lebesgue_fourier(n, extra_bits=160))
print('PASS all 101 values: signed-integral formula and 160 extra bits', flush=True)
# Source closed forms do not share the generator's tangent summation.
closed = {
0: R(1),
1: R(1)/3 + 2*R(3).sqrt()/R.pi(),
2: R(1)/5 + (25-2*R(5).sqrt()).sqrt()/R.pi(),
3: R(1)/7 + (22*(R.pi()/7).sin()-2*(R.pi()/14).cos()+10*(3*R.pi()/14).cos())/(3*R.pi())
}
for n,v in closed.items():
agree(values[n],v)
# The generic exact comparison helper is used on OEIS integer prefixes.
prefixes, expected = {}, {}
oeis_counts={}
for n, seq in [(1,'226654'),(2,'226655'),(3,'226656')]:
rows=[]
for line in (HERE/('b'+seq+'.txt')).read_text().splitlines():
if line.strip() and not line.startswith('#'):
idx,digit=map(int,line.split())
assert idx == len(rows)+1 and 0 <= digit <= 9
rows.append(str(digit))
digits=''.join(rows)
scale=ZZ(10)**(len(digits)-1)
lo=QQ(ZZ(digits))/scale
hi=lo+QQ(1)/scale
assert narrow(values[n])>R(lo) and narrow(values[n])<R(hi)
# floor is unambiguous because the ball lies strictly in this cell.
prefixes[n]=(R(values[n])*scale).floor()
expected[n]=ZZ(digits)
oeis_counts['A'+seq]=len(digits)
assert not agrees_with(prefixes, lambda n:expected[n])
print('PASS source closed forms and OEIS digits:',oeis_counts,flush=True)
for n in range(1,MAX_DEGREE+1):
assert R(values[n]) > R(values[n-1])
# Classical bounds in MathWorld (17), checked only for n>=1.
logarithmic = 4*R(n).log()/R.pi()**2
assert R(values[n])>logarithmic
assert R(values[n])<logarithmic+3
print('PASS strict increase and classical logarithmic bounds on 1..100',flush=True)
written = {n:to_text(v,100) for n,v in values.items()}
for n,text in written.items():
written_contains(text,independent[n])
if n:assert len(Decimal(text).as_tuple().digits)==100
stored_count=0
if stored_path:
doc=json.loads(pathlib.Path(stored_path).read_text())
raw=doc['Numbers']
assert isinstance(raw,dict), type(raw)
assert set(raw)==set(map(str,range(MAX_DEGREE+1)))
for key,entry in raw.items():
text=entry['number'] if isinstance(entry,dict) else str(entry)
n=int(key)
written_contains(text,independent[n])
if n in closed:written_contains(text,closed[n])
if n:assert len(Decimal(text).as_tuple().digits)==100
assert (raw['0']['number'] if isinstance(raw['0'],dict) else str(raw['0']))=='1'
stored_count=len(raw)
print('PASS all stored decimal enclosures contain independent integral balls',flush=True)
versions={'python':sys.version.split()[0]}
for package in ['numberdb','passagemath-standard','passagemath-flint','sage-conf']:
try:versions[package]=version(package)
except PackageNotFoundError:pass
report={
'tid':'T499','entries':len(values),'range':[0,MAX_DEGREE],
'working_bits':numberdb.bits(100,losing=96),
'minimum_relative_accuracy_bits':min(int(values[n].accuracy()) for n in values if n),
'maximum_ball_radius':str(max(values[n].rad() for n in values if n)),
'independent_bits':640,'extra_precision_bits':160,
'raw_measure':measure(values),'serialized_measure':measure(written),
'oeis_digits':oeis_counts,'stored_checked':stored_count,
'seconds':time.monotonic()-started,'versions':versions,
'sample_values':{str(n):written[n] for n in [0,1,2,3,10,100]}
}
print(json.dumps(report,indent=2),flush=True)
return report
if __name__=='__main__':
main(sys.argv[1] if len(sys.argv)>1 else None)