back to table · edit · history · where entries came from · files · download
4682 bytes, as of the version from 2026-10-25 10:54 (current). Recorded here, not run.
"""Growth constants of the classes of planar maps -- numberdb.org/T483.
Run with SageMath (or passagemath with numberdb):
sage -pip install numberdb
sage -python generate.py
sage -python checks.py
sage -python generate.py --fill
The default verifies every stored entry. --fill writes entries to the existing
T483 draft with NUMBERDB_API_KEY set; it does not make the table public.
A private draft also requires the owner's key for verification. The build
runner may instead supply the key on stdin with NUMBERDB_KEY_FROM_STDIN=1.
All maps are rooted at a directed edge on the oriented sphere and unlabelled.
The six general map classes are counted by edges, the three triangulation
classes by all vertices, and the two quadrangulation classes by all faces.
Constants follow the exact enumerations cited in the table. Rational results
are returned in QQ. The type-I triangulation constant is exactly 12*sqrt(3),
returned as a certified Arb enclosure. At 100 digits the 64-bit guard gives
more than 118 relative decimal digits; checks.py measures the actual bound.
No empirical extrapolation is used to produce the stored numbers.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField
GUARD_BITS = 64
CLASSES = (
('all', 'edges', 12, 1,
r"Loops and multiple edges are allowed. Tutte's count gives $\gamma=12$ CITE{NRR}."),
('2-connected', 'edges', 27, 4,
r'Nonseparable maps have no loops or cut vertices; multiple edges are allowed. The constant is exactly $27/4$ CITE{NRR}.'),
('3-connected', 'edges', 4, 1,
r'The underlying graph is simple and 3-vertex-connected. The constant is exactly $4$ CITE{NRR}.'),
('bipartite', 'edges', 8, 1,
r'The underlying graph is bipartite; no choice of a colouring is counted. The constant is exactly $8$ CITE{NRR}.'),
('eulerian', 'edges', 8, 1,
r'Every vertex has even degree, with each loop contributing $2$. Planar duality identifies these counts with bipartite-map counts CITE{LW}.'),
('loopless', 'edges', 256, 27,
r'Loops are forbidden and multiple edges are allowed. The constant is exactly $256/27$ CITE{LW}.'),
('triangulations-I', 'vertices', None, None,
r'Type I allows loops and multiple edges. The exact constant is $12\sqrt3$, stored as a certified real enclosure CITE{CLG}.'),
('triangulations-II', 'vertices', 27, 2,
r'Type II forbids loops and allows multiple edges. The constant is exactly $27/2$ CITE{AS}.'),
('triangulations-III', 'vertices', 256, 27,
r'Type III is simple, with neither loops nor multiple edges. The constant is exactly $256/27$ CITE{AS}.'),
('quadrangulations', 'faces', 12, 1,
r"Every face has degree $4$, with repeated boundary edges counted with multiplicity. Tutte's angular bijection gives the same count as all maps with $n$ edges CITE{CLG}."),
('simple-quadrangulations', 'faces', 27, 4,
r'The underlying graph is simple. The ternary-tree parametrisation of the counting series gives $\gamma=27/4$ CITE{AFP}.'),
)
class PlanarMapGrowth(numberdb.Generator):
table = 'T483'
parameters = ('class', 'size', 'labelling')
type = 'R'
digits = 100
rigour = 'proven'
files = ('generate.py', 'checks.py', 'check.py', 'source-notes.md')
def enumerate(self):
for key, size, *_ in CLASSES:
yield {'class': key, 'size': size, 'labelling': 'unlabelled'}
def value(self, params, digits):
for key, size, numerator, denominator, comment in CLASSES:
if params['class'] == key:
if params['size'] != size or params['labelling'] != 'unlabelled':
raise ValueError('This class is tabulated with a different size or labelling.')
if numerator is None:
field = RealBallField(numberdb.bits(digits, losing=GUARD_BITS))
value = 12 * field(3).sqrt()
else:
value = QQ(numerator) / QQ(denominator)
return {'number': value, 'comment': comment}
raise ValueError('Unknown map class')
if __name__ == '__main__':
if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
numberdb.configure(api_key=sys.stdin.read().strip())
generator = PlanarMapGrowth()
if '--fill' in sys.argv or os.environ.get('NUMBERDB_PUBLISH') == '1':
print(generator.publish(message='Fill eleven planar-map growth constants with exact rational values and a certified radical'))
else:
report = generator.verify(sample=None)
print(report)
raise SystemExit(0 if report.ok else 1)