back to table · edit · history · where entries came from · files · download
4079 bytes, as of the version from 2026-11-10 20:59 (current). Recorded here, not run.
"""Vasyunin V_N squared errors -- numberdb.org/T708.
sage -pip install numberdb
sage -python generate.py # verify; no write
sage -python generate.py --publish # fill authorized target; never offer
For private drafts configure NUMBERDB_API_KEY.
N is a positive integer; the default selection is every N=1,...,30.
V_N=sum mu(n) rho_n - g_N rho_1, g_N=sum mu(n)/n, rho_n(x)={1/(nx)}.
The output is ||chi+V_N||^2 in L^2((0,infinity),dx), chi=1_(0,1).
Finite cotangent sums (BBLS math/0306251v1 Proposition 89) and Arb balls
at numberdb.bits(digits, losing=128) enclose all transcendental operations.
N=1 gives V_1=0 and exact squared error 1; no decimal-pattern inference.
The gram_system component is reused from T706/T641, original T641 SHA-256
7e155af1d4a4963f874e0c536051c1cf0b7afd01e21b93d64a674c7fab8592c8.
Its formula is checked against the primary source and a separate period integral.
See derivation.md, checks.py and numerical-evidence.json for error bounds,
measured accuracy and executable controls. No sibling decimals are inputs.
"""
import os
import sys
from functools import lru_cache
from math import gcd
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.integer_ring import ZZ
from sage.rings.real_arb import RealBallField
from sage.arith.misc import moebius
MAX_N=30
WORKING_GUARD=128
def gram_system(limit, precision):
"""Fresh finite cotangent sums, Gram entries, and target inner products."""
R = RealBallField(precision)
C = (2*R.pi()).log() - R.euler_constant()
@lru_cache(None)
def vasyunin(p, q):
return sum((R(QQ((m*p) % q)/QQ(q)) *
(R.pi()*R(QQ(m)/QQ(q))).cot()
for m in range(1, q)), R(0))
@lru_cache(None)
def autocorrelation(p, q):
x = R(QQ(p)/QQ(q))
return (((1-x)*x.log() + (1+x)*C)/2
- R.pi()*(vasyunin(p,q)+vasyunin(q,p))/(2*q))
G = [[R(0) for k in range(limit)] for j in range(limit)]
for j in range(1, limit+1):
for k in range(1, j+1):
g = gcd(j,k)
G[j-1][k-1] = G[k-1][j-1] = autocorrelation(j//g,k//g)/j
b = [(R(n).log()+1-R.euler_constant())/n for n in range(1,limit+1)]
return R, G, b
def coefficients(N):
weights=[QQ(moebius(n)) for n in range(1,N+1)]
g=sum((weights[n-1]/QQ(n) for n in range(1,N+1)),QQ(0))
weights[0]-=g
assert sum((weights[n-1]/QQ(n) for n in range(1,N+1)),QQ(0))==0
return weights
@lru_cache(None)
def computation(limit, digits):
R,G,b=gram_system(limit,numberdb.bits(digits,losing=WORKING_GUARD))
values=[ZZ(1)]
for N in range(2,limit+1):
w=coefficients(N)
v=R(1)+2*sum((w[i]*b[i] for i in range(N)),R(0))
v+=sum((w[i]*w[j]*G[i][j] for i in range(N) for j in range(N)),R(0))
assert v.is_finite() and v>0
assert v.accuracy()>=numberdb.bits(digits)+16
values.append(v)
return R,G,b,values
class VasyuninErrors(numberdb.Generator):
table='T708'
parameters=('N',)
type='R'
digits=100
rigour='proven'
files=('generate.py','checks.py','integral_kernel.py','argument-selection.md',
'derivation.md','numerical-evidence.json','skill-manifest.json','research.md',
'verify_stored.py')
def enumerate(self,limit=MAX_N):
for N in range(1,limit+1):yield {'N':str(N)}
def value(self,params,digits):
N=int(params['N'])
if N<1:raise ValueError('N must be a positive integer')
if N==1:return ZZ(1)
return computation(max(MAX_N,N),digits)[3][N-1]
if __name__=='__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
numberdb.configure(api_key=sys.stdin.read().strip())
generator=VasyuninErrors()
if '--publish' in sys.argv or os.environ.get('NUMBERDB_PUBLISH')=='1':
print(generator.publish(message=os.environ.get('NUMBERDB_EDIT_MESSAGE','Recompute Vasyunin errors for N=1,...,30')))
else:
report=generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)