# Hyperelliptic components only, with labelled zeros and area one.
# zeros=1: H(2*g-2); zeros=2: H(g-1, g-1). See CMSZ, Section 6.5.
import numberdb.sage as numberdb
from math import factorial, prod
from sage.rings.integer_ring import ZZ
from sage.rings.rational_field import QQ
from sage.rings.real_arb import RealBallField


def hyperelliptic_volume(g, zeros=1, digits=100):
    g = ZZ(g)
    if g < 2 or zeros not in (1, 2):
        raise ValueError('Use genus g >= 2 and one or two zeros.')
    def df(n):
        return prod(range(n, 0, -2))
    if zeros == 1:
        q = QQ(2 * df(2*g - 3)) / (factorial(2*g + 1) * df(2*g - 2))
    else:
        q = QQ(8 * df(2*g - 2)) / (factorial(2*g + 2) * df(2*g - 1))
    field = RealBallField(numberdb.bits(digits, losing=64))
    return field(q) * field.pi()**(2*g)


hyperelliptic_volume(5, zeros=2, digits=100)  # H(4,4), beyond the stored range.
