back to table · edit · history · where entries came from · files · download
4819 bytes, as of the version from 2026-10-27 08:39 (current). Recorded here, not run.
"""Parity-twisted spectral zeta values of homogeneous oscillators -- numberdb.org/T542.
Run with SageMath:
sage -pip install numberdb mpmath
sage -python generate.py # verify all entries
sage -python generate.py --fill # fill this draft, NUMBERDB_API_KEY set
Download accelerate.py alongside this file. To fill with every evidence
attachment, also download the files declared by ParitySpectralZeta.files.
The --fill operation writes entries; it does not publish or offer the draft.
H_N=-d^2/dx^2+|x|^N on the full line, with zero shift and the even ground
state indexed by zero. Store the Neumann minus Dirichlet trace, not its
absolute value or the full trace. For N>=3 use Watkins (2012), (2.5a,b),
with sigma=2/(N+2) and radial lambda=-1/2 and +1/2 respectively. The radial
lambda is not an energy shift. Equation (2.5a) includes the factor 1/4;
the inconsistent introductory (1.3) does not. Independent checks settle it.
The generic Gamma-ratio tail helper is reused from T541's attached
accelerate.py, read from the website database in this run. It is justified
by DLMF 5.11.8 but does not certify the asymptotic remainder. We vary precision,
cutoff and correction count together: (150 digits,160,140), (200,320,180).
The retained 100 digits therefore have heuristic (agreement-checked) rigour.
Independent checks use Voros's full-trace formula and the Wronskian relation,
a separate mpmath hypergeometric evaluation, Airy log derivatives, the harmonic
spectrum and the sextic closed form. See numerical-evidence.md for measurements.
"""
import os
import sys
from functools import lru_cache
import numberdb.sage as numberdb
import mpmath as mp
from accelerate import hyper_tail
SETTINGS = {150: (160, 140), 200: (320, 180)}
@lru_cache(None)
def boundary(N, n, sign, working):
"""sign=+1: Dirichlet; sign=-1: Neumann."""
with mp.workdps(working):
sigma = mp.mpf(2) / (N + 2)
lam = mp.mpf(sign) / 2
half = mp.mpf(1) / 2
if n == 1:
result = sigma**(2-2*sigma) * mp.gamma(sigma*(1+lam))
result *= mp.gamma(sigma) * mp.gamma(half-sigma)
result /= 4*mp.sqrt(mp.pi)*mp.gamma(1-sigma*(1-lam))
elif n == 2:
A = [half+sigma*lam, 2*sigma*(1+lam), sigma*(2+lam),
2*sigma, sigma*(1+lam)]
B = [1+sigma*lam, 1+2*sigma*lam, half+sigma*(2+lam),
1+sigma*(1+lam)]
pref = mp.sqrt(mp.pi)*sigma**(3-4*sigma)
pref /= mp.mpf(4)**(1+sigma*lam)*(1+lam)
pref *= mp.gamma(2*sigma*(1+lam))*mp.gamma(sigma*(2+lam))*mp.gamma(2*sigma)
pref /= mp.gamma(1+sigma*lam)**2*mp.gamma(half+sigma*(2+lam))
result = pref*hyper_tail(A, B, *SETTINGS[working])
else:
raise ValueError('Only inverse orders one and two are implemented.')
return mp.nstr(result, working)
@lru_cache(None)
def compute(N, n, working):
with mp.workdps(working):
if N == 1:
assert n == 2
kappa = mp.root(3, 3)*mp.gamma(mp.mpf(2)/3)/mp.gamma(mp.mpf(1)/3)
result = 1/kappa-kappa**2
elif N == 2:
assert n == 2
result = mp.catalan
else:
result = mp.mpf(boundary(N,n,-1,working))-mp.mpf(boundary(N,n,1,working))
return mp.nstr(result, working)
class ParitySpectralZeta(numberdb.Generator):
table = 'T542'
parameters = ('N', 'n')
type = 'R'
digits = 100
rigour = 'heuristic (agreement-checked)'
files = ('generate.py', 'accelerate.py', 'checks.py', 'check.py',
'argument-selection.md', 'numerical-evidence.md', 'values.json',
'numerical-checks.json', 'skill-manifest.json')
def enumerate(self):
for N in range(1, 13):
for n in ((2,) if N < 3 else (1, 2)):
yield {'N': N, 'n': n}
def value(self, params, digits):
N, n = int(params['N']), int(params['n'])
if N < 1 or n not in (1,2) or (n == 1 and N < 3):
raise ValueError('Only the absolutely convergent first two moments are implemented.')
return numberdb.agreeing(lambda working: compute(N,n,working), at=(150,200))
if __name__ == '__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
key = sys.stdin.read().strip()
if key.startswith('NUMBERDB_') and '=' in key:
key = key.split('=', 1)[1].strip().strip(chr(34)+chr(39))
os.environ['NUMBERDB_API_KEY'] = key
gen = ParitySpectralZeta()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
print(gen.publish(message='Fill 22 parity-twisted oscillator traces with independent checks'))
else:
report = gen.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)