generate.py

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

4713 bytes, as of the version from 2026-10-30 12:33 (current). Recorded here, not run.

"""Volumes of real and complex Stiefel manifolds -- numberdb.org/T624.

Run with SageMath (or a suitable passagemath installation):
    sage -pip install numberdb
    sage -python generate.py              # verify every stored entry
    sage -python check_values.py          # independent local checks
    sage -python check_values.py --stored # repeat checks on the database
    sage -python generate.py --fill       # fill this draft, with an API key

--fill only sends entries and attachments; it does not publish or offer a draft.
Private-draft reads also require NUMBERDB_API_KEY. For a key piped on stdin,
set NUMBERDB_KEY_FROM_STDIN=1. No credential is stored in this file.

The ambient Frobenius metric is fixed. Sphere factors are reduced by the exact
recurrence S_d = 2*pi*S_(d-2)/(d-1), starting at S_0=2 and S_1=2*pi.
The metric correction is 2^(k*(k-1)/4) over R and 2^(k*(k-1)/2) over C.
Only a rational coefficient, an optional sqrt(2), and integer powers of pi
remain for ball evaluation. The guard is 64 bits beyond numberdb.bits(digits);
check_values.py measures retained precision and serialized containment for all
272 default entries. See argument-selection.md and mathematical-notes.md.
"""
import os
import sys
import numberdb.sage as numberdb
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField

WORKING_GUARD = 64
MAX_N = 16


def exact_form(field, n, k):
    """Return (rational coefficient, pi exponent, sqrt(2) exponent 0 or 1)."""
    n, k = ZZ(n), ZZ(k)
    if field not in ('real', 'complex') or n < 1 or not 1 <= k <= n:
        raise ValueError('need field real or complex and integers 1 <= k <= n')
    coefficient, pi_power = QQ(1), 0
    for j in range(k):
        dimension = n-j-1 if field == 'real' else 2*(n-j)-1
        c, p = QQ(2), int(dimension % 2)
        for d in range(int(dimension), 1, -2):
            c *= QQ(2)/QQ(d-1)
            p += 1
        coefficient *= c
        pi_power += p
    # Write the correction as a power of sqrt(2), and extract its even part.
    sqrt_power = k*(k-1)//2 if field == 'real' else k*(k-1)
    coefficient *= ZZ(2)**(sqrt_power//2)
    return coefficient, pi_power, int(sqrt_power % 2)


def stiefel_volume(field, n, k, digits=100):
    coefficient, pi_power, sqrt_power = exact_form(field, n, k)
    if pi_power == 0 and sqrt_power == 0:
        return coefficient
    R = RealBallField(numberdb.bits(digits, losing=WORKING_GUARD))
    result = R(coefficient)*R.pi()**pi_power
    if sqrt_power:
        result *= R(2).sqrt()
    return result


class StiefelVolumes(numberdb.Generator):
    table = 'T624'
    parameters = ('field', 'n', 'k')
    type = 'R'
    digits = 100
    rigour = 'proven'
    files = ('generate.py', 'check_values.py', 'check.py',
             'argument-selection.md', 'mathematical-notes.md',
             'skill-evidence.json', 'numerical-evidence.json')

    def enumerate(self, max_n=MAX_N):
        for field in ('real', 'complex'):
            for n in range(1, max_n+1):
                for k in range(1, n+1):
                    yield {'field': field, 'n': n, 'k': k}

    def value(self, params, digits):
        field, n, k = params['field'], int(params['n']), int(params['k'])
        number = stiefel_volume(field, n, k, digits)
        if (field, n, k) == ('real', 1, 1):
            return {'number': number, 'comment': r'The two points of $O(1)=\{-1,1\}$ have total zero-dimensional volume $2$.'}
        if (field, n, k) == ('real', 2, 2):
            return {'number': number, 'comment': r'Each component of $O(2)$ is a circle of Frobenius radius $\sqrt2$, so the total length is $4\sqrt2\pi$.'}
        if (field, n, k) == ('real', 3, 3):
            return {'number': number, 'comment': r'The full orthogonal group $O(3)$ has volume $32\sqrt2\pi^2$ in this metric.'}
        if (field, n, k) == ('complex', 2, 2):
            return {'number': number, 'comment': r'The unitary group $U(2)$ has Frobenius volume $8\pi^3$.'}
        return number


def configure_key_from_stdin():
    if os.environ.get('NUMBERDB_KEY_FROM_STDIN') == '1':
        token = sys.stdin.read().strip()
        if '=' in token and token.split('=', 1)[0].isupper():
            token = token.split('=', 1)[1].strip().strip('\'"')
        numberdb.configure(api_key=token)


if __name__ == '__main__':
    configure_key_from_stdin()
    generator = StiefelVolumes()
    if '--fill' in sys.argv:
        print(generator.publish(message='Fill Frobenius Stiefel volumes with certified balls and reproducible checks.'))
    else:
        report = generator.verify(sample=None)
        print(report)
        sys.exit(0 if report.ok else 1)