checks.py

back to table · edit · history · where entries came from · files · download

6732 bytes, as of the version from 2026-11-09 09:52 (current). Recorded here, not run.

"""Independent numerical checks for numberdb.org/T685.

    sage -python checks.py

Uses mpmath quadrature of the published log-sine/Clausen integrals, independently
of the generator's Arb integration and polynomial-tail algorithm. Known exact
integrals and five published low-order formulas control the methods first.
The high-precision mpmath agreement is evidence, not the certification.
"""
import json
import sys
import time
from functools import lru_cache
from fractions import Fraction
from pathlib import Path
import numberdb.sage as numberdb
import mpmath as mp
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from sage.rings.complex_arb import ComplexBallField
from sage.env import SAGE_VERSION
from numberdb._write import to_text
import numberdb as package
from generate import moment, field_bits, four_term_polynomial, MultipleMahler

MANIFEST = 'agents/runs/20261109T080742Z-build-skills/manifest.json'
SKILL_SHA256 = '886390324dd1971e381a43cf3b46b822ab0bc67d62f31d8481e29ec79556746b'


def decimal_rational(text):
    q = Fraction(text)
    return QQ(q.numerator) / q.denominator


def written_interval(text, bits=600):
    # Every written decimal denotes +/- one unit of its last place.
    from decimal import Decimal
    q = decimal_rational(text)
    exponent = Decimal(text).as_tuple().exponent
    ulp = QQ(10)**exponent
    return q-ulp, q+ulp


def assert_written_contains(text, ball):
    lo, hi = written_interval(text)
    assert ball > lo and ball < hi, (text, ball)


def low_order_controls():
    R = RealBallField(600); C = ComplexBallField(600)
    pi=R.pi(); z=(C.pi()*C(0,1)/3).exp()
    cl2=z.polylog(2).imag(); cl4=z.polylog(4).imag()
    log2=R(2).log(); li4=C(QQ(1)/2).polylog(4).real()
    expected = {
        (3,1):cl2/pi, (3,2):pi**2/54,
        (3,3):9*cl4/(2*pi)-R(3).zeta(),
        (4,1):7*R(3).zeta()/(2*pi**2),
        (4,2):(8*li4+7*log2*R(3).zeta()+log2**4/3)/pi**2
              -log2**2/3-23*pi**2/360,
    }
    for key, value in expected.items():
        computed=moment(*key)
        assert value.is_finite() and value.accuracy()>500
        assert computed.overlaps(value), (key, computed, value)
    return expected


def independent_all(dps):
    with mp.workdps(dps):
        assert abs(mp.quad(lambda t:t*t,[0,1])-mp.mpf(1)/3) < mp.mpf(10)**(-dps+5)
        assert abs(mp.quad(lambda t:mp.log(2*mp.sin(t/2)),[mp.pi/3,mp.pi])
                   -mp.im(mp.polylog(2,mp.exp(mp.j*mp.pi/3)))) < mp.mpf(10)**(-dps+5)
        @lru_cache(maxsize=None)
        def g(t):
            if t==0: return mp.mpf(0)
            theta=mp.pi*t
            return (theta*mp.log(2*mp.sin(theta/2))
                    +mp.im(mp.polylog(2,mp.exp(mp.j*theta))))/mp.pi
        assert abs(g(mp.mpf(1))-mp.log(2)) < mp.mpf(10)**(-dps+5)
        # A second reduction of the conditional mean: integral of u*cot(u).
        for t in (mp.mpf(1)/4,mp.mpf(1)/2,mp.mpf(3)/4):
            cot_integral=mp.quad(lambda u: u*mp.cot(mp.pi*u/2) if u else 2/mp.pi,[0,t])*mp.pi/2
            assert abs(cot_integral-g(t)) < mp.mpf(10)**(-dps+5)
        out={}
        for n in (3,4):
            for k in range(1,13):
                if n==3:
                    v=mp.quad(lambda theta:mp.log(2*mp.sin(theta/2))**k,
                              [mp.pi/3,mp.pi/2,mp.pi])/mp.pi
                else:
                    v=mp.quad(lambda t:g(t)**k,[0,mp.mpf(1)/2,1])
                out[(n,k)]=mp.nstr(v,dps)
                print('independent',dps,n,k,mp.nstr(v,18),flush=True)
        return out


def main():
    started=time.time()
    C=ComplexBallField(445); R=RealBallField(445)
    control=C.integral(lambda t,a:t*t,0,1).real()
    assert control.is_finite() and control.overlaps(R(QQ(1)/3))
    assert control.accuracy()>400
    expected=low_order_controls()
    print('controls passed',flush=True)
    small=independent_all(75)
    large=independent_all(125)
    entries=[]
    for p in MultipleMahler().enumerate():
        key=(int(p['n']),int(p['k']))
        value=moment(*key); higher=moment(*key,digits=140)
        assert value.overlaps(higher)
        assert value.is_finite() and higher.is_finite()
        text=to_text(value,digits=100)
        assert_written_contains(text,higher)
        with mp.workdps(150):
            v=mp.mpf(large[key]); w=mp.mpf(small[key])
            low_agreement=abs(v-w)
            assert low_agreement < mp.mpf('1e-70')
            reference=decimal_rational(large[key])
            distance=abs(higher-RealBallField(field_bits(140))(reference))
            assert distance < QQ(1)/10**115, (key,distance)
        entries.append({'n':key[0],'k':key[1],'number':text,
                        'accuracy_bits':int(value.accuracy()),
                        'radius':str(value.rad()),
                        'higher_accuracy_bits':int(higher.accuracy()),
                        'independent_75d':small[key], 'independent_125d':large[key],
                        'independent_absolute_difference_upper':str(distance.upper())})
    # Moment properties of the nonnegative conditional means, over the full range.
    for n in (3,4):
        for k in range(1,13):
            assert moment(n,k)>0
            if k<12: assert moment(n,k+1)<R(2).log()*moment(n,k)
            if 1<k<12: assert moment(n,k)**2 < moment(n,k-1)*moment(n,k+1)
    h,error,N=four_term_polynomial(100)
    evidence={'table':'T685','skill_manifest':MANIFEST,
              'skill_versions':{'local':SKILL_SHA256,'live':SKILL_SHA256},
              'versions':{'sage':SAGE_VERSION,'mpmath':mp.__version__,
                          'numberdb':getattr(package,'__version__','see attached client metadata')},
              'working_bits':field_bits(100), 'series_N':N,'series_uniform_error_bound':str(error),
              'minimum_accuracy_bits':min(x['accuracy_bits'] for x in entries),
              'control_cases':['Arb and mpmath integral of t^2 = 1/3',
                               'Clausen log-sine integral at pi/3',
                               'conditional mean at t=1 = log(2)',
                               'conditional mean versus integrated cotangent at 1/4,1/2,3/4',
                               'BS equations (34),(35),(36),(43),(44) with (24) and (10)'],
              'independent_check':'All 24 entries by mpmath log-sine/Clausen quadrature at 75 and 125 decimal digits; discrepancy from 140-digit ball less than 1e-115.',
              'properties':'Positive, decreasing after multiplication bound log(2), strictly log-convex on every applicable triple.',
              'entries':entries,'elapsed_seconds':time.time()-started}
    print('EVIDENCE '+json.dumps(evidence,sort_keys=True),flush=True)

if __name__=='__main__': main()