back to table · edit · history · where entries came from · files · download
8839 bytes, as of the version from 2026-10-25 05:01 (current). Recorded here, not run.
"""Independent arithmetic and literature checks for numberdb.org/T472.
sage -python checks.py # all generated values
sage -python checks.py --stored # all values read from the database
An unpublished draft requires NUMBERDB_API_KEY, or NUMBERDB_KEY_FROM_STDIN=1
and the key on stdin. No request here modifies the database. A successful
check is consistency of published estimates, not a new physical measurement.
"""
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_mpfi import RealIntervalField
from fractions import Fraction
from itertools import product
import json
import os
import sys
from generate import CriticalExponents3D, INPUTS, CLASSES, EXPONENTS
from check import exactness, measure, agrees_with, names_its_rings
def q(s):
f = Fraction(str(s))
return QQ(f.numerator)/QQ(f.denominator)
def ends(text):
c,r = [q(a.strip()) for a in text.split('+/-')]
assert r > 0
return c-r,c+r
def interval(text):
return RealIntervalField(384)(list(ends(text)))
def exponents(yt,yh):
# Independent RG eigenvalue parameterisation, rather than the generator's
# formulas in nu, eta or nu, gamma.
return dict(alpha=2-3/yt,beta=(3-yh)/yt,gamma=(2*yh-3)/yt,
delta=yh/(3-yh),nu=1/yt,eta=5-2*yh)
def overlap(a,b):
return not (a[1] < b[0] or b[1] < a[0])
def scaling(row,dimension=3):
a,b,g,d,n,e=[row[k] for k in ('alpha','beta','gamma','delta','nu','eta')]
return {'Rushbrooke':a+2*b+g-2,'Widom':g-b*(d-1),
'Fisher':g-n*(2-e),'Josephson':dimension*n+a-2,
'critical-isotherm':(dimension-2+e)*d-(dimension+2-e)}
# Other determinations, not the inputs used to construct the table.
INDEPENDENT = {
'ising': {'nu':'0.63002 +/- 0.00010','eta':'0.03627 +/- 0.00010','omega':'0.832 +/- 0.006'},
'xy': {'alpha':'-0.0151 +/- 0.0003','beta':'0.3486 +/- 0.0001',
'gamma':'1.3178 +/- 0.0002','delta':'4.780 +/- 0.001',
'nu':'0.6717 +/- 0.0001','eta':'0.0381 +/- 0.0002','omega':'0.785 +/- 0.020'},
'heisenberg': {'alpha':'-0.1336 +/- 0.0015','beta':'0.3689 +/- 0.0003',
'gamma':'1.3960 +/- 0.0009','delta':'4.783 +/- 0.003',
'nu':'0.7112 +/- 0.0005','eta':'0.0375 +/- 0.0005'},
'saw': {'nu':'0.587597 +/- 0.000007','gamma':'1.1566 +/- 0.0010',
'eta':'0.0310 +/- 0.0007'},
}
def records(stored=False):
if stored:
doc=numberdb.table('T472')
rows=doc['Numbers']
if isinstance(rows,dict):
assert list(doc['Parameters'])==['class','exponent']
return {(cls,exponent):{'number':entry['number'],
'comment':entry.get('comment','')}
for cls,group in rows.items() for exponent,entry in group.items()}
assert isinstance(rows,list), 'Unexpected database entry shape'
return {(r['params']['class'],r['params']['exponent']):
{'number':r['number'],'comment':r.get('comment','')} for r in rows}
g=CriticalExponents3D()
return {(p['class'],p['exponent']):g.value(p,g.digits) for p in g.enumerate()}
def run(stored=False):
# Known positive and negative controls run before the empirical comparisons.
control={k:QQ(v) for k,v in dict(alpha=0,beta='1/8',gamma='7/4',
delta=15,nu=1,eta='1/4').items()}
assert all(x==0 for x in scaling(control,2).values())
assert interval('2.00 +/- 0.01').lower() < 2 < interval('2.00 +/- 0.01').upper()
assert not overlap(ends('2.00 +/- 0.01'),ends('3.00 +/- 0.01'))
bad=dict(control);bad['gamma']=QQ(2)
assert scaling(bad,2)['Rushbrooke'] != 0
result={'mode':'stored' if stored else 'generated','controls':'passed'}
values=records(stored)
assert set(values)==set(product(CLASSES,EXPONENTS))
assert not exactness(values)
assert not names_its_rings(os.path.join(os.path.dirname(__file__),'generate.py'))
result['measurement']=measure(values)
result['rows']={','.join(k):v['number'] for k,v in values.items()}
result['scaling_residuals']={}; result['independent_comparisons']=[]; result['legacy_discrepancies']=[]
result['corner_checks']=0
for cls in CLASSES:
row={k:interval(values[cls,k]['number']) for k in EXPONENTS}
for k,b in row.items():
assert not any(x.is_NaN() or x.is_infinity() for x in (b.lower(),b.upper()))
assert b.absolute_diameter()>0 and b.absolute_diameter()<q('0.3')
# Joint consistency: the exact input midpoint maps into every one of
# the six stored components simultaneously, not just separate residuals.
n0,n1=ends(INPUTS[cls]['nu']); assert n0>0
second='gamma' if cls=='saw' else 'eta'
s0,s1=ends(INPUTS[cls][second])
if cls=='saw':
assert 3*n0-s1>0 and s0>0 # monotonic derivatives have fixed signs
else:
assert 1+s0>0 and 2-s1>0
for n,s in product((n0,n1,(n0+n1)/2),(s0,s1,(s0+s1)/2)):
yt=1/n
yh=(3+s/n)/2 if cls=='saw' else (5-s)/2
expected=exponents(yt,yh)
for k,v in expected.items():
low,high=ends(values[cls,k]['number'])
assert low<=v<=high,(cls,k,str(v),values[cls,k])
result['corner_checks']+=1
residues=scaling(row)
assert all(b.contains_zero() for b in residues.values()),(cls,residues)
result['scaling_residuals'][cls]={k:str(v) for k,v in residues.items()}
for key,other in INDEPENDENT.get(cls,{}).items():
if cls=='heisenberg' and key=='beta':
assert not overlap(ends(values[cls,key]['number']),ends(other))
result['legacy_discrepancies'].append({'entry':'heisenberg,beta',
'selected':values[cls,key]['number'],'legacy_Campostrini2002':other,
'reason':'Different numerical determinations; the published one-error ranges do not overlap. No source error bar has been widened.'})
continue
assert overlap(ends(values[cls,key]['number']),ends(other)),(cls,key,other)
result['independent_comparisons'].append(cls+','+key)
# The published XY and Heisenberg comparison sets must themselves obey
# all five relations before being used as checks.
for cls in ('xy','heisenberg'):
assert all(x.contains_zero() for x in scaling({k:interval(v) for k,v in INDEPENDENT[cls].items()}).values())
# Independent Heisenberg conformal bootstrap, Chester et al. (2021), Table 1.
phi=interval('0.518936 +/- 0.000067')
singlet=interval('1.59488 +/- 0.00081')
for k,v in exponents(3-singlet,3-phi).items():
assert v.overlaps(interval(values['heisenberg',k]['number'])),k
result['independent_comparisons'].append('heisenberg,bootstrap,'+k)
# Independent percolation FSS eigenvalues: Xu et al. (2014), Sec. III A.
n=interval(values['percolation','nu']['number']); eta=interval(values['percolation','eta']['number'])
assert (1/n).overlaps(interval('1.1413 +/- 0.0015'))
assert ((5-eta)/2).overlaps(interval('2.52293 +/- 0.00010'))
result['independent_comparisons']+=['percolation,yt','percolation,yh']
# SAW correction against an earlier independent Monte Carlo simulation.
d=interval(values['saw','nu']['number'])*interval(values['saw','omega']['number'])
assert d.overlaps(interval('0.528 +/- 0.012'))
result['independent_comparisons'].append('saw,Delta1')
# Ising cross-table relations checked against the source scaling dimensions,
# since the family's CFT companion tables are not published in the corpus.
sig=interval('0.518148806 +/- 0.000000024'); eps=interval('1.41262528 +/- 0.00000029')
prime=interval('3.82951 +/- 0.00061')
expected={'nu':1/(3-eps),'eta':2*sig-1,'omega':prime-3,
'alpha':2-3/(3-eps),'beta':sig/(3-eps),
'gamma':(3-2*sig)/(3-eps),'delta':(3-sig)/sig}
for k,v in expected.items():
assert v.overlaps(interval(values['ising',k]['number'])),k
result['ising_cft_relations']=7
result['scaling_relations']=25
result['independent_comparison_count']=len(result['independent_comparisons'])
result['limitations']=['No Monte Carlo simulation or conformal bootstrap optimisation was rerun.',
'Heisenberg and percolation omega were checked against their primary-source text, not independently recomputed.',
'Physical uncertainty boxes are conditional estimates, not rigorous enclosures or joint confidence regions.']
result['passed']=True
return result
if __name__=='__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
os.environ['NUMBERDB_API_KEY']=sys.stdin.read().strip()
print(json.dumps(run('--stored' in sys.argv or os.environ.get('NUMBERDB_STORED')=='1'),indent=2))