back to table · edit · history · where entries came from · files · download
4106 bytes, as of the version from 2026-10-30 06:50 (current). Recorded here, not run.
"""Moment of inertia I/(MR^2) of polytropic stars -- numberdb.org/T616.
Run with SageMath (install numberdb once with sage -pip install numberdb):
sage -python generate.py # verify all stored entries
sage -python generate.py --fill # send entries to the existing draft
Download the attachments listed in `files` beside this script first.
Set NUMBERDB_API_KEY for authenticated draft reads/writes. Campaign scripts
may pass the token on stdin with NUMBERDB_KEY_FROM_STDIN=1. Entry writing
never offers, reviews or publishes the table.
The sole parameter n selects the same finite background models as T613-T615.
See argument-selection.md for the disjoint intrinsic, application and bounded
reference groups. The solver implements half-integer n in [0,5), not arbitrary
rational indices. The n=0 value is exactly 2/5; n=1 uses an Arb evaluation of
2/3-4/pi^2. Other rows integrate J=integral xi^4 theta^n dxi alongside xi and
q in t=sqrt(theta), then return 2J/(3q*xi^2). The accumulated integral
H=integral xi^2 theta dxi checks J=q*xi^2-6H at every selected surface.
The two numerical runs use 150/210 decimal working digits, Taylor orders
160/210, step divisors 12/18 and central matching radii 1/2 and 2/3. The
worst relative discrepancy over all ten models is below 3.25e-154, leaving
ample margin for the 100 stored significant digits. These are heuristic
agreement checks: truncation and global ODE errors have no certified bound.
The separate radial formulation and literature approximant are validation,
not the controller's independent critique. See numerical-evidence.json and
independent-evidence.json for actual measurements and controls.
"""
import os
import sys
from functools import lru_cache
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
from solver import inertia
INDICES=('0','1/2','1','3/2','2','5/2','3','7/2','4','9/2')
CONFIG={150:(160,12,'1/2'),210:(210,18,'2/3')}
@lru_cache(maxsize=32)
def compute(n,working):
return str(inertia(n,working,*CONFIG[working]))
class PolytropicInertia(numberdb.Generator):
table='T616'
parameters=('n',)
type='R'
digits=100
rigour='heuristic (agreement-checked)'
files=('generate.py','solver.py','argument-selection.md','compute.py',
'numerical-evidence.json','independent_checks.py','independent-evidence.json',
'readback_checks.py','skill-evidence.json','source-manifest.json',
'check.py','dry_run.py','validate.py')
def enumerate(self):
for n in INDICES:
yield {'n':n}
def value(self,params,digits):
n=str(QQ(params['n']))
if n not in INDICES:
raise ValueError('Use one of the selected finite polytropic indices.')
if digits>100:
raise ValueError('The current precision policy was checked for 100 digits.')
if n=='0':
return {'number':QQ(2)/5,'comment':r'The incompressible model has constant interior density, so $I/(MR^2)=2/5$.'}
if n=='1':
B=RealBallField(numberdb.bits(digits,losing=80))
return {'number':B(2)/3-4/B.pi()**2,'comment':r'The linear profile $\theta_1(\xi)=\sin(\xi)/\xi$ gives $I/(MR^2)=2/3-4/\pi^2$.'}
return numberdb.agreeing(lambda working:compute(n,working),at=(150,210))
if __name__=='__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN')=='1':
token=sys.stdin.read().strip()
if '=' in token and token.split('=',1)[0].replace('_','').isalnum():
token=token.split('=',1)[1].strip().strip('\"\'')
os.environ['NUMBERDB_API_KEY']=token
generator=PolytropicInertia()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH')=='1':
for params in generator.enumerate():
generator.value(params,generator.digits)
print(generator.publish(message='Add ten axial inertia constants with numerical checks and reproducible sources.'))
else:
report=generator.verify(sample=None)
print(report)
sys.exit(0 if report.ok else 1)