generate.py

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

4143 bytes, as of the version from 2026-10-24 21:16 (current). Recorded here, not run.

"""Mean distance between two uniform random points of a region -- numberdb.org/T467.

Run with SageMath (or passagemath-symbolics) and the numberdb package:
    sage -pip install numberdb
    sage -python generate.py             # verify every stored entry
    sage -python generate.py --fill      # write entries to the existing draft

Writing requires NUMBERDB_API_KEY. NUMBERDB_KEY_FROM_STDIN=1 reads it from
stdin instead. --fill fills entries and never publishes a draft for public
viewing. For the campaign wrapper, NUMBERDB_PUBLISH=1 is equivalent to --fill.

The nine standard regions and their measures are specified in table.json.
All nonrational closed forms are evaluated by Arb with 80 guard bits.
The interval, solid ball and sphere means are returned as exact rationals.
Independent density/covariogram quadratures are in checks.py, which reports
empirical agreement separately from the rigor of the closed-form enclosures.
Sources: Aharonyan (2012), DOI 10.46991/PYSUA.2012.46.3.003;
Bailey, Borwein, Crandall (2007), DOI 10.1016/j.cam.2006.06.010;
Tu, Fischbach (2002), arXiv math-ph/0201046.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField

WORKING_GUARD = 80
REGIONS = (
    'unit-interval', 'unit-square', 'rectangle-1x2',
    'equilateral-triangle', 'unit-disk', 'unit-cube',
    'unit-ball-3', 'unit-circle', 'unit-sphere-2',
)
COMMENTS = {
    'unit-interval': r'The exact mean is $1/3$ CITE{Box}.',
    'unit-square': r'The exact mean is $(2+\sqrt2+5\log(1+\sqrt2))/15$ CITE{Box}.',
    'rectangle-1x2': r'The exact mean is $(33-5\sqrt5)/60+(11/12)\log((1+\sqrt5)/2)$, the $a=1$, $b=2$ case of CITE{Planar}, equation (1.4).',
    'equilateral-triangle': r'The exact mean is $1/5+(3/20)\log3$ CITE{Planar}.',
    'unit-disk': r'The exact mean is $128/(45\pi)$ CITE{Planar}.',
    'unit-cube': r'This is the Robbins constant: $[4+17\sqrt2-6\sqrt3+21\log(1+\sqrt2)+42\log(2+\sqrt3)-7\pi]/105$ CITE{Box}.',
    'unit-ball-3': r'The exact mean is $36/35$, obtained from the solid-ball distance density in CITE{Spherical}, equation (15).',
    'unit-circle': r'The exact mean chord length is $4/\pi$.',
    'unit-sphere-2': r'The exact mean chord length is $4/3$.',
}


def closed_form(region, digits):
    exact = {'unit-interval': QQ(1)/3, 'unit-ball-3': QQ(36)/35,
             'unit-sphere-2': QQ(4)/3}
    if region in exact:
        return exact[region]
    R = RealBallField(numberdb.bits(digits, losing=WORKING_GUARD))
    if region == 'unit-square':
        s = R(2).sqrt()
        return (2+s+5*(1+s).log())/15
    if region == 'rectangle-1x2':
        s = R(5).sqrt()
        return (33-5*s)/60+R(11)/12*((1+s)/2).log()
    if region == 'equilateral-triangle':
        return R(1)/5+R(3)/20*R(3).log()
    if region == 'unit-disk':
        return R(128)/(45*R.pi())
    if region == 'unit-cube':
        s, t = R(2).sqrt(), R(3).sqrt()
        return (4+17*s-6*t+21*(1+s).log()+42*(2+t).log()-7*R.pi())/105
    if region == 'unit-circle':
        return 4/R.pi()
    raise ValueError('Unknown region: '+region)


class MeanDistance(numberdb.Generator):
    table = 'T467'
    parameters = ('region',)
    type = 'R'
    digits = 100
    rigour = 'proven'
    files = ('generate.py', 'checks.py', 'table.json', 'check.py', 'validation.txt')

    def enumerate(self):
        for region in REGIONS:
            yield {'region': region}

    def value(self, params, digits):
        region = params['region']
        return {'number': closed_form(region, digits),
                'comment': COMMENTS[region]}


if __name__ == '__main__':
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN'):
        numberdb.configure(api_key=sys.stdin.read().strip())
    g = MeanDistance()
    if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
        print(g.publish(message='Fill nine independently checked mean distances',
                        assisted_by=os.environ.get('NUMBERDB_ASSISTED_BY', '')))
    else:
        report = g.verify(sample=None)
        print(report)
        sys.exit(0 if report.ok else 1)