def test_H2_cylinder_diagram_contributions(): A = AbelianStratum(2).unique_component() c1 = sum(c.volume_contribution() for c in A.cylinder_diagrams(1)).integral_sum_as_mzv() c2 = sum(c.volume_contribution() for c in A.cylinder_diagrams(2)).integral_sum_as_mzv() assert c1 == M(4) / 3 assert c2 == (2 * M(1, 3) + M(2, 2)) / 3 vol = c1 + c2 assert vol == masur_veech_volume(A, rational=True) * M( 2 * A.stratum().genus())
def test_H211_cylinder_diagram_contributions(): A = AbelianStratum(2, 1, 1).unique_component() c1 = sum(c.volume_contribution() for c in A.cylinder_diagrams(1)).integral_sum_as_mzv() c2 = sum(c.volume_contribution() for c in A.cylinder_diagrams(2)).integral_sum_as_mzv() c3 = sum(c.volume_contribution() for c in A.cylinder_diagrams(3)).integral_sum_as_mzv() assert c1 == 7 * M(8) / 180 assert c2 == (1620 * M(1, 7) + 850 * M(2, 6) + 436 * M(3, 5) + 231 * M(4, 4) + 130 * M(5, 3) + 65 * M(6, 2) + 35 * M(7) - 35 * M(8)) / 1260
def test_H31_cylinder_diagram_contributions(): # values from Table 3 of A. Zorich "Square tiled surfaces # and Teichmueller volumes of the moduli spaces of Abelian # differentials" (2002) A = AbelianStratum(3, 1).unique_component() c1 = sum(c.volume_contribution() for c in A.cylinder_diagrams(1)).integral_sum_as_mzv() c2 = sum(c.volume_contribution() for c in A.cylinder_diagrams(2)).integral_sum_as_mzv() c3 = sum(c.volume_contribution() for c in A.cylinder_diagrams(3)).integral_sum_as_mzv() assert c1 == M(7) / 15 assert c2 == (55 * M(1, 6) + 29 * M(2, 5) + 15 * M(3, 4) + 8 * M(4, 3) + 4 * M(5, 2)) / 45 vol = 16 * M(6) / 45
def test_gothic_generic(): x = polygen(QQ) K = NumberField(x**3 - 2, 'a', embedding=AA(2)**QQ((1, 3))) a = K.gen() S = translation_surfaces.cathedral(a, a**2) O = GL2ROrbitClosure(S) assert O.ambient_stratum() == AbelianStratum(2, 2, 2) for d in O.decompositions(4, 50): O.update_tangent_space_from_flow_decomposition(d) assert O.dimension() == O.absolute_dimension() == 4 assert O.field_of_definition() == QQ
def test_gothic_exact_reals(): pytest.importorskip('pyexactreal') from pyexactreal import ExactReals x = polygen(QQ) K = NumberField(x**3 - 2, 'a', embedding=AA(2)**QQ((1, 3))) R = ExactReals(K) S = translation_surfaces.cathedral(K.gen(), R.random_element([0.1, 0.2])) O = GL2ROrbitClosure(S) assert O.ambient_stratum() == AbelianStratum(2, 2, 2) for d in O.decompositions(4, 50): O.update_tangent_space_from_flow_decomposition(d) assert O.dimension() == O.absolute_dimension() == 4
def test_H4odd_cylinder_diagram_contributions(): A = AbelianStratum(4).odd_component() c1 = sum(c.volume_contribution() for c in A.cylinder_diagrams(1)).integral_sum_as_mzv() c2 = sum(c.volume_contribution() for c in A.cylinder_diagrams(2)).integral_sum_as_mzv() c3 = sum(c.volume_contribution() for c in A.cylinder_diagrams(3)).integral_sum_as_mzv() vol = c1 + c2 + c3 assert vol == A.masur_veech_volume(rational=True) * M( 2 * A.stratum().genus())
def test_minimal_stratum_components(): for g in range(2, 6): A = AbelianStratum(2 * g - 2) assert sum( C.masur_veech_volume(rational=True) for C in A.components()) == A.masur_veech_volume(rational=True) assert sum( C.masur_veech_volume(rational=False) for C in A.components()) == A.masur_veech_volume(rational=False)
def test_gothic_veech(): x = polygen(QQ) K = NumberField(x**2 - 2, 'sqrt2', embedding=AA(2)**QQ((1, 2))) sqrt2 = K.gen() x = QQ((1, 2)) y = 1 a = x + y * sqrt2 b = -3 * x - QQ((3, 2)) + 3 * y * sqrt2 S = translation_surfaces.cathedral(a, b) O = GL2ROrbitClosure(S) assert O.ambient_stratum() == AbelianStratum(2, 2, 2) for d in O.decompositions(4, 50): assert d.parabolic() O.update_tangent_space_from_flow_decomposition(d) assert O.dimension() == O.absolute_dimension() == 2 assert O.field_of_definition() == O.V2._isomorphic_vector_space.base_ring()
def stratum(self): r""" Return the stratum this surface belongs to. This uses the package ``surface_dynamics`` (see http://www.labri.fr/perso/vdelecro/flatsurf_sage.html) EXAMPLES:: sage: import flatsurf.geometry.similarity_surface_generators as sfg sage: sfg.translation_surfaces.octagon_and_squares().stratum() H_3(4) """ from surface_dynamics import AbelianStratum from sage.rings.integer_ring import ZZ return AbelianStratum([ZZ(a - 1) for a in self.angles()])
def test_H11_cylinder_diagram_contributions(): A = AbelianStratum(1, 1).hyperelliptic_component() c1 = sum(c.volume_contribution() for c in A.cylinder_diagrams(1)).integral_sum_as_mzv() c2 = sum(c.volume_contribution() for c in A.cylinder_diagrams(2)).integral_sum_as_mzv() c3 = sum(c.volume_contribution() for c in A.cylinder_diagrams(3)).integral_sum_as_mzv() assert c1 == M(5) / 6 assert c2 == M(2) * M(3) / 3 - M(5) / 6 assert c3 == (2 * M(4) - M(2) * M(3)) / 3 vol = c1 + c2 + c3 assert vol == A.masur_veech_volume(rational=True) * M( 2 * A.stratum().genus())
def ambient_stratum(self): r""" Return the stratum of Abelian differentials this surface belongs to. EXAMPLES:: sage: from flatsurf import EquiangularPolygons, similarity_surfaces sage: from flatsurf import GL2ROrbitClosure # optional: pyflatsurf sage: E = EquiangularPolygons(1, 3, 5) sage: T = E(1) sage: S = similarity_surfaces.billiard(T) sage: S = S.minimal_cover(cover_type="translation") sage: O = GL2ROrbitClosure(S) # optional: pyflatsurf sage: O.ambient_stratum() # optional: pyflatsurf H_3(4, 0^4) """ from surface_dynamics import AbelianStratum surface = self._surface angles = [surface.angle(v) for v in surface.vertices()] return AbelianStratum([a-1 for a in angles])
def test_H_3_3(): H = AbelianStratum(3, 3) check_abelian_component(H.hyperelliptic_component(), 100) check_abelian_component(H.non_hyperelliptic_component(), 100)
def test_H_6(): H = AbelianStratum(6) check_abelian_component(H.hyperelliptic_component(), 100) check_abelian_component(H.even_component(), 100) check_abelian_component(H.odd_component(), 100)
def test_H31(): A = AbelianStratum(3,1) cylinder_diagrams_testing(A) origami_check(A.unique_component(), 10, 10)
def test_H22(): A = AbelianStratum(2,2) cylinder_diagrams_testing(A) origami_check(A.hyperelliptic_component(), 10, 10) origami_check(A.odd_component(), 10, 10)
def click(stratum, component, nb_squares_limit, multiplicities_limit, literature): from surface_dynamics import AbelianStratum if not stratum.startswith("H(") or not stratum.endswith(")"): raise click.UsageError("invalid stratum argument") try: H = AbelianStratum( *[int(x.strip()) for x in stratum[2:-1].split(",")]) except ValueError: raise click.UsageError("invalid stratum argument") if component == "hyp" or component == "hyperelliptic": H = H.hyperelliptic_component() elif component == "nonhyp" or component == "non-hyperelliptic": H = H.nonhyperelliptic_component() elif component == "even": H = H.even_component() elif component == "odd": H = H.odd_component() elif component is not None: raise click.UsageError("invalid component argument") seen = set() for c in H.cylinder_diagrams(): for n in range(c.smallest_integer_lengths()[0], nb_squares_limit): for lh in c.widths_and_heights_iterator(n, height_one=True): for o0 in c.cylcoord_to_origami_iterator(*lh): o1 = o0.mirror() o2 = o0.vertical_symmetry() o3 = o0.horizontal_symmetry() for o in [o0, o1, o2, o3]: o.relabel(inplace=True) if o0 > o1 or o0 > o2 and o0 > o3: continue # TODO: in case of equality above, we will generate the same # origami twice. cd1 = o1.cylinder_decomposition() if any(h != 1 for _, _, _, h, _, _ in cd1): continue for mh in IntegerVectors(multiplicities_limit, c.ncyls(), min_part=1): for mv in IntegerVectors(multiplicities_limit, len(cd1), min_part=1): tv = ThurstonVeech(o.r_tuple(), o.u_tuple(), mh, mv) if tv in seen: print("Skipping duplicate") continue if literature == "include": pass elif literature == "exclude": if tv.reference(): continue elif literature == "only": reference = tv.reference() if (reference is None or "Translation covering" in reference): continue else: raise NotImplementedError( "Unsupported literature value") seen.add(tv) yield tv