Strata of Abelian and quadratic differentials¶
Template file¶
Strata of differential on Riemann surfaces
This file gather common code used in
abelian_strata
and
quadratic_strata
.
- class surface_dynamics.flat_surfaces.strata.Strata[source]¶
Bases:
Parent
Strata of Abelian or Quadratic differentials.
- class surface_dynamics.flat_surfaces.strata.Stratum(signature, k)[source]¶
Bases:
UniqueRepresentation
,SageObject
Stratum of holomorphic or meromorphic k-differentials on smooth connected Riemann surfaces.
INPUT:
signature
– a list ofn
integers (determine the angles of conical singularities)k
– optional integer (default1
) the order of the differential
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((2,), k=1) H_2(2)
- components()[source]¶
Lists the connected components of the Stratum.
OUTPUT:
list – a list of connected components of stratum
EXAMPLES:
sage: from surface_dynamics import Stratum
Some abelian strata:
sage: Stratum([0], k=1).components() (H_1(0)^hyp,) sage: Stratum([2], k=1).components() (H_2(2)^hyp,) sage: Stratum([4], k=1).components() (H_3(4)^hyp, H_3(4)^odd) sage: Stratum([2,2], k=1).components() (H_3(2^2)^hyp, H_3(2^2)^odd) sage: Stratum([1,1,1,1], k=1).components() (H_3(1^4)^c,)
Some quadratic strata:
sage: Stratum([12], k=2).components() (Q_4(12)^reg, Q_4(12)^irr) sage: Stratum([6,-1,-1], k=2).components() (Q_2(6, -1^2)^hyp, Q_2(6, -1^2)^nonhyp)
- connected_components[source]¶
File: /home/runner/work/surface-dynamics/surface-dynamics/surface_dynamics/flat_surfaces/strata.py (starting at line 364)
Return the connected components of this stratum of differentials.
Abelian holomorphic differentials [KonZor03]
Quadratic differentials with at most simple poles [Lan08]
- dimension()[source]¶
Return the complex dimension of this stratum.
The dimension is 2g-2+s+1 where g is the genus of surfaces in the stratum, s the number of singularities. The complex dimension of a stratum is also the number of intervals of any interval exchange transformations associated to the strata.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((0,), k=1).dimension() 2 sage: Stratum((0,0), k=1).dimension() 3 sage: Stratum((2,), k=1).dimension() 4 sage: Stratum((1,1), k=1).dimension() 5 sage: Stratum({-1:4}, k=2).dimension() 2
sage: a = Stratum((4,3,2,1,0), k=1) sage: p = a.permutation_representative() sage: len(p) == a.dimension() True
- is_connected()[source]¶
Test if the strata is connected.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([2], k=1).is_connected() True sage: Stratum([2,2], k=1).is_connected() False sage: Stratum([-1,-1,-1,-1], k=2).is_connected() True sage: Stratum([12], k=2).is_connected() False
- is_empty()[source]¶
Return True if the stratum is empty
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([2], k=1).is_empty() False sage: Stratum([1,-1], k=2).is_empty() True
- masur_veech_volume(rational=False, method=None)[source]¶
Return the Masur-Veech volume of this stratum.
INPUT:
rational
(optional, boolean) - ifFalse
(default) return the Masur-Veech volume and ifTrue
return the Masur-Veech volume divided by zeta(2g).method
(optional string) - the method to use to compute the volume either, seemasur_veech_volume()
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([2], k=1).masur_veech_volume() 1/120*pi^4 sage: Stratum([1,1,1,1], k=1).masur_veech_volume() 1/4860*pi^6 sage: Stratum([20], k=1).masur_veech_volume() 1604064377302075061983/792184445986404135075840000000000*pi^22
- nb_fake_zeros()[source]¶
Return the number of fake zeros.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([0], k=1).nb_fake_zeros() doctest:warning ... UserWarning: nb_fake_zeros() has been deprecated and will be removed in a future version of surface-dynamics; use signature() 1 sage: Stratum([1,1,0,0], k=1).nb_fake_zeros() 2 sage: Stratum([0,4,2,2], k=2).nb_fake_zeros() 1
- nb_zeros(fake_zeros=True, poles=True)[source]¶
Returns the number of zeros of self.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([0], k=1).nb_zeros() doctest:warning ... UserWarning: nb_zero() has been deprecated and will be removed in a future version of surface-dynamics; use signature() 1 sage: Stratum({2:4,3:2}, k=1).nb_zeros() 6 sage: Stratum({-1:4}, k=2).nb_zeros() 4 sage: Stratum({-1:4,1:4}, k=2).nb_zeros() 8
- number_of_components()[source]¶
Returns the number of connected components of self
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([2], k=1).number_of_components() 1 sage: Stratum([4], k=1).number_of_components() 2 sage: Stratum([3,3], k=1).number_of_components() 2
- one_component()[source]¶
Returns a connected component of this stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([2], k=1).one_component() H_2(2)^hyp
- permutation_representative(*args, **kwds)[source]¶
Return a permutation of interval exchanges associated to this stratum.
This method only makes sense for Abelian and quadratic differentials.
EXAMPLES:
sage: from surface_dynamics import Stratum
Examples from Abelian differentials:
sage: a = Stratum([3,2,1,0,0], k=1) sage: p = a.permutation_representative() sage: p.stratum() H_4(3, 2, 1, 0^2) sage: a = Stratum([2, 2, 2], k=1) sage: p = a.permutation_representative() sage: p.stratum() H_4(2^3)
Examples from quadratic differentials:
sage: a = Stratum([6,-1,-1], k=2) sage: p = a.permutation_representative() sage: p.stratum() Q_2(6, -1^2) sage: a = Stratum([-1,-1,-1,-1,0,0], k=2) sage: p = a.permutation_representative() sage: p.stratum() Q_0(0^2, -1^4)
- random_component()[source]¶
Returns a random connected component of this stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Q = Stratum([6,6], k=2) sage: Q.random_component() # random Q_4(6^2)^hyp sage: Q.random_component() # random Q_4(6^2)^reg
- rank()[source]¶
Return the rank of this GL(2,R)-invariant manifold (half dimension of the absolute part of the tangent space).
EXAMPLES:
sage: from surface_dynamics import Stratum, QuadraticStrata sage: Stratum((0,0), k=1).rank() 1 sage: Stratum((2,), k=1).rank() 2 sage: Stratum((2,0,0), k=1).rank() 2 sage: Stratum({-1: 4}, k=2).rank() 1 sage: Stratum({-1:4, 0:5}, k=2).rank() 1
Complete list of rank 2 quadratic strata listed by dimension:
sage: for dim in range(4, 9): ....: quad = [Q for Q in QuadraticStrata(dimension=dim) if Q.rank() == 2] ....: print("%d: %s" % (dim, ", ".join(map(str, quad)))) 4: Q_2(5, -1), Q_1(1^2, -1^2), Q_1(3, -1^3), Q_0(1, -1^5) 5: Q_3(8), Q_2(2, 1^2), Q_2(4, 1, -1), Q_2(3, 2, -1), Q_2(6, -1^2), Q_1(2, 1, -1^3), Q_1(4, -1^4), Q_0(2, -1^6) 6: Q_3(6, 2), Q_3(4^2), Q_2(2^2, 1, -1), Q_2(4, 2, -1^2), Q_1(2^2, -1^4) 7: Q_3(4, 2^2), Q_2(2^3, -1^2) 8: Q_3(2^4)
- signature()[source]¶
Return the order of zeros with multiplicities.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([1, 2, 3], k=1).signature() (3, 2, 1) sage: Stratum({2: 4}, k=1).signature() (2, 2, 2, 2) sage: Stratum([-1, 1], k=1).signature() (1, -1) sage: Stratum({-1: 4}, k=2).signature() (-1, -1, -1, -1) sage: Stratum({1: 8}, k=2).signature() (1, 1, 1, 1, 1, 1, 1, 1) sage: Stratum({-2: 2, 0: 1}, k=2).signature() (0, -2, -2)
- surface_differential_order()[source]¶
Return the order of differentials in this stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([1]*6, 3).surface_differential_order() 3
- surface_genus()[source]¶
Return the genus of the surfaces in this stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((0,), k=1).surface_genus() 1 sage: Stratum((1,1), k=1).surface_genus() 2 sage: Stratum((3,2,1), k=1).surface_genus() 4 sage: Stratum((-1,-1,-1,-1), k=2).surface_genus() 0
- surface_has_finite_area()[source]¶
Return whether the k-differentials in this moduli space have finite or infinite area.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((3, 2, 1), k=1).surface_has_finite_area() True sage: Stratum((1, 0, -1), k=1).surface_has_finite_area() False sage: Stratum([-1]*6, k=3).surface_has_finite_area() True sage: Stratum([-2]*3, k=3).surface_has_finite_area() True sage: Stratum([-3]*2, k=3).surface_has_finite_area() False
- unique_component()[source]¶
Returns the unique component of self or raise a ValueError.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([1,1], k=1) sage: a H_2(1^2) sage: a.unique_component() H_2(1^2)^hyp sage: a = Stratum([3,2,1], k=1) sage: a H_4(3, 2, 1) sage: a.unique_component() H_4(3, 2, 1)^c sage: Stratum({1:1, -1:5}, k=2).unique_component() Q_0(1, -1^5)^c sage: Stratum([3,2,-1], k=2).unique_component() Q_2(3, 2, -1)^nonhyp sage: Stratum([12], k=2).unique_component() Traceback (most recent call last): ... ValueError: several components for this stratum
- class surface_dynamics.flat_surfaces.strata.StratumComponent(stratum)[source]¶
Bases:
SageObject
Generic class for connected component of a stratum of flat surfaces.
Assumes there are implemented
a method .permutation_representative()
There may be
an attribute ._name
an attribute ._latex_name
- dimension()[source]¶
Return the (complex) dimension of this GL(2,R)-invariant orbifold.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([4], k=1).odd_component().dimension() 6 sage: Stratum([12], k=2).regular_component().dimension() 7
- masur_veech_volume(rational=False, method=None)[source]¶
Return the Masur-Veech volume of this stratum component.
INPUT:
rational
(optional, boolean) - ifFalse
(default) return the Masur-Veech volume and ifTrue
return the Masur-Veech volume divided by zeta(2g).method
(optional string) - the method to use to compute the volume either, seemasur_veech_volume()
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([4], k=1).hyperelliptic_component().masur_veech_volume() 1/6720*pi^6 sage: Stratum([6], k=1).even_component().masur_veech_volume() 32/1913625*pi^8
- rank()[source]¶
Return the rank of this GL(2,R)-invariant orbifold.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([4], k=1).odd_component().rank() 3 sage: Stratum([12], k=2).regular_component().rank() 3
- stratum()[source]¶
Return the stratum associated to self
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([4,4], k=1) sage: all([c.stratum() == a for c in a.components()]) True
- surface_dynamics.flat_surfaces.strata.list_to_exp_list(l)[source]¶
Convert list into exponential notation.
EXAMPLES:
sage: from surface_dynamics import * sage: from surface_dynamics.flat_surfaces.strata import list_to_exp_list sage: l = [0,0,2,2,3,2,0,0,0] sage: list_to_exp_list(l) [(0, 2), (2, 2), (3, 1), (2, 1), (0, 3)]
Abelian strata¶
Strata of differentials on Riemann surfaces
The space of Abelian differentials on Riemann surfaces of a given genus is
stratified by degrees of zeros. Each stratum has one, two or three connected
components each of which is associated to an extended Rauzy class. The
components()
method
lists connected components of a stratum.
The work for Abelian differentials was done by Maxim Kontsevich and Anton Zorich in [KonZor03] and for quadratic differentials by Erwan Lanneau in [Lan08]. Zorich gave an algorithm to pass from a connected component of a stratum to the associated Rauzy class (for both interval exchange transformations and linear involutions) in [Zor08] and is implemented for Abelian stratum at different level (approximately one for each component):
for connected stratum
permutation_representative()
for hyperellitic component
permutation_representative()
for non hyperelliptic component, the algorithm is the same as for connected component
for odd component
permutation_representative()
for even component
permutation_representative()
The inverse operation (pass from an interval exchange transformation to the connected component) is partially written in [KonZor03] and simply named here ?
Some of the code here was first available on Mathematica [ZS].
A refinement of Zorich representatives was worked out by L. Jefreys in [Jef19]. Namely, for each connected component of Abelian differential his construction provides a square-tiled surface with both in horizontal and vertical direction a decomposition with single cylinder of height one. The implementation is available as
for connected stratum
single_cylinder_representative()
for hyperelliptic component
single_cylinder_representative()
for odd component
single_cylinder_representative()
for even component
single_cylinder_representative()
AUTHORS:
Vincent Delecroix (2009-09-29): initial version
EXAMPLES:
sage: from surface_dynamics import *
Construction of a stratum from a list of singularity degrees:
sage: a = Stratum([1,1], k=1)
sage: a
H_2(1^2)
sage: a.surface_genus()
2
sage: a.dimension()
5
sage: a = Stratum([4,3,2,1], k=1)
sage: a
H_6(4, 3, 2, 1)
sage: a.surface_genus()
6
sage: a.dimension()
15
By convention, the degrees are always written in decreasing order:
sage: a1 = Stratum([4,3,2,1], k=1)
sage: a1
H_6(4, 3, 2, 1)
sage: a2 = Stratum([2,3,1,4], k=1)
sage: a2
H_6(4, 3, 2, 1)
sage: a1 == a2
True
It is possible to lis strata and their connected components:
sage: Stratum([10], k=1).components()
(H_6(10)^hyp, H_6(10)^odd, H_6(10)^even)
Get a list of strata with constraints on genus or on the number of intervals of a representative:
sage: AbelianStrata(genus=3).list()
[H_3(4), H_3(3, 1), H_3(2^2), H_3(2, 1^2), H_3(1^4)]
Obtains the connected components of a stratum:
sage: a = Stratum([0], k=1)
sage: a.components()
(H_1(0)^hyp,)
sage: @cached_function
....: def nb_irred_perm(n):
....: if n == 0 or n == 1: return 1
....: return factorial(n) - sum(nb_irred_perm(k) * factorial(n - k) for k in range(1,n))
sage: [nb_irred_perm(i) for i in range(10)]
[1, 1, 1, 3, 13, 71, 461, 3447, 29093, 273343]
sage: A = AbelianStrata(dimension=5, fake_zeros=True)
sage: N = 0
sage: for a in A:
....: for cc in a.components():
....: for z in set(a.signature()):
....: p = cc.permutation_representative(left_degree=z)
....: n = p.rauzy_diagram().cardinality()
....: print("%13s, %d : %d"%(cc, z, n))
....: print(p)
....: N += n
H_2(2, 0)^hyp, 0 : 11
0 1 2 3 4
4 2 1 3 0
H_2(2, 0)^hyp, 2 : 35
0 1 2 3 4
4 1 3 2 0
H_2(1^2)^hyp, 1 : 15
0 1 2 3 4
4 3 2 1 0
H_1(0^4)^hyp, 0 : 10
0 1 2 3 4
4 0 1 2 3
sage: N
71
sage: nb_irred_perm(5)
71
- surface_dynamics.flat_surfaces.abelian_strata.ASC¶
alias of
AbelianStratumComponent
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStrata(genus=None, dimension=None, fake_zeros=None)[source]¶
Bases:
Strata
Abelian strata.
INPUT:
genus
- a non negative integer or Nonedimension
- a non negative integer or Nonefake_zeros
- boolean
EXAMPLES:
sage: from surface_dynamics import *
Abelian strata with a given genus:
sage: for s in AbelianStrata(genus=1): print(s) H_1(0)
sage: for s in AbelianStrata(genus=2): print(s) H_2(2) H_2(1^2)
sage: for s in AbelianStrata(genus=3): print(s) H_3(4) H_3(3, 1) H_3(2^2) H_3(2, 1^2) H_3(1^4)
sage: for s in AbelianStrata(genus=4): print(s) H_4(6) H_4(5, 1) H_4(4, 2) H_4(4, 1^2) H_4(3^2) H_4(3, 2, 1) H_4(3, 1^3) H_4(2^3) H_4(2^2, 1^2) H_4(2, 1^4) H_4(1^6)
Get outside of the tests. Abelian strata with a given number of intervals
sage for s in AbelianStrata(dimension=2): print(s) H^out([0])
sage for s in AbelianStrata(dimension=3): print(s) H^out([0], 0)
sage for s in AbelianStrata(dimension=4): print(s) H^out([2]) H^out([0], 0, 0)
Get outside of tests sage for s in AbelianStrata(dimension=5): print(s) H^out(2, [0]) H^out([2], 0) H^out([1], 1) H^out([0], 0, 0, 0)
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStrata_all(genus=None, dimension=None, fake_zeros=None)[source]¶
Bases:
AbelianStrata
Abelian strata.
INPUT:
fake_zeros
- boolean (default:False
)
EXAMPLES:
sage: from surface_dynamics import * sage: A = AbelianStrata() sage: it = iter(A) sage: for _ in range(10): ....: print(next(it)) H_1(0) H_2(2) H_2(1^2) H_3(4) H_3(3, 1) H_3(2^2) H_4(6) H_3(2, 1^2) H_4(5, 1) H_4(4, 2) sage: A = AbelianStrata(fake_zeros=True) sage: it = iter(A) sage: for _ in range(10): ....: print(next(it)) H_1(0) H_1(0^2) H_2(2) H_1(0^3) H_2(2, 0) H_2(1^2) H_1(0^4) H_3(4) H_2(2, 0^2) H_2(1^2, 0)
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStrata_d(genus=None, dimension=None, fake_zeros=None)[source]¶
Bases:
AbelianStrata
Strata with prescribed dimension.
INPUT:
dimension
- an integer greater than 1fake_zeros
- boolean (default: False) - allows or not fake zeros
EXAMPLES:
sage: from surface_dynamics import * sage: for a in AbelianStrata(dimension=5,fake_zeros=True): ....: print(a) ....: print(a.permutation_representative()) H_2(2, 0) 0 1 2 3 4 4 1 3 2 0 H_2(1^2) 0 1 2 3 4 4 3 2 1 0 H_1(0^4) 0 1 2 3 4 4 0 1 2 3
- an_element()¶
Returns the first stratum.
EXAMPLES:
sage: from surface_dynamics import AbelianStrata sage: AbelianStrata(dimension=2).first() H_1(0) sage: AbelianStrata(dimension=3).first() H_1(0^2) sage: AbelianStrata(dimension=4).first() H_2(2)
- cardinality()[source]¶
Return the number of Abelian strata with given dimension.
EXAMPLES:
sage: from surface_dynamics import * sage: AbelianStrata(dimension=5,fake_zeros=True).cardinality() 3 sage: AbelianStrata(dimension=5,fake_zeros=False).cardinality() 1 sage: AbelianStrata(dimension=6,fake_zeros=True).cardinality() 4 sage: AbelianStrata(dimension=6,fake_zeros=False).cardinality() 1 sage: AbelianStrata(dimension=7,fake_zeros=True).cardinality() 6 sage: AbelianStrata(dimension=7,fake_zeros=False).cardinality() 2 sage: AbelianStrata(dimension=12,fake_zeros=True).cardinality() 29 sage: AbelianStrata(dimension=12,fake_zeros=False).cardinality() 7
- first()[source]¶
Returns the first stratum.
EXAMPLES:
sage: from surface_dynamics import AbelianStrata sage: AbelianStrata(dimension=2).first() H_1(0) sage: AbelianStrata(dimension=3).first() H_1(0^2) sage: AbelianStrata(dimension=4).first() H_2(2)
- last()[source]¶
Return the last stratum.
EXAMPLES:
sage: from surface_dynamics import AbelianStrata sage: AbelianStrata(dimension=9,fake_zeros=True).last() H_1(0^8) sage: AbelianStrata(dimension=9,fake_zeros=False).last() H_3(1^4) sage: AbelianStrata(dimension=10,fake_zeros=True).last() H_1(0^9) sage: AbelianStrata(dimension=10,fake_zeros=False).last() H_4(2^3)
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStrata_g(genus=None, dimension=None, fake_zeros=None)[source]¶
Bases:
AbelianStrata
Stratas of genus g surfaces without fake zeros.
INPUT:
genus
- a non negative integer
EXAMPLES:
sage: from surface_dynamics import * sage: AbelianStrata(genus=2).list() [H_2(2), H_2(1^2)] sage: AbelianStrata(genus=3).list() [H_3(4), H_3(3, 1), H_3(2^2), H_3(2, 1^2), H_3(1^4)] sage: AbelianStrata(genus=4).random_element() #random H_4(4, 2)
- an_element_()¶
Return the first element of this list of strata.
EXAMPLES:
sage: from surface_dynamics import AbelianStrata sage: AbelianStrata(genus=3).first() H_3(4) sage: AbelianStrata(genus=4).first() H_4(6)
- cardinality()[source]¶
Return the number of abelian strata with a given genus.
EXAMPLES:
sage: from surface_dynamics import * sage: AbelianStrata(genus=1).cardinality() 1 sage: AbelianStrata(genus=2).cardinality() 2 sage: AbelianStrata(genus=3).cardinality() 5 sage: AbelianStrata(genus=4).cardinality() 11
- first()[source]¶
Return the first element of this list of strata.
EXAMPLES:
sage: from surface_dynamics import AbelianStrata sage: AbelianStrata(genus=3).first() H_3(4) sage: AbelianStrata(genus=4).first() H_4(6)
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStrata_gd(genus=None, dimension=None, fake_zeros=None)[source]¶
Bases:
AbelianStrata
Abelian strata of prescribed genus and number of intervals.
INPUT:
genus
- integer: the genus of the surfacesdimension
- integer: the number of intervalsfake_zeros
- boolean: whether or not consider fake zeros
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStratum(signature, k)[source]¶
Bases:
Stratum
Stratum of Abelian differentials.
A stratum with a marked outgoing separatrix corresponds to Rauzy diagram with left induction, a stratum with marked incoming separatrix correspond to Rauzy diagram with right induction. If there is no marked separatrix, the associated Rauzy diagram is the extended Rauzy diagram (consideration of the
surface_dynamics.interval_exchanges.template.Permutation.symmetric()
operation of Boissy-Lanneau).When you want to specify a marked separatrix, the degree on which it is is the first term of your degrees list.
INPUT:
marked_separatrix
-None
(default) or ‘in’ (for incoming separatrix) or ‘out’ (for outgoing separatrix).
EXAMPLES:
sage: from surface_dynamics import *
Creation of an Abelian stratum and get its connected components:
sage: a = Stratum((2, 2), k=1) sage: a H_3(2^2) sage: a.components() (H_3(2^2)^hyp, H_3(2^2)^odd)
Get a permutation representative of a connected component:
sage: a = Stratum((2,2), k=1) sage: a_hyp, a_odd = a.components() sage: a_hyp.permutation_representative() 0 1 2 3 4 5 6 6 5 4 3 2 1 0 sage: a_odd.permutation_representative() 0 1 2 3 4 5 6 3 2 4 6 5 1 0
You can specify the alphabet:
sage: a_odd.permutation_representative(alphabet="ABCDEFGHIJKLMNOPQRSTUVWXYZ") A B C D E F G D C E G F B A
- cylinder_diagram_iterator(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
Iterator over all cylinder diagram of this stratum.
The generation is up to isomorphism and horizontal/vertical symmetry (and they are in standard form).
INPUT:
ncyls
– an optional number of cylindersup_to_symmetry
- (boolean, defaultTrue
) to return only cylinder diagrams up to horizontal and vertical symmetry.force_computation
– ifTrue
do no use the database of cylinder diagrams (default isFalse
)
EXAMPLES:
sage: from surface_dynamics import Stratum, CylinderDiagram sage: A = Stratum([4], k=1) sage: C1 = [CylinderDiagram('(0,2,1)-(0,3,4) (3)-(2) (4)-(1)'), ....: CylinderDiagram('(0,2,1)-(0,3,4) (3)-(1) (4)-(2)'), ....: CylinderDiagram('(0,1)-(0,3,4) (2,3)-(1) (4)-(2)'), ....: CylinderDiagram('(0,2)-(4) (1,4)-(2,3) (3)-(0,1)'), ....: CylinderDiagram('(0,2)-(0,3) (1,3)-(1,4) (4)-(2)'), ....: CylinderDiagram('(0,1)-(0,3) (2,3)-(1,4) (4)-(2)')] sage: C2 = list(A.cylinder_diagram_iterator(3, force_computation=True)) sage: assert len(C1) == len(C2) sage: for (c1, c2) in zip(C1, C2): ....: assert c1.is_isomorphic(c2) or \ ....: c1.is_isomorphic(c2.horizontal_symmetry()) or \ ....: c1.is_isomorphic(c2.vertical_symmetry()) or \ ....: c1.is_isomorphic(c2.inverse()) sage: sum(1 for _ in A.cylinder_diagram_iterator(3, True, True)) 6 sage: sum(1 for _ in A.cylinder_diagram_iterator(3, True, False)) 6 sage: sum(1 for _ in A.cylinder_diagram_iterator(3, False, True)) 9 sage: sum(1 for _ in A.cylinder_diagram_iterator(3, False, False)) 9
- cylinder_diagrams(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
Return a list of cylinder diagram of this stratum.
INPUT:
- ``ncyls`` -- an optional number of cylinders
up_to_symmetry
- (boolean, defaultTrue
) to return only cylinder diagrams up to horizontal and vertical symmetry.force_computation
– IfTrue
then do not use the database of cylinder diagrams (default isFalse
).
EXAMPLES:
sage: from surface_dynamics import Stratum, CylinderDiagram sage: A = Stratum([2,2], k=1) sage: C1 = [CylinderDiagram('(0,1)-(0,5) (2)-(4) (3,4)-(1) (5)-(2,3)'), ....: CylinderDiagram('(0,2,1)-(3,4,5) (3)-(1) (4)-(2) (5)-(0)'), ....: CylinderDiagram('(0,2,1)-(3,5,4) (3)-(1) (4)-(2) (5)-(0)'), ....: CylinderDiagram('(0,3)-(5) (1)-(0) (2,5)-(3,4) (4)-(1,2)'), ....: CylinderDiagram('(0,3)-(0,5) (1,2)-(1,4) (4)-(3) (5)-(2)'), ....: CylinderDiagram('(0,5)-(3,4) (1,4)-(2,5) (2)-(0) (3)-(1)'), ....: CylinderDiagram('(0,5)-(3,4) (1,4)-(2,5) (2)-(1) (3)-(0)')] sage: C2 = A.cylinder_diagrams(4) sage: assert len(C1) == len(C2) sage: isoms = [] sage: for c in A.cylinder_diagrams(4): ....: isom = [] ....: for i,cc in enumerate(C1): ....: if c.is_isomorphic(cc) or \ ....: c.is_isomorphic(cc.horizontal_symmetry()) or \ ....: c.is_isomorphic(cc.vertical_symmetry()) or \ ....: c.is_isomorphic(cc.inverse()): ....: isom.append(i) ....: assert len(isom) == 1, isom ....: isoms.extend(isom) sage: assert sorted(isoms) == [0, 1, 2, 3, 4, 5, 6] sage: len(A.cylinder_diagrams(4, up_to_symmetry=False)) 7 sage: sum(4 / (1 + sum(cd.symmetries())) for cd in A.cylinder_diagrams(4, up_to_symmetry=True)) 7
Recovering the multiplicity of the symmetric versions:
sage: total = 0 sage: for c in Stratum([2,1,1], k=1).cylinder_diagrams(2): ....: total += 4 // (1 + sum(c.symmetries())) sage: total 61 sage: len(Stratum([2, 1, 1], k=1).cylinder_diagrams(2, up_to_symmetry=False)) 61
You obtain the same number directly:
sage: Stratum([2, 1, 1], k=1).cylinder_diagrams_number(2, up_to_symmetry=False) 61
- cylinder_diagrams_by_component(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
Return a dictionary component -> list of cylinder diagrams.
INPUT:
ncyls
- None or integer (default: None) - the number of cylindersup_to_symmetry
- (boolean, defaultTrue
) to return only cylinder diagrams up to horizontal and vertical symmetry.force_computation
- boolean (default:False
) - ifFalse
, then try to use the database.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: A = Stratum([4], k=1) sage: cyls = A.cylinder_diagrams_by_component(ncyls=2, force_computation=True) sage: A_hyp = A.hyperelliptic_component() sage: A_odd = A.odd_component() sage: len(cyls[A_odd]) 4 sage: len(cyls[A_hyp]) 2 sage: all(c.ncyls() == 2 for c in cyls[A_hyp]) True sage: all(c.stratum_component() == A_hyp for c in cyls[A_hyp]) True sage: all(c.ncyls() == 2 for c in cyls[A_odd]) True sage: all(c.stratum_component() == A_odd for c in cyls[A_odd]) True sage: for ncyls in range(1, 4): ....: for up_to_symmetry in [True, False]: ....: cd1 = A.cylinder_diagrams_by_component(ncyls, up_to_symmetry, True) ....: cd2 = A.cylinder_diagrams_by_component(ncyls, up_to_symmetry, False) ....: assert len(cd1[A_hyp]) == len(cd2[A_hyp]) ....: assert len(cd1[A_odd]) == len(cd2[A_odd])
- cylinder_diagrams_number(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
Return the number of cylinder diagram that belongs to this stratum.
INPUT:
ncyls
– an optional number of cylindersup_to_symmetry
- (boolean, defaultTrue
) to return only cylinder diagrams up to horizontal and vertical symmetry.force_computation
– ifTrue
do no use the database of cylinder diagrams (default isFalse
)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: H22 = Stratum([2,2], k=1) sage: H22.cylinder_diagrams_number(3) 18 sage: H22.cylinder_diagrams_number(4) 7
If
force_computation
is set toTrue
then the database is not used. It might be slower for large strata:sage: H22.cylinder_diagrams_number(3, force_computation=True) 18 sage: H22.cylinder_diagrams_number(4, force_computation=True) 7 sage: H31 = Stratum([3,1], k=1) sage: for d in range(1,5): ....: print("%d %d" %(H31.cylinder_diagrams_number(d, True, False), ....: H31.cylinder_diagrams_number(d, True, True))) 2 2 12 12 16 16 4 4 sage: H211 = Stratum([2,1,1], k=1) sage: for d in range(1,6): ....: print("%d %d" % (H211.cylinder_diagrams_number(d, True, False), ....: H211.cylinder_diagrams_number(d, True, True))) 5 5 29 29 53 53 27 27 8 8
- even_component()[source]¶
Return the even component of self (if any)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum({2:4}, k=1) sage: a H_5(2^4) sage: a.even_component() H_5(2^4)^even
- has_even_component()[source]¶
Test whether this stratum has an even spin component.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((2,2), k=1).has_even_component() False sage: Stratum((6,), k=1).has_even_component() True sage: Stratum((6,), k=1).even_component() H_4(6)^even sage: Stratum((0,), k=1).has_even_component() False
- has_hyperelliptic_component()[source]¶
Test whether this stratum has an hyperelliptic component.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((2,1,1), k=1).has_hyperelliptic_component() False sage: Stratum((2,2), k=1).has_hyperelliptic_component() True sage: Stratum((0,0,0), k=1).has_hyperelliptic_component() True sage: Stratum((2,0), k=1).has_hyperelliptic_component() True sage: Stratum((2,2), k=1).hyperelliptic_component() H_3(2^2)^hyp
- has_non_hyperelliptic_component()[source]¶
Test whether this stratum has a non-hyperelliptic component.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((1,1), k=1).has_non_hyperelliptic_component() False sage: Stratum((3,3), k=1).has_non_hyperelliptic_component() True sage: Stratum((3,3,0), k=1).has_non_hyperelliptic_component() True sage: Stratum((3,3), k=1).non_hyperelliptic_component() H_4(3^2)^nonhyp
- has_odd_component()[source]¶
Test whether this stratum has an odd spin component.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum((2,), k=1).has_odd_component() False sage: Stratum((4,), k=1).has_odd_component() True sage: Stratum((4,), k=1).odd_component() H_3(4)^odd sage: Stratum((0,), k=1).has_odd_component() False
- hyperelliptic_component()[source]¶
Return the hyperelliptic component of self (if any)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([10], k=1) sage: a H_6(10) sage: a.hyperelliptic_component() H_6(10)^hyp
- non_hyperelliptic_component()[source]¶
Return the non hyperelliptic component of self (if any)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum((3,3), k=1) sage: a H_4(3^2) sage: a.non_hyperelliptic_component() H_4(3^2)^nonhyp
- odd_component()[source]¶
Return the odd component of self (if any).
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([2,2], k=1) sage: a H_3(2^2) sage: a.odd_component() H_3(2^2)^odd
- one_cylinder_diagram()[source]¶
Return a diagram with one cylinder in this connected component.
The diagram returned is the one deduced from the method representative.
INPUT:
ncyls
- the number of cylinders
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([3,2,1], k=1) sage: a H_4(3, 2, 1) sage: c = a.one_cylinder_diagram();c (0,8,3,2,1,6,5,4,7)-(0,8,7,6,5,4,3,2,1) sage: c.stratum() H_4(3, 2, 1)
- orientation_quotients(fake_zeros=False)[source]¶
Return the list of quadratic strata such that their orientation cover are contained in this stratum.
If
fake_zeros
(default: False) is True we do care about poles which becomes a marked zero.EXAMPLES:
sage: from surface_dynamics import Stratum
The stratum H(2g-2) has one conic singularities of angle 2(2g-1)pi. The only way a surface in H(2g-2) covers a quadratic differential is that the quadratic differential has as unique zeros a conical singularity of angle (2g-1) pi. The number of poles may vary and give a collection of possibilities:
sage: Stratum([2], k=1).orientation_quotients() [Q_0(1, -1^5)] sage: Stratum([4], k=1).orientation_quotients() [Q_1(3, -1^3), Q_0(3, -1^7)] sage: Stratum([6], k=1).orientation_quotients() [Q_2(5, -1), Q_1(5, -1^5), Q_0(5, -1^9)]
A stratum with two zeros may or may not have orientation quotients:
sage: Stratum([1,1], k=1).orientation_quotients() [Q_1(2, -1^2), Q_0(2, -1^6)] sage: Stratum([2,2], k=1).orientation_quotients() [Q_1(1^2, -1^2), Q_0(1^2, -1^6), Q_1(4, -1^4), Q_0(4, -1^8)] sage: Stratum([3,1], k=1).orientation_quotients() []
To impose that covering of poles are fake zeros, switch option
fake_zeros
toTrue
:sage: Stratum([2,2,0,0], k=1).orientation_quotients(fake_zeros=True) [Q_1(1^2, -1^2)]
- separatrix_diagram_iterator(ncyls=None)[source]¶
Return an iterator over the separatrix diagrams of this stratum.
For strata of small dimension, it could be faster to use the method separatrix_diagrams.
INPUT:
ncyls
– an optional number of cylinders
- separatrix_diagrams(ncyls=None)[source]¶
Returns the list of separatrix diagrams that appears in this stratum.
INPUT:
database
- boolean (default: True) - if True, use the FlatSurfacesDatabase
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([2], k=1) sage: a H_2(2) sage: for s in a.separatrix_diagrams(): print(s) (0,1,2)-(0,1,2) (0)(1,2)-(0,1)(2)
- separatrix_diagrams_number(ncyls=None)[source]¶
Return the number of separatrix diagram that belongs to this stratum.
- single_cylinder_origami()[source]¶
Returns an origami associated to a single cylinder permutation representative.
Returns an origami in this connected component having a single vertical cylinder and a single horizontal cylinder.
Examples:
sage: from surface_dynamics import Stratum sage: C = Stratum([4], k=1) sage: O = C.single_cylinder_origami() sage: O (1,2,3,4,5) (1,4,3,5,2) sage: O.stratum() == Stratum([4], k=1) True sage: C = Stratum([2,0], k=1) sage: O = C.single_cylinder_origami() sage: O (1,2,3,4) (1,3,2,4) sage: O.stratum() == Stratum([2], k=1) True
- single_cylinder_representative(alphabet=None, reduced=True)[source]¶
Returns a single cylinder permutation representative.
Returns a permutation representative of a square-tiled surface in this component having a single vertical cylinder and a single horizontal cylinder.
Such representatives were constructed for every stratum of Abelian differentials by Jeffreys [Jef19].
INPUT:
alphabet
– an optional alphabet for the permutation representativereduced
(boolean, defaultTrue
) – whether to return a reduced permutation (ie without labels)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: C = Stratum([2,0], k=1) sage: p = C.single_cylinder_representative() sage: p 0 1 2 3 4 4 3 1 2 0 sage: p.stratum() == C True sage: C = Stratum([3,1], k=1) sage: p = C.single_cylinder_representative(alphabet=Alphabet(name='lower')) sage: p a b c d e f g c f b g e d a sage: p.stratum() == C True sage: C = Stratum([2], k=1) sage: C.single_cylinder_representative() Traceback (most recent call last): ... ValueError: no 1,1-square-tiled surfaces in this stratum try again with H_2(2, 0) sage: C = Stratum([1,1], k=1) sage: C.single_cylinder_representative() Traceback (most recent call last): ... ValueError: no 1,1-square-tiled surfaces in this stratum try again with H_2(1^2, 0^2)
- class surface_dynamics.flat_surfaces.abelian_strata.AbelianStratumComponent(stratum)[source]¶
Bases:
StratumComponent
Connected component of Abelian stratum.
Warning
Internal class! Do not use directly!
- arithmetic_teichmueller_curves(n, primitive=False)[source]¶
Return the arithmetic Teichmueller curves in that component of stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: A = Stratum([2], k=1).hyperelliptic_component(); A H_2(2)^hyp sage: for i in range(3,10): ....: print("%d %d" % (i,len(A.arithmetic_teichmueller_curves(i)))) 3 1 4 1 5 2 6 1 7 2 8 1 9 2 sage: A = Stratum([1,1], k=1).hyperelliptic_component(); A H_2(1^2)^hyp sage: for i in range(4,10): ....: T = A.arithmetic_teichmueller_curves(i) ....: T_prim = list(filter(lambda t:t.origami().is_primitive(), T)) ....: print("%d %d %d" % (i,len(T),len(T_prim))) 4 2 1 5 1 1 6 5 2 7 2 2 8 4 2 9 4 2 sage: A = Stratum([4], k=1).hyperelliptic_component(); A H_3(4)^hyp sage: for i in range(5,10): ....: print("%d %d" % (i,len(A.arithmetic_teichmueller_curves(i)))) 5 2 6 4 7 3 8 3 9 4
- cylinder_diagram_iterator(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
An iterator over the cylinder diagrams.
INPUT:
- ``ncyls`` -- (optional) a fixed number of cylinders
up_to_symmetry
- (boolean, defaultTrue
) to return only cylinder diagrams up to horizontal and vertical symmetry.force_computation
– (defaultFalse
) whether the database should be used or not
EXAMPLES:
sage: from surface_dynamics import Stratum sage: A = Stratum([1,1,1,1], k=1) sage: cc = A.unique_component() sage: it = cc.cylinder_diagram_iterator(3) sage: cyl = next(it); cyl (0,7)-(0,5) (1,6)-(1,4) (2,4,3,5)-(2,7,3,6) sage: cyl.stratum_component() H_3(1^4)^c sage: cyl.ncyls() 3
Note that if you set
force_computation
toTrue
the order of the iteration might be different and you might obtain cylinder diagram with some symmetries applied:sage: # long time sage: C1 = list(cc.cylinder_diagram_iterator(3, force_computation=False)) sage: C2 = list(cc.cylinder_diagram_iterator(3, force_computation=True)) sage: assert len(C1) == len(C2) sage: isoms = [] sage: for c in C1: ....: isom = [] ....: for i,cc in enumerate(C2): ....: if c.is_isomorphic(cc) or \ ....: c.is_isomorphic(cc.horizontal_symmetry()) or \ ....: c.is_isomorphic(cc.vertical_symmetry()) or \ ....: c.is_isomorphic(cc.inverse()): ....: isom.append(i) ....: assert len(isom) == 1, isom ....: isoms.extend(isom) sage: assert sorted(isoms) == list(range(len(C1)))
- cylinder_diagrams(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
Return the list of cylinder diagrams associated to this component.
INPUT:
ncyls
- integer or list of integers (default: None) - consider only the cylinder diagrams with a given number of cylinders.up_to_symmetry
- (boolean, defaultTrue
) to return only cylinder diagrams up to horizontal and vertical symmetry.force_computation
– boolean (defaultFalse
). IfTrue
, the database of cylinder diagrams is not used.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: C = Stratum([1,1,1,1], k=1).unique_component(); C H_3(1^4)^c sage: for c in C.cylinder_diagrams(6): print(c) (0,1)-(7) (2)-(0) (3)-(4) (4,7)-(5,6) (5)-(1) (6)-(2,3) (0,1)-(7) (2)-(1) (3)-(0) (4,7)-(5,6) (5)-(4) (6)-(2,3) (0,3)-(6,7) (1,2)-(4,5) (4)-(1) (5)-(3) (6)-(2) (7)-(0) (0,3)-(6,7) (1,2)-(4,5) (4)-(3) (5)-(0) (6)-(2) (7)-(1)
- cylinder_diagrams_number(ncyls=None, up_to_symmetry=True, force_computation=False)[source]¶
Return the number of cylinder diagrams.
INPUT:
ncyls
- integer or list of integers (default: None) - restrict the counting to a given number of cylinders.up_to_symmetry
- (boolean, defaultTrue
) to count only cylinder diagrams up to horizontal and vertical symmetry.force_computation
- (default:False
) whether we use the database or compute explicitly using the generation algorithm.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: C = Stratum([3,1], k=1).unique_component() sage: C.cylinder_diagrams_number(1) 2 sage: C.cylinder_diagrams_number(2) 12 sage: C.cylinder_diagrams_number(3) 16 sage: C.cylinder_diagrams_number(4) 4
Note that when setting
force_computation
toTrue
we got the same numbers:sage: for i in range(1,5): ....: print(C.cylinder_diagrams_number(i, force_computation=True)) 2 12 16 4 sage: C = Stratum([6], k=1) sage: C_hyp = C.hyperelliptic_component() sage: C_odd = C.odd_component() sage: C_even = C.even_component() sage: for i in range(1,5): print(C.cylinder_diagrams_number(i)) 16 76 130 67 sage: for i in range(1,5): print(C_hyp.cylinder_diagrams_number(i)) 1 3 8 4 sage: for i in range(1,5): print(C_odd.cylinder_diagrams_number(i)) 11 49 80 42 sage: for i in range(1,5): ....: print(C_even.cylinder_diagrams_number(i, True, False)) 4 24 42 21 sage: for i in range(1,5): # long time ....: print(C_even.cylinder_diagrams_number(i, True, True)) # long time 4 24 42 21
- lyapunov_exponents_approx(**kargs)[source]¶
Return the approximate Lyapunov exponents of the KZ-cocycle.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: Stratum([2], k=1).unique_component().lyapunov_exponents_approx(nb_iterations=2**21) # abs tol .05 [1.000, 0.333] sage: H4hyp, H4odd = Stratum([4], k=1).components() sage: H4hyp.lyapunov_exponents_approx(nb_iterations=2**21) # abs tol .05 [1.000, 0.616, 0.184] sage: H4odd.lyapunov_exponents_approx(nb_iterations=2**21) # abs tol .05 [1.000, 0.418, 0.182]
- one_cylinder_diagram()[source]¶
Return a diagram with one cylinder in this connected component.
The diagram returned is the one deduced from the method permutation_representative.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: A = Stratum([2,2], k=1).odd_component() sage: c = A.one_cylinder_diagram() sage: c (0,5,1,3,2,4)-(0,5,4,3,2,1) sage: c.stratum_component() H_3(2^2)^odd sage: A = Stratum([3,3], k=1).non_hyperelliptic_component() sage: c = A.one_cylinder_diagram() sage: c (0,7,3,2,1,5,4,6)-(0,7,6,5,4,3,2,1) sage: c.stratum_component() H_4(3^2)^nonhyp
- one_origami()[source]¶
Returns an origami in this component
The origami returned has the minimal number of squares and one cylinder. It is obtained from the permutation representative of the stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([2,2], k=1).one_component() sage: a.one_origami().stratum() H_3(2^2) sage: Stratum([3,2,1], k=1).unique_component().one_origami().stratum() H_4(3, 2, 1)
- origami_iterator(n, reduced=True, primitive=False)[source]¶
Iterator through the set of origamis with
n
squares in this stratum.The output origamis are in normal form. But be careful as there may be repetition in the output!
INPUT:
n
- integer - the number of squaresreduced
- boolean (default:True
)primitive
- boolean (default:False
)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: cc = Stratum([6], k=1).even_component() sage: it = cc.origami_iterator(13) sage: o = next(it) sage: o (1,2,3,4,5,6,7,8,9,10,11,12,13) (1,8,2)(3,12,6,11,5,13,7,9)(4,10) sage: o.stratum_component() H_4(6)^even
- origamis(n, reduced=True, primitive=False)[source]¶
Return the set of origamis with n squares in this stratum.
INPUT:
n
- integer - the number of squaresreduced
- boolean (default: True)primitive
- boolean (default: False)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: H11_hyp = Stratum([1,1], k=1).hyperelliptic_component() sage: len(H11_hyp.origamis(6)) 88 sage: T6 = H11_hyp.arithmetic_teichmueller_curves(6) sage: len(T6) 5 sage: sum(t.veech_group().index() for t in T6) 88 sage: H4_odd = Stratum([4], k=1).odd_component() sage: len(H4_odd.origamis(6)) 155 sage: T6 = H4_odd.arithmetic_teichmueller_curves(6) sage: sum(t.veech_group().index() for t in T6) 155
- permutation_representative(left_degree=None, reduced=True, alphabet=None, relabel=True)[source]¶
Returns the Zorich representative of this connected component.
Zorich constructs explicitly interval exchange transformations for each stratum in [Zor08].
INPUT:
reduced
- boolean (default:True
): whether you obtain a reduced or labelled permutationalphabet
- an alphabet orNone
: whether you want to specify an alphabet for your permutationleft_degree
- the degree of the singularity on the left of the interval.
OUTPUT:
permutation – a permutation which lives in this component
EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([1,1,1,1], k=1).unique_component() sage: p = c.permutation_representative(alphabet="abcdefghi") sage: p a b c d e f g h i e d c f i h g b a sage: p.stratum_component() H_3(1^4)^c sage: cc = Stratum([3,2,1,0], k=1).unique_component() sage: p = cc.permutation_representative(left_degree=3); p 0 1 2 3 4 5 6 7 8 9 10 4 3 7 6 5 10 9 8 2 0 1 sage: p.stratum_component() H_4(3, 2, 1, 0)^c sage: p.marking().left() 4 sage: p.rauzy_diagram() # not tested Rauzy diagram with 1060774 permutations sage: p = cc.permutation_representative(left_degree=2); p 0 1 2 3 4 5 6 7 8 9 10 4 3 5 7 6 10 9 8 2 0 1 sage: p.stratum_component() H_4(3, 2, 1, 0)^c sage: p.marking().left() 3 sage: p.rauzy_diagram() # not tested Rauzy diagram with 792066 permutations sage: p = cc.permutation_representative(left_degree=1); p 0 1 2 3 4 5 6 7 8 9 10 5 4 3 7 6 8 10 9 2 0 1 sage: p.stratum_component() H_4(3, 2, 1, 0)^c sage: p.marking().left() 2 sage: p.rauzy_diagram() # not tested Rauzy diagram with 538494 permutations sage: p = cc.permutation_representative(left_degree=0); p 0 1 2 3 4 5 6 7 8 9 10 4 2 7 6 5 10 9 8 1 3 0 sage: p.stratum_component() H_4(3, 2, 1, 0)^c sage: p.marking().left() 1 sage: p.rauzy_diagram() # not tested Rauzy diagram with 246914 permutations
- random_standard_permutation(nsteps=64)[source]¶
Perform a random walk on rauzy diagram stopped on a standard permutation.
INPUT:
nsteps
- integer or None - perform nsteps and then stops as soon as a Strebel differential is found.
At each step, with probability 1/3 we perform one of the following moves:
exchange top,bottom and left,right (proba 1/10)
top rauzy move (proba 9/20)
bot rauzy move (proba 9/20)
EXAMPLES:
sage: from surface_dynamics import Stratum
sage: C = Stratum([10], k=1).hyperelliptic_component() sage: p = C.random_standard_permutation(); p # random 0 1 2 3 4 5 6 7 8 9 10 11 11 10 9 8 7 6 5 4 3 2 1 0 sage: p.stratum_component() H_6(10)^hyp
sage: C = Stratum([6,4,2], k=1).odd_component(); C H_7(6, 4, 2)^odd sage: p = C.random_standard_permutation(); p # random 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 15 2 14 12 3 11 6 10 8 5 9 13 7 4 1 0 sage: p.stratum_component() H_7(6, 4, 2)^odd
sage: C = Stratum([2,2,2,2], k=1).even_component(); C H_5(2^4)^even sage: p = C.random_standard_permutation(); p # random 0 1 2 3 4 5 6 7 8 9 10 11 12 12 4 9 11 8 3 7 6 1 10 2 5 0 sage: p.stratum_component() H_5(2^4)^even
sage: C = Stratum([32], k=1).odd_component(); C H_17(32)^odd sage: p = C.random_standard_permutation(); p # random 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 33 30 10 3 32 19 11 28 4 14 24 15 21 20 9 12 25 6 2 29 26 23 27 13 8 1 18 17 16 31 7 22 5 0 sage: p.stratum_component() H_17(32)^odd
- rauzy_class_cardinality(left_degree=None, reduced=True)[source]¶
Rauzy diagram cardinality for connected components.
Returns the cardinality of the extended Rauzy diagram associated to this connected component.
If left_degree is provided then it returns the cardinality of the Rauzy diagram with a singularity of that degree attached on the left. Otherwise it returns the cardinality of the extended Rauzy diagram.
INPUT:
left_degree
- the degree to be attached to the singularity on the leftreduced
- boolean (default: True) - consider the cardinality of reduced or extended Rauzy diagram
EXAMPLES:
sage: from surface_dynamics import * sage: a = Stratum({1:4}, k=1).unique_component() sage: a H_3(1^4)^c sage: a.rauzy_diagram() Rauzy diagram with 1255 permutations sage: a.rauzy_class_cardinality() 1255 sage: cc = Stratum([3,2,1], k=1).unique_component() sage: cc.rauzy_diagram(left_degree=3) # long time Rauzy diagram with 96434 permutations sage: cc.rauzy_class_cardinality(left_degree=3) 96434 sage: cc.rauzy_diagram(left_degree=2) # long time Rauzy diagram with 72006 permutations sage: cc.rauzy_class_cardinality(left_degree=2) 72006 sage: cc.rauzy_diagram(left_degree=1) # long time Rauzy diagram with 48954 permutations sage: cc.rauzy_class_cardinality(left_degree=1) 48954 sage: a = Stratum({1:8}, k=1).unique_component() sage: a H_5(1^8)^c sage: a.rauzy_class_cardinality() 55184875
Cardinalities for labeled Rauzy classes instead of reduced:
sage: cc = Stratum([2,1,1], k=1).unique_component() sage: cc.rauzy_diagram(left_degree=2, reduced=False) Rauzy diagram with 3676 permutations sage: cc.rauzy_class_cardinality(left_degree=2, reduced=False) 3676 sage: cc.rauzy_diagram(left_degree=1, reduced=False) Rauzy diagram with 3774 permutations sage: cc.rauzy_class_cardinality(left_degree=1,reduced=False) 3774 sage: cc = Stratum([2,1,1,0], k=1).unique_component() sage: cc.rauzy_diagram(left_degree=2, reduced=False) # long time Rauzy diagram with 33084 permutations sage: cc.rauzy_diagram(left_degree=1, reduced=False) # long time Rauzy diagram with 33966 permutations sage: cc.rauzy_diagram(left_degree=0, reduced=False) # long time Rauzy diagram with 30828 permutations sage: cc.rauzy_class_cardinality(left_degree=2, reduced=False) 33084 sage: cc.rauzy_class_cardinality(left_degree=1, reduced=False) 33966 sage: cc.rauzy_class_cardinality(left_degree=0, reduced=False) 30828
- rauzy_diagram(*args, **kwds)[source]¶
Returns the extended Rauzy diagram associated to this connected component.
OUTPUT:
rauzy diagram – the Rauzy diagram associated to this stratum
EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([0], k=1).components()[0] sage: r = c.rauzy_diagram()
- single_cylinder_origami()[source]¶
Returns an origami associated to a single cylinder permutation representative.
Returns an origami in this connected (or non-hyperelliptic) component having a single vertical cylinder and a single horizontal cylinder.
Such representatives were constructed for every stratum of Abelian differentials by Jeffreys [Jef19].
Examples:
sage: from surface_dynamics import Stratum sage: cc = Stratum([4], k=1).odd_component() sage: O = cc.single_cylinder_origami() sage: O (1,2,3,4,5) (1,4,3,5,2) sage: O.stratum_component() == cc True sage: cc = Stratum([5,3], k=1).unique_component() sage: O = cc.single_cylinder_origami() sage: O (1,2,3,4,5,6,7,8,9,10) (1,9,8,10,6,7,4,3,5,2) sage: O.stratum_component() == cc True sage: cc = Stratum([4,2], k=1).even_component() sage: O = cc.single_cylinder_origami() sage: O (1,2,3,4,5,6,7,8) (1,3,7,5,6,8,4,2) sage: O.stratum_component() == cc True
- single_cylinder_representative(alphabet=None, reduced=True)[source]¶
Returns a single cylinder permutation representative.
Returns a cylindric permutation representative of this connected stratum (or non-hyperelliptic component) such that the associated square-tiled surface is made of a single cylinder of height one in both horizontal and vertical direction.
Such representatives were constructed for every stratum of Abelian differentials by Jeffreys [Jef19].
INPUT:
alphabet
– an optional alphabet for the permutation representativereduced
(boolean, defaultTrue
) – whether to return a reduced permutation (ie without labels)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: cc = Stratum([1,1,1,1], k=1).unique_component() sage: p = cc.single_cylinder_representative() sage: p 0 1 2 3 4 5 6 7 8 2 6 5 3 1 8 4 7 0 sage: p.stratum_component() == cc True sage: cc = Stratum([2,1,1], k=1).unique_component() sage: p = cc.single_cylinder_representative() sage: p 0 1 2 3 4 5 6 7 2 6 4 1 7 5 3 0 sage: p.stratum_component() == cc True sage: cc = Stratum([3,3], k=1).non_hyperelliptic_component() sage: p = cc.single_cylinder_representative(alphabet=Alphabet(name='lower')) sage: p a b c d e f g h i c i g f h e b d a sage: p.stratum_component() == cc True
- spin()[source]¶
Return
None
since surfaces in this component have no spin.EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([1,1,1,1], k=1).unique_component(); c H_3(1^4)^c sage: c.spin() is None True
- standard_permutations()[source]¶
Return the set of standard permutations.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: C = Stratum([4], k=1).odd_component() sage: C H_3(4)^odd sage: for p in C.standard_permutations(): print("%s\n***********" % p) 0 1 2 3 4 5 5 2 1 4 3 0 *********** 0 1 2 3 4 5 5 3 1 4 2 0 *********** 0 1 2 3 4 5 5 4 1 3 2 0 *********** 0 1 2 3 4 5 5 2 4 1 3 0 *********** 0 1 2 3 4 5 5 4 2 1 3 0 *********** 0 1 2 3 4 5 5 2 4 3 1 0 *********** 0 1 2 3 4 5 5 3 2 4 1 0 ***********
- standard_permutations_number(left_degree=None)[source]¶
Return the number of standard permutations in the Rauzy class associated to this connected component.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: cc = Stratum([3,1], k=1).unique_component() sage: sum(1 for p in cc.rauzy_diagram() if p.is_standard()) 24 sage: cc.standard_permutations_number() 24 sage: sum(1 for p in cc.rauzy_diagram(left_degree=3) if p.is_standard()) 16 sage: cc.standard_permutations_number(left_degree=3) 16 sage: sum(1 for p in cc.rauzy_diagram(left_degree=1) if p.is_standard()) 8 sage: cc.standard_permutations_number(left_degree=1) 8 sage: cc = Stratum({1:10}, k=1).unique_component() sage: cc H_6(1^10)^c sage: cc.standard_permutations_number() 59520825
- surface_dynamics.flat_surfaces.abelian_strata.EvenASC¶
alias of
EvenAbelianStratumComponent
- class surface_dynamics.flat_surfaces.abelian_strata.EvenAbelianStratumComponent(stratum)[source]¶
Bases:
AbelianStratumComponent
Connected component of Abelian stratum with even spin structure.
Warning
Internal class! Do not use directly!
- permutation_representative(left_degree=None, reduced=True, alphabet=None, relabel=True)[source]¶
Returns the Zorich representative of this connected component.
Zorich constructs explicitly interval exchange transformations for each stratum in [Zor08].
INPUT:
reduced
- boolean (default: True): whether you obtain a reduced or labelled permutationleft_degree
- integer (optional) - a specified degree of zero at the left of the interval.alphabet
- alphabet or None (default: None): whether you want to specify an alphabet for your representativerelabel
- boolean (default: True) - if False uses Zorich’s natural numbering otherwise uses 0,1,…
EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([6], k=1).even_component() sage: c H_4(6)^even sage: p = c.permutation_representative(alphabet=range(8)) sage: p 0 1 2 3 4 5 6 7 5 4 3 2 7 6 1 0 sage: p.stratum_component() H_4(6)^even
sage: c = Stratum([4,4], k=1).even_component() sage: c H_5(4^2)^even sage: p = c.permutation_representative(alphabet=range(11)) sage: p 0 1 2 3 4 5 6 7 8 9 10 5 4 3 2 6 8 7 10 9 1 0 sage: p.stratum_component() H_5(4^2)^even
Different markings lead to different Rauzy diagrams:
sage: c = Stratum([4,2,0], k=1).even_component() sage: p = c.permutation_representative(left_degree=4); p 0 1 2 3 4 5 6 7 8 9 6 5 4 3 7 9 8 2 0 1 sage: p.stratum_component() H_4(4, 2, 0)^even sage: p.marking().left() 5 sage: p.rauzy_diagram() # long time Rauzy diagram with 66140 permutations sage: p = c.permutation_representative(left_degree=2); p 0 1 2 3 4 5 6 7 8 9 7 6 5 4 3 9 8 2 0 1 sage: p.stratum_component() H_4(4, 2, 0)^even sage: p.marking().left() 3 sage: p.rauzy_diagram() # long time Rauzy diagram with 39540 permutations sage: p = c.permutation_representative(left_degree=0); p 0 1 2 3 4 5 6 7 8 9 6 4 3 2 7 9 8 1 5 0 sage: p.stratum_component() H_4(4, 2, 0)^even sage: p.marking().left() 1 sage: p.rauzy_diagram() # long time Rauzy diagram with 11792 permutations
- rauzy_class_cardinality(left_degree=None, reduced=True)[source]¶
Cardinality of rauzy diagram for even component of a stratum
INPUT:
left_degree
- integerreduced
- boolean
EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([6], k=1).even_component() sage: c.rauzy_diagram() Rauzy diagram with 2327 permutations sage: c.rauzy_class_cardinality() 2327 sage: c = Stratum([4,2,0], k=1).even_component() sage: c.rauzy_class_cardinality() 117472 sage: c.rauzy_diagram(left_degree=4) # long time Rauzy diagram with 66140 permutations sage: c.rauzy_class_cardinality(left_degree=4) 66140 sage: c.rauzy_diagram(left_degree=4, reduced=False) # long time Rauzy diagram with 198420 permutations sage: c.rauzy_class_cardinality(left_degree=4,reduced=False) 198420 sage: c.rauzy_class_cardinality(2) 39540 sage: c.rauzy_diagram(left_degree=2) # long time Rauzy diagram with 39540 permutations sage: c.rauzy_diagram(left_degree=2, reduced=False) # long time Rauzy diagram with 197700 permutations sage: c.rauzy_class_cardinality(left_degree=2, reduced=False) 197700 sage: c.rauzy_class_cardinality(0) 11792 sage: c.rauzy_diagram(left_degree=0) Rauzy diagram with 11792 permutations sage: c.rauzy_diagram(left_degree=0, reduced=False) # long time Rauzy diagram with 176880 permutations sage: c.rauzy_class_cardinality(left_degree=0, reduced=False) 176880
- single_cylinder_representative(alphabet=None, reduced=False)[source]¶
Returns a single cylinder permutation representative.
Returns a permutation representative of a square-tiled surface in this component having a single vertical cylinder and a single horizontal cylinder.
Such representatives were constructed for every stratum of Abelian differentials by Jeffreys [Jef19].
INPUT:
alphabet
– an optional alphabet for the permutation representativereduced
(boolean, defaultTrue
) – whether to return a reduced permutation (ie without labels)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: cc = Stratum([6], k=1).even_component() sage: p = cc.single_cylinder_representative(alphabet=Alphabet(name='lower')) sage: p a b c d e f g h c h g f d b e a sage: p.stratum_component() == cc True sage: cc = Stratum([4,4], k=1).even_component() sage: p = cc.single_cylinder_representative() sage: p 0 1 2 3 4 5 6 7 8 9 10 2 10 7 5 8 1 9 6 4 3 0 sage: p.stratum_component() == cc True
- spin()[source]¶
Return
0
.EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([4,2], k=1).even_component(); c H_4(4, 2)^even sage: c.spin() 0
- standard_permutations_number()[source]¶
Return the number of standard permutation of this even component.
EXAMPLES:
sage: from surface_dynamics import Stratum
For strata in genus 3, the number of standard permutations is reasonably small and the whole set can be computed:
sage: C = Stratum([6], k=1).even_component() sage: len(C.standard_permutations()) # long time 44 sage: C.standard_permutations_number() 44 sage: C = Stratum([4,2], k=1).even_component() sage: len(C.standard_permutations()) # long time 136 sage: C.standard_permutations_number() 136 sage: C = Stratum([2,2,2], k=1).even_component() sage: len(C.standard_permutations()) # long time 92 sage: C.standard_permutations_number() 92
For higher genera, this number can be very big:
sage: C = Stratum([20], k=1).even_component() sage: C.standard_permutations_number() 109398514483439999
- surface_dynamics.flat_surfaces.abelian_strata.HypASC¶
alias of
HypAbelianStratumComponent
- class surface_dynamics.flat_surfaces.abelian_strata.HypAbelianStratumComponent(stratum)[source]¶
Bases:
AbelianStratumComponent
Hyperelliptic component of Abelian stratum.
- permutation_representative(left_degree=None, reduced=True, alphabet=None, relabel=True)[source]¶
Returns the Zorich representative of this connected component.
Zorich constructs explicitly interval exchange transformations for each stratum in [Zor08].
INPUT:
reduced
- boolean (default:True
): whether you obtain a reduced or labelled permutationalphabet
- alphabet orNone
(default:None
): whether you want to specify an alphabet for your representative
EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([0], k=1).hyperelliptic_component() sage: p = c.permutation_representative() sage: p 0 1 1 0 sage: p.stratum_component() H_1(0)^hyp sage: c = Stratum([0,0], k=1).hyperelliptic_component() sage: p = c.permutation_representative(alphabet="abc") sage: p a b c c b a sage: p.stratum_component() H_1(0^2)^hyp sage: c = Stratum([2,2], k=1).hyperelliptic_component() sage: p = c.permutation_representative(alphabet="ABCDEFGHIJKL") sage: p A B C D E F G G F E D C B A sage: c = Stratum([1,1,0], k=1).hyperelliptic_component() sage: p = c.permutation_representative(left_degree=1); p 0 1 2 3 4 5 5 1 4 3 2 0 sage: p.marking().left() 2 sage: p.rauzy_diagram() Rauzy diagram with 90 permutations sage: p = c.permutation_representative(left_degree=0); p 0 1 2 3 4 5 5 3 2 1 4 0 sage: p.marking().left() 1 sage: p.rauzy_diagram() Rauzy diagram with 20 permutations
- random_standard_permutation(nsteps=None)[source]¶
In hyperelliptic component there is only one standard permutation.
- rauzy_class_cardinality(left_degree=None, reduced=True)[source]¶
Return the cardinality of the extended Rauzy diagram associated to the hyperelliptic component
The cardinality of the Rauzy diagram or extended Rauzy diagram associated to H_{hyp}(2g-2,0^k) or H_{hyp}(g-1,g-1,0^k) depends only on the dimension d of the initial stratum mathcal{H}_{hyp}(2g-2) for which d=2g or mathcal{H}_{hyp}(g-1,g-1) for which d=2g+1 and the number of fake zeros k. The formula is
\[\binom{d+k+1}{k} (2^{d-1}-1) + d \binom{d+k}{k-1}\]INPUT:
left_degree
- integer - the degree of the singularity attached at the left of the interval.reduced
- boolean (default: True) - if False, consider labeled Rauzy diagrams instead of reduced.
EXAMPLES:
sage: from surface_dynamics import Stratum
The case of the torus is a little bit different:
sage: c = Stratum([0], k=1).hyperelliptic_component() sage: c.rauzy_diagram() Rauzy diagram with 1 permutation sage: c.rauzy_class_cardinality() 1 sage: c = Stratum([0,0], k=1).hyperelliptic_component() sage: c.rauzy_diagram() Rauzy diagram with 3 permutations sage: c.rauzy_class_cardinality() 3
Examples in genus 2:
sage: c = Stratum([2,0], k=1).hyperelliptic_component() sage: c.rauzy_diagram() Rauzy diagram with 46 permutations sage: c.rauzy_class_cardinality() 46 sage: c.rauzy_diagram(left_degree=2) Rauzy diagram with 35 permutations sage: c.rauzy_class_cardinality(left_degree=2) 35 sage: c.rauzy_diagram(left_degree=0) Rauzy diagram with 11 permutations sage: c.rauzy_class_cardinality(left_degree=0) 11 sage: c.rauzy_diagram(left_degree=0, reduced=False) Rauzy diagram with 33 permutations sage: c.rauzy_class_cardinality(left_degree=0, reduced=False) 33 sage: c = Stratum([1,1,0,0], k=1).hyperelliptic_component() sage: c.rauzy_diagram() Rauzy diagram with 455 permutations sage: c.rauzy_class_cardinality() 455 sage: c.rauzy_diagram(left_degree=1) Rauzy diagram with 315 permutations sage: c.rauzy_class_cardinality(left_degree=1) 315 sage: c.rauzy_diagram(left_degree=1, reduced=False) Rauzy diagram with 630 permutations sage: c.rauzy_class_cardinality(left_degree=1, reduced=False) 630 sage: c.rauzy_diagram(left_degree=0) Rauzy diagram with 140 permutations sage: c.rauzy_class_cardinality(left_degree=0) 140 sage: c.rauzy_diagram(left_degree=0, reduced=False) Rauzy diagram with 560 permutations sage: c.rauzy_class_cardinality(left_degree=0, reduced=False) 560
Other examples in higher genus:
sage: c = Stratum([12,0,0], k=1).hyperelliptic_component() sage: c.rauzy_class_cardinality() 1114200 sage: c.rauzy_class_cardinality(left_degree=12, reduced=False) 1965840 sage: c = Stratum([14], k=1).hyperelliptic_component() sage: c.rauzy_class_cardinality() 32767
- single_cylinder_representative(alphabet=None, reduced=True)[source]¶
Returns a single cylinder permutation representative.
Returns a permutation representative of a square-tiled surface in this component having a single vertical cylinder and a single horizontal cylinder.
Such representatives were constructed for every stratum of Abelian differentials by Jeffreys [Jef19].
INPUT:
alphabet
– an optional alphabet for the permutation representativereduced
(boolean, defaultTrue
) – whether to return a reduced permutation (ie without labels)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: cc = Stratum([2,0], k=1).hyperelliptic_component() sage: p = cc.single_cylinder_representative(alphabet=Alphabet(name='upper')) sage: p A B C D E E D B C A sage: p.stratum_component() == cc True sage: cc = Stratum({3:2,0:6}, k=1).hyperelliptic_component() sage: p = cc.single_cylinder_representative() sage: p 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 14 12 13 10 11 8 9 7 5 6 3 4 1 2 0 sage: p.stratum_component() == cc True sage: cc = Stratum([2], k=1).hyperelliptic_component() sage: cc.single_cylinder_representative() Traceback (most recent call last): ... ValueError: no 1,1-square-tiled surfaces in this connected component try again with H_2(2, 0)^hyp sage: cc = Stratum({3:2,0:5}, k=1).hyperelliptic_component() sage: cc.single_cylinder_representative() Traceback (most recent call last): ... ValueError: no 1,1-square-tiled surfaces in this connected component try again with H_4(3^2, 0^6)^hyp
- spin()[source]¶
Return the spin parity of hyperelliptic stratum.
EXAMPLES:
sage: from surface_dynamics import Stratum
For the strata H(2g-2):
sage: c = Stratum([0], k=1).hyperelliptic_component() sage: c.spin() 1 sage: p = c.permutation_representative() sage: p.arf_invariant() 1 sage: c = Stratum([2], k=1).hyperelliptic_component() sage: c.spin() 1 sage: p = c.permutation_representative() sage: p.arf_invariant() 1 sage: c = Stratum([4], k=1).hyperelliptic_component() sage: c.spin() 0 sage: p = c.permutation_representative() sage: p.arf_invariant() 0
For the strata H(g-1,g-1):
sage: c = Stratum([2,2], k=1).hyperelliptic_component() sage: c.spin() 0 sage: p = c.permutation_representative() sage: p.arf_invariant() 0 sage: c = Stratum([4,4], k=1).hyperelliptic_component() sage: c.spin() 1 sage: p = c.permutation_representative() sage: p.arf_invariant() 1
- surface_dynamics.flat_surfaces.abelian_strata.NonHypASC¶
alias of
NonHypAbelianStratumComponent
- class surface_dynamics.flat_surfaces.abelian_strata.NonHypAbelianStratumComponent(stratum)[source]¶
Bases:
AbelianStratumComponent
Non hyperelliptic component of Abelian stratum.
- rauzy_class_cardinality(left_degree=None, reduced=True)[source]¶
Return the cardinality of Rauzy diagram associated to this non hyperelliptic component.
INPUT:
left_degree
- integerreduced
- boolean (default: True)
EXAMPLES:
sage: from surface_dynamics import Stratum
Examples in genus 3:
sage: c = Stratum([3,3], k=1).non_hyperelliptic_component() sage: c.rauzy_class_cardinality() 15568 sage: c = Stratum([3,3,0], k=1).non_hyperelliptic_component() sage: c.rauzy_class_cardinality() 173723 sage: c.rauzy_diagram(left_degree=3) # long time Rauzy diagram with 155680 permutations sage: c.rauzy_class_cardinality(left_degree=3) 155680 sage: c.rauzy_diagram(left_degree=3, reduced=False) # not tested Rauzy diagram with 311360 permutations sage: c.rauzy_class_cardinality(left_degree=3, reduced=False) 311360 sage: c.rauzy_diagram(left_degree=0) # long time Rauzy diagram with 18043 permutations sage: c.rauzy_class_cardinality(left_degree=0) 18043 sage: cc.rauzy_diagram(left_degree=0, reduced=False) # not tested Rauzy diagram with 288688 permutations sage: c.rauzy_class_cardinality(left_degree=0,reduced=False) 288688
When genus growths, the size of the Rauzy diagram becomes very big:
sage: c = Stratum([5,5], k=1).non_hyperelliptic_component() sage: c.rauzy_class_cardinality() 136116680 sage: c = Stratum([7,7,0], k=1).non_hyperelliptic_component() sage: c.rauzy_class_cardinality() 88484743236111 sage: c.rauzy_class_cardinality(left_degree=7, reduced=False) 334071852804864
- standard_permutations_number()[source]¶
EXAMPLES:
sage: from surface_dynamics import Stratum sage: C = Stratum([3,3], k=1).non_hyperelliptic_component() sage: len(C.standard_permutations()) # long time 275 sage: C.standard_permutations_number() 275 sage: C = Stratum([5,5], k=1).non_hyperelliptic_component() sage: C.standard_permutations_number() 1022399 sage: C = Stratum([7,7], k=1).non_hyperelliptic_component() sage: C.standard_permutations_number() 19229011199
- surface_dynamics.flat_surfaces.abelian_strata.OddASC¶
alias of
OddAbelianStratumComponent
- class surface_dynamics.flat_surfaces.abelian_strata.OddAbelianStratumComponent(stratum)[source]¶
Bases:
AbelianStratumComponent
Connected component of an Abelian stratum with odd spin parity.
- permutation_representative(left_degree=None, reduced=True, alphabet=None, relabel=True)[source]¶
Returns the Zorich representative of this connected component.
A. Zorich constructs explicitly interval exchange transformations for each stratum in [Zor08].
EXAMPLES:
sage: from surface_dynamics import Stratum sage: a = Stratum([6], k=1).odd_component() sage: p = a.permutation_representative() sage: p 0 1 2 3 4 5 6 7 3 2 5 4 7 6 1 0 sage: p.stratum_component() H_4(6)^odd
sage: a = Stratum([4,4], k=1).odd_component() sage: p = a.permutation_representative() sage: p 0 1 2 3 4 5 6 7 8 9 10 3 2 5 4 6 8 7 10 9 1 0 sage: p.stratum_component() H_5(4^2)^odd
Different markings lead to different Rauzy diagrams:
sage: c = Stratum([4,2,0], k=1).odd_component() sage: p = c.permutation_representative(left_degree=4); p 0 1 2 3 4 5 6 7 8 9 4 3 6 5 7 9 8 2 0 1 sage: p.stratum_component() H_4(4, 2, 0)^odd sage: p.marking().left() 5 sage: p.rauzy_diagram() # not tested Rauzy diagram with 147090 permutations sage: p = c.permutation_representative(left_degree=2); p 0 1 2 3 4 5 6 7 8 9 4 3 5 7 6 9 8 2 0 1 sage: p.stratum_component() H_4(4, 2, 0)^odd sage: p.marking().left() 3 sage: p.rauzy_diagram() # long time Rauzy diagram with 87970 permutations sage: p = c.permutation_representative(left_degree=0); p 0 1 2 3 4 5 6 7 8 9 4 2 6 5 7 9 8 1 3 0 sage: p.stratum_component() H_4(4, 2, 0)^odd sage: p.marking().left() 1 sage: p.rauzy_diagram() # long time Rauzy diagram with 27754 permutations
- rauzy_class_cardinality(left_degree=None, reduced=True)[source]¶
Cardinality of rauzy diagram for odd component
INPUT:
left_degree
- integer (optional)reduced
- boolean (default: True)
EXAMPLES:
sage: from surface_dynamics import Stratum
The genus must be at least 3 to have an odd component:
sage: c = Stratum([4], k=1).odd_component() sage: c.rauzy_diagram() Rauzy diagram with 134 permutations sage: c.rauzy_class_cardinality() 134 sage: c = Stratum([4,0], k=1).odd_component() sage: c.rauzy_diagram() Rauzy diagram with 1114 permutations sage: c.rauzy_class_cardinality() 1114 sage: c = Stratum([2,2], k=1).odd_component() sage: c.rauzy_diagram() Rauzy diagram with 294 permutations sage: c.rauzy_class_cardinality() 294 sage: c = Stratum([2,2,0], k=1).odd_component() sage: c.rauzy_class_cardinality() 2723 sage: c.rauzy_diagram(left_degree=2) Rauzy diagram with 2352 permutations sage: c.rauzy_class_cardinality(left_degree=2) 2352 sage: c.rauzy_diagram(left_degree=2, reduced=False) Rauzy diagram with 7056 permutations sage: c.rauzy_class_cardinality(left_degree=2, reduced=False) 7056 sage: c.rauzy_diagram(left_degree=0) Rauzy diagram with 371 permutations sage: c.rauzy_class_cardinality(left_degree=0) 371 sage: c.rauzy_diagram(left_degree=0, reduced=False) Rauzy diagram with 6678 permutations sage: c.rauzy_class_cardinality(left_degree=0, reduced=False) 6678
Example in higher genus for which an explicit computation of the Rauzy diagram would be very long:
sage: c = Stratum([4,2,0], k=1).odd_component() sage: c.rauzy_class_cardinality() 262814 sage: c = Stratum([4,4,4], k=1).odd_component() sage: c.rauzy_class_cardinality() 24691288838 sage: c.rauzy_class_cardinality(left_degree=4, reduced=False) 1234564441900
- single_cylinder_representative(alphabet=None, reduced=True)[source]¶
Returns a single cylinder permutation representative.
Returns a permutation representative of a square-tiled surface in this component having a single vertical cylinder and a single horizontal cylinder.
Such representatives were constructed for every stratum of Abelian differentials by Jeffreys [Jef19].
INPUT:
alphabet
– an optional alphabet for the permutation representativereduced
(boolean, defaultTrue
) – whether to return a reduced permutation (ie without labels)
EXAMPLES:
sage: from surface_dynamics import Stratum sage: cc = Stratum([4], k=1).odd_component() sage: p = cc.single_cylinder_representative(alphabet=Alphabet(name='upper')) sage: p A B C D E F C F E B D A sage: p.stratum_component() == cc True sage: cc = Stratum([6,2], k=1).odd_component() sage: p = cc.single_cylinder_representative() sage: p 0 1 2 3 4 5 6 7 8 9 10 2 5 4 6 3 8 10 7 1 9 0 sage: p.stratum_component() == cc True
- spin()[source]¶
Returns 1 which is, by definition, the spin parity of this stratum component.
EXAMPLES:
sage: from surface_dynamics import Stratum sage: c = Stratum([4], k=1).odd_component(); c H_3(4)^odd sage: c.spin() 1
- standard_permutations_number()[source]¶
Return the number of standard permutation of this even component.
EXAMPLES:
sage: from surface_dynamics import Stratum
In genus 2, there are two strata which contains an odd component:
sage: C = Stratum([4], k=1).odd_component() sage: len(C.standard_permutations()) 7 sage: C.standard_permutations_number() 7 sage: C = Stratum([2,2], k=1).odd_component() sage: len(C.standard_permutations()) 11 sage: C.standard_permutations_number() 11
In genus 3, the number of standard permutations is reasonably small and the whole set can be computed:
sage: C = Stratum([6], k=1).odd_component() sage: len(C.standard_permutations()) # long time 135 sage: C.standard_permutations_number() 135 sage: C = Stratum([4,2], k=1).odd_component() sage: len(C.standard_permutations()) # long time 472 sage: C.standard_permutations_number() 472 sage: C = Stratum([2,2,2], k=1).odd_component() sage: len(C.standard_permutations()) # long time 372 sage: C.standard_permutations_number() 372
For higher genera, this number can be very big:
sage: C = Stratum([8,6,4,2], k=1).odd_component() sage: C.standard_permutations_number() 26596699869748377600
Quadratic strata¶
Strata of quadratic differentials on Riemann surfaces
More precisely, we are interested in meromorphic quadratic differentials with at most simple poles on closed compact connected Riemann surfaces, which are not globally the square of an abelian differential.
The moduli space of such quadratic differentials on Riemann surfaces of a given genus is a complex orbifold, stratified by the degrees of zeros (zeros of degree -1, or simple poles, being allowed). The strata themselves are complex orbifolds. Most strata are connected but some (infinitely many) are not.
A stratum corresponds to the Sage object
QuadraticStratum
.
The classification of connected components of strata of quadratic differentials was established by Erwan Lanneau in [Lan08], after a similar classification was established by Kontsevich and Zorich in [KonZor03] in the Abelian case.
Each stratum has one or two connected components and each
component is associated to an extended Rauzy class. The
components()
method gives the decomposition of a stratum into its connected components.
A representative for each connected component of stratum is given by Zorich in [Zor08].
This is implemented here following [Zor08]:
genus zero stratum
permutation_representative()
genus one stratum
permutation_representative()
genus two hyperellitic component
permutation_representative()
genus two non-hyperellitic component
permutation_representative()
connected component
permutation_representative()
hyperelliptic component
permutation_representative()
non-hyperelliptic component is similar to connected components
regular component of exceptional stratum
permutation_representative()
irregular component of exceptional stratum
permutation_representative()
The inverse operation, i.e., starting from a permutation, determine
the connected component it lives in, is partially written in [KonZor03].
See:
stratum_component()
.
The code here implements the descriptions in [Zor08]. Zorich already implemented all this for Mathematica in [ZS].
See also abelian_strata
for Abelian strata.
AUTHORS:
Vincent Delecroix (2009-09-29): initial version
Samuel Lelievre (2010-10-08): quadratic strata
EXAMPLES:
sage: from surface_dynamics import *
Construction of a stratum from a list of singularity degrees:
sage: a = Stratum([2,2], k=2)
sage: a
Q_2(2^2)
sage: a.surface_genus()
2
sage: a = Stratum([4,3,2,2,1], k=2)
sage: a
Q_4(4, 3, 2^2, 1)
sage: a.surface_genus()
4
By convention, the degrees are always written in decreasing order:
sage: a1 = Stratum([7,5,3,1], k=2)
sage: a1
Q_5(7, 5, 3, 1)
sage: a2 = Stratum([3,1,7,5], k=2)
sage: a2
Q_5(7, 5, 3, 1)
sage: a1 == a2
True
List the connected components of a stratum:
sage: a = Stratum([6,2], k=2)
sage: a.components()
(Q_3(6, 2)^hyp, Q_3(6, 2)^nonhyp)
sage: a = Stratum([12], k=2)
sage: cc = a.components()
sage: cc
(Q_4(12)^reg, Q_4(12)^irr)
sage: for c in cc:
....: print(c)
....: print(c.permutation_representative())
Q_4(12)^reg
0 1 2 1 2 3 4 3 4 5
5 6 7 6 7 0
Q_4(12)^irr
0 1 2 3 4 5 6 5
7 6 4 7 3 2 1 0
sage: a = Stratum([1, 1, 1, 1], k=2)
sage: a.components()
(Q_2(1^4)^hyp,)
sage: c = a.components()[0]
sage: p = c.permutation_representative(); p
0 1 2 3 1 4 5
2 6 5 4 6 3 0
- surface_dynamics.flat_surfaces.quadratic_strata.CQSC¶
alias of
ConnectedQuadraticStratumComponent
- class surface_dynamics.flat_surfaces.quadratic_strata.ConnectedQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
Connected component of stratum of quadratic differentials.
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- permutation_representative(reduced=True, alphabet=None, relabel=True)[source]¶
Returns a generalized permutation representative.
NOTES:
The representative is made by constructing two lists l0 and l1 which correspond to a generalized permutation representative for the stratum with simple zeros, and then erasing some elements from l0 and l1 (this corresponds to collapsing saddle connections to merge zeros). It may be possible to find a faster way to obtain the desired l0 and l1 than by constructing the long versions and erasing symbols; the current implementation has a loop with “del l0[l0.index(i)]” and “del l1[l1.index(i)]”.
EXAMPLES:
sage: from surface_dynamics import * sage: cc = Stratum([6,-1,-1], k=2).non_hyperelliptic_component() sage: p = cc.permutation_representative(); p 0 1 2 1 3 3 4 4 5 5 2 0 sage: p.stratum_component() Q_2(6, -1^2)^nonhyp sage: cc = Stratum({3: 2, -1: 2}, k=2).non_hyperelliptic_component() sage: p = cc.permutation_representative(); p 0 1 2 1 3 4 3 5 5 4 6 6 2 0 sage: p.stratum_component() Q_2(3^2, -1^2)^nonhyp sage: cc = Stratum([8], k=2).unique_component() sage: p = cc.permutation_representative(); p 0 1 2 1 2 3 4 5 4 5 3 0 sage: p.stratum_component() Q_3(8)^c sage: Q = Stratum([4,4], k=2).unique_component() sage: p = Q.permutation_representative(); p 0 1 2 3 2 3 4 5 6 5 6 1 4 0 sage: p.stratum_component() Q_3(4^2)^c sage: Q = Stratum({12:1,-1:4}, k=2).unique_component() sage: p = Q.permutation_representative() sage: p 0 1 2 1 2 3 3 4 4 5 5 6 6 7 8 9 8 9 7 0 sage: p.stratum() Q_3(12, -1^4)
- surface_dynamics.flat_surfaces.quadratic_strata.DeprecatedQuadraticStratumConstructor(*l, **kwds)[source]¶
- surface_dynamics.flat_surfaces.quadratic_strata.GOQSC¶
alias of
GenusOneQuadraticStratumComponent
- surface_dynamics.flat_surfaces.quadratic_strata.GTHQSC¶
- surface_dynamics.flat_surfaces.quadratic_strata.GTNQSC¶
- surface_dynamics.flat_surfaces.quadratic_strata.GZQSC¶
alias of
GenusZeroQuadraticStratumComponent
- class surface_dynamics.flat_surfaces.quadratic_strata.GenusOneQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- permutation_representative(reduced=True, alphabet=None, relabel=True)[source]¶
Returns a generalized permutation representative.
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum({2: 1, -1: 2}, k=2).permutation_representative() 0 1 2 2 1 3 3 0 sage: Stratum({3: 1, -1: 3}, k=2).permutation_representative() 0 1 2 2 3 3 1 4 4 0 sage: Stratum({1: 2, -1: 2}, k=2).permutation_representative() 0 1 2 3 3 2 1 4 4 0 sage: Q = Stratum({2: 1, 1: 1, -1: 3}, k=2) sage: Q.permutation_representative(alphabet='abcdef') a b c c d e e d b f f a
- class surface_dynamics.flat_surfaces.quadratic_strata.GenusTwoHyperellipticQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- class surface_dynamics.flat_surfaces.quadratic_strata.GenusTwoNonhyperellipticQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- class surface_dynamics.flat_surfaces.quadratic_strata.GenusZeroQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- permutation_representative(reduced=True, alphabet=None, relabel=True)[source]¶
Returns a generalized permutation representative.
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([-1,-1,-1,-1], k=2).permutation_representative() 0 1 1 2 2 0 sage: Stratum({1:1, -1:5}, k=2).permutation_representative() 0 1 1 2 2 3 3 4 4 0 sage: Stratum({2:1, -1:6}, k=2).permutation_representative() 0 1 1 2 2 3 3 4 4 5 5 0 sage: Stratum({1:2, -1:6}, k=2).permutation_representative() 0 1 1 2 2 3 4 4 5 5 3 6 6 0 sage: Stratum({2:1, 1:1, -1:7}, k=2).permutation_representative() 0 1 1 2 2 3 3 4 5 5 6 6 4 7 7 0
- surface_dynamics.flat_surfaces.quadratic_strata.HQSC¶
- class surface_dynamics.flat_surfaces.quadratic_strata.HyperellipticQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- permutation_representative(reduced=True, alphabet=None, relabel=True)[source]¶
Returns a generalized permutation representative.
EXAMPLES:
sage: from surface_dynamics import * sage: cc = Stratum({6:1, -1:2}, k=2).hyperelliptic_component() sage: cc.permutation_representative() 0 1 2 3 4 1 5 4 3 2 5 0 sage: cc = Stratum({3: 2, -1: 2}, k=2).hyperelliptic_component() sage: cc.permutation_representative() 0 1 2 3 4 5 1 6 5 4 3 2 6 0 sage: cc = Stratum([10,10], k=2).hyperelliptic_component() sage: cc.permutation_representative() 0 1 2 3 4 5 6 1 7 8 9 10 11 11 10 9 8 7 12 6 5 4 3 2 12 0
- surface_dynamics.flat_surfaces.quadratic_strata.IEQSC¶
- class surface_dynamics.flat_surfaces.quadratic_strata.IrregularExceptionalQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- permutation_representative(reduced=True, alphabet=None, relabel=True)[source]¶
Returns a generalized permutation representative.
EXAMPLES:
sage: from surface_dynamics import * sage: cc = Stratum([9,-1], k=2).irregular_component() sage: p = cc.permutation_representative(); p 0 1 2 3 4 1 2 3 4 5 5 6 6 0 sage: p.stratum_component() # optional Q_3(9, -1)^irr sage: cc = Stratum([6,3,-1], k=2).irregular_component() sage: p = cc.permutation_representative(); p 0 1 2 3 4 5 1 2 3 4 5 6 6 7 7 0 sage: p.stratum_component() Q_3(6, 3, -1)^irr sage: cc = Stratum([12], k=2).irregular_component() sage: p = cc.permutation_representative(); p 0 1 2 3 4 5 6 5 7 6 4 7 3 2 1 0 sage: p.stratum_component() Q_4(12)^irr
- surface_dynamics.flat_surfaces.quadratic_strata.NQSC¶
- class surface_dynamics.flat_surfaces.quadratic_strata.NonhyperellipticQuadraticStratumComponent(stratum)[source]¶
Bases:
ConnectedQuadraticStratumComponent
Non hyperelliptic component of stratum of quadratic differentials.
- surface_dynamics.flat_surfaces.quadratic_strata.QSC¶
alias of
QuadraticStratumComponent
- surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStrata(genus=None, dimension=None, min_nb_poles=None, max_nb_poles=None, nb_poles=None, fake_zeros=False)[source]¶
Quadratic strata.
INPUT:
genus
- a non negative integer or Nonedimension
- a non negative integer or Nonemin_nb_poles
,max_nb_poles
- the minimum and maximum number of poles allowednb_poles
- integer - the number of poles (if the option is set then the optionsmin_nb_poles
andmax_nb_poles
are ignored)fake_zeros
- boolean - whether to allow fake zeros or not
EXAMPLES:
sage: from surface_dynamics import * sage: Q = QuadraticStrata(genus=2); Q Quadratic strata of genus 2 surfaces sage: Q.cardinality() +Infinity sage: i = iter(Q) sage: next(i) Q_2(2^2) sage: next(i) Q_2(2, 1^2) sage: next(i) Q_2(1^4) sage: next(i) Q_2(5, -1) sage: Q = QuadraticStrata(dimension=5); Q Quadratic strata of dimension 5 sage: Q = QuadraticStrata(genus=3,max_nb_poles=6); Q Quadratic strata of genus 3 surfaces with at most 6 poles sage: Q.cardinality() 463 sage: for q in Q: print(q) Q_3(8) Q_3(7, 1) Q_3(6, 2) ... Q_3(2^2, 1^10, -1^6) Q_3(2, 1^12, -1^6) Q_3(1^14, -1^6) sage: Q = QuadraticStrata(genus=2,nb_poles=0); Q Quadratic strata of genus 2 surfaces with no pole sage: for q in Q: print(q) Q_2(2^2) Q_2(2, 1^2) Q_2(1^4) sage: Q = QuadraticStrata(dimension=7,min_nb_poles=1,max_nb_poles=3); Q Quadratic strata of dimension 7 with at least 1 and at most 3 poles sage: for q in Q: print(q) Q_3(8, 1, -1) Q_3(7, 2, -1) Q_3(6, 3, -1) Q_3(5, 4, -1) Q_2(2, 1^3, -1) Q_3(10, -1^2) Q_2(4, 1^2, -1^2) Q_2(3, 2, 1, -1^2) Q_2(2^3, -1^2) Q_2(6, 1, -1^3) Q_2(5, 2, -1^3) Q_2(4, 3, -1^3) sage: Q = QuadraticStrata(dimension=6, genus=0) sage: Q Quadratic strata of genus 0 surfaces and dimension 6 sage: for q in Q: print(q) Q_0(1^2, -1^6) Q_0(3, -1^7) sage: Q = QuadraticStrata(dimension=5, genus=1, fake_zeros=True, nb_poles=0) sage: for q in Q: print(q)
- class surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStrata_class[source]¶
Bases:
Strata
Base class for strata of quadratic differentials.
- class surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStrata_d(dimension, min_nb_poles, max_nb_poles, fake_zeros)[source]¶
Bases:
QuadraticStrata_class
Strata with prescribed dimension.
EXAMPLES:
sage: from surface_dynamics import * sage: for q in QuadraticStrata(dimension=5): print(q) Q_3(8) Q_2(2, 1^2) Q_2(4, 1, -1) Q_2(3, 2, -1) Q_2(6, -1^2) Q_1(2, 1, -1^3) Q_1(4, -1^4) Q_0(2, -1^6) sage: Q = QuadraticStrata(dimension=6,nb_poles=1); Q Quadratic strata of dimension 6 with 1 pole sage: for q in Q: print(q) Q_3(9, -1) Q_2(3, 1^2, -1) Q_2(2^2, 1, -1)
- class surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStrata_g(genus, min_nb_poles=None, max_nb_poles=None)[source]¶
Bases:
QuadraticStrata_class
Stratas of genus g surfaces.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = QuadraticStrata(genus=3); Q Quadratic strata of genus 3 surfaces sage: Q.cardinality() +Infinity sage: i = iter(Q) sage: next(i) Q_3(8) sage: Q = QuadraticStrata(genus=2,max_nb_poles=1); Q Quadratic strata of genus 2 surfaces with at most 1 pole sage: Q.list() [Q_2(2^2), Q_2(2, 1^2), Q_2(1^4), Q_2(5, -1), Q_2(4, 1, -1), Q_2(3, 2, -1), Q_2(3, 1^2, -1), Q_2(2^2, 1, -1), Q_2(2, 1^3, -1), Q_2(1^5, -1)] sage: Q = QuadraticStrata(genus=4,nb_poles=3); Q Quadratic strata of genus 4 surfaces with 3 poles sage: Q.cardinality() 176
- an_element_()¶
Return the first element of this list of strata.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = QuadraticStrata(genus=4); Q Quadratic strata of genus 4 surfaces sage: Q.first() Q_4(12) sage: Q = QuadraticStrata(genus=3,nb_poles=1); Q Quadratic strata of genus 3 surfaces with 1 pole sage: Q.first() Q_3(9, -1) sage: Q = QuadraticStrata(genus=3,min_nb_poles=2); Q Quadratic strata of genus 3 surfaces with at least 2 poles sage: Q.first() Q_3(10, -1^2)
- first()[source]¶
Return the first element of this list of strata.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = QuadraticStrata(genus=4); Q Quadratic strata of genus 4 surfaces sage: Q.first() Q_4(12) sage: Q = QuadraticStrata(genus=3,nb_poles=1); Q Quadratic strata of genus 3 surfaces with 1 pole sage: Q.first() Q_3(9, -1) sage: Q = QuadraticStrata(genus=3,min_nb_poles=2); Q Quadratic strata of genus 3 surfaces with at least 2 poles sage: Q.first() Q_3(10, -1^2)
- last()[source]¶
Return the last element of this list of strata.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = QuadraticStrata(genus=2, nb_poles=0); Q Quadratic strata of genus 2 surfaces with no pole sage: Q.last() Q_2(1^4) sage: Q = QuadraticStrata(genus=0); Q Quadratic strata of genus 0 surfaces sage: Q.last() Traceback (most recent call last): ... NotImplementedError: infinite list
- class surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStrata_gd(genus, dimension, min_nb_poles, max_nb_poles, fake_zeros)[source]¶
Bases:
QuadraticStrata_class
Quadratic strata with presrcribed genus and dimension.
- class surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStratum(signature, k)[source]¶
Bases:
Stratum
Stratum of quadratic differentials.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = Stratum([15,-1,-1,-1], k=2) sage: Q Q_4(15, -1^3) sage: Q.components() (Q_4(15, -1^3)^c,) sage: Q = Stratum([6,6], k=2) sage: Q Q_4(6^2) sage: Q.components() (Q_4(6^2)^hyp, Q_4(6^2)^reg, Q_4(6^2)^irr)
- has_hyperelliptic_component()[source]¶
Returns True if and only if self has a connected component which contains only hyperelliptic surfaces.
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([2,2], k=2).has_hyperelliptic_component() True sage: Stratum([3,1], k=2).has_hyperelliptic_component() False
- has_non_hyperelliptic_component()[source]¶
Test whether this stratum has a non hyperelliptic component.
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([10,10], k=2).has_non_hyperelliptic_component() True sage: Stratum([6,6], k=2).has_non_hyperelliptic_component() False
- has_regular_and_irregular_components()[source]¶
Test whether this component has a pair of regular, irregular components.
The list of strata of quadratic differentials that admit such a pair are:
in genus 3: Q(9,-1), Q(6,3,-1), Q(3,3,3,-1) in genus 4: Q(12), Q(9,3), Q(6,6), Q(6,3,3), Q(3,3,3,3)
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([9,-1], k=2).has_regular_and_irregular_components() True sage: Stratum([11,1], k=2).has_regular_and_irregular_components() False
- hyperelliptic_component()[source]¶
Returns the hyperelliptic component of self (or raise a ValueError).
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([2,2], k=2).hyperelliptic_component() Q_2(2^2)^hyp sage: Stratum([3,1], k=2).hyperelliptic_component() Traceback (most recent call last): ... ValueError: the stratum has no hyperelliptic component
- irregular_component()[source]¶
Returns the irregular component of that stratum or raise a ValueError.
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([3,3,3,-1], k=2).irregular_component() Q_3(3^3, -1)^irr sage: Stratum([2,2], k=2).irregular_component() Traceback (most recent call last): ... ValueError: no irregular component for this stratum
- non_hyperelliptic_component()[source]¶
Returns the non hyperelliptic component of this stratum (or raise a ValueError).
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([10,10], k=2).non_hyperelliptic_component() Q_6(10^2)^nonhyp sage: Stratum([2,2], k=2).non_hyperelliptic_component() Traceback (most recent call last): ... ValueError: no non hyperelliptic component
- orientation_cover(fake_zeros=False)[source]¶
Return the stratum of Abelian differentials which contains the set of orientation cover of quadratic differentials in this stratum.
OPTIONS:
fake_zeros
- boolean - if True, add fake zeros which corresponds to the double cover of poles.
EXAMPLES:
sage: from surface_dynamics import * sage: q = Stratum({4:1,-1:4}, k=2) sage: q Q_1(4, -1^4) sage: a1 = q.orientation_cover(); a1 H_3(2^2) sage: q.orientation_cover(fake_zeros=True) H_3(2^2, 0^4)
For hyperelliptic strata (orientation cover of quadratic strata of the form Q(n,-1^{n+4})) the dimension coincide. From [Lan08] we know that it only happens for those ones:
sage: q = Stratum({4:1, -1:8}, k=2) sage: q Q_0(4, -1^8) sage: q.dimension() 7 sage: q.orientation_cover().dimension() 7 sage: q = Stratum({3:1, 1:1, -1:8}, k=2) sage: q Q_0(3, 1, -1^8) sage: q.dimension() 8 sage: a = q.orientation_cover(); a H_4(4, 2) sage: a.dimension() 9
- random_cylindric_permutation()[source]¶
Return a random cylindric permutation that belongs to this stratum.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = Stratum([4,4], k=2) sage: Q.random_cylindric_permutation() # random 0 1 2 3 4 5 1 5 2 6 3 6 4 0
- regular_component()[source]¶
Returns the regular component of that stratum or raise a ValueError.
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([12], k=2).regular_component() Q_4(12)^reg sage: Stratum([2,2,2,2], k=2).regular_component() Traceback (most recent call last): ... ValueError: no regular component for this stratum
- spin()[source]¶
Return the spin structure (None, 0 or 1) of that component.
Any quadratic differential has a canonic double cover (called the orientation cover) which is a surface, generally of higher genera, with an Abelian differential. The spin structure of the quadratic differential is the spin structure of that double cover.
The spin is None if any degree of zero of the quadratic differential is congruent to 2 mod 4. Otherwise, denoting respectively k1 and k3 the number of degree of zero congruent to 1 and 3 modulo 4 we have
..MATH:
spin = ((k1-k3)/4) mod 2
The proof of that formula is the object of [Lan04].
EXAMPLES:
sage: from surface_dynamics import * sage: Stratum([1,3], k=2).spin() 0 sage: Stratum({1:1,3:1,-1:4}, k=2).spin() 1 sage: Stratum([2,2], k=2).spin() is None True
- class surface_dynamics.flat_surfaces.quadratic_strata.QuadraticStratumComponent(stratum)[source]¶
Bases:
StratumComponent
Generic class for component of quadratic stratum.
- lyapunov_exponents_H_minus(**kargs)[source]¶
Compute the H^- Lyapunov exponents.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = Stratum({1:3, -1:3}, k=2).unique_component() sage: Q.lyapunov_exponents_H_minus(nb_iterations=2**21) # long time # abs tol .05 [1.000, 0.369, 0.176] sage: R = Stratum([3,3,3,-1], k=2).regular_component() sage: R.lyapunov_exponents_H_minus(nb_iterations=2**21) # long time # abs tol .05 [1.000, 0.328, 0.1899, 0.0820]
- lyapunov_exponents_H_plus(*args, **kargs)[source]¶
Compute the H^+ part of Lyapunov exponents spectrum.
All arguments and keywords are sent to ?
EXAMPLES:
sage: from surface_dynamics import * sage: R = Stratum([3,3,3,-1], k=2).regular_component() sage: R.lyapunov_exponents_H_plus(nb_iterations=2**21) # long time # abs tol .05 [0.596, 0.405, 0.202] sage: sum(_) # long time # abs tol .05 1.2 sage: R = Stratum([2,2,2,2], k=2).unique_component() sage: R.lyapunov_exponents_H_plus(nb_iterations=2**21) # long time # abs tol .05 [0.651, 0.469, 0.243] sage: sum(_) # long time # abs tol .05 1.3636
- one_cylinder_diagram()[source]¶
Return a separatrix diagram with one cylinder that belongs to this component of stratum.
EXAMPLES:
sage: from surface_dynamics import * sage: Q = Stratum({1:1,-1:5}, k=2) sage: c = Q.unique_component().one_cylinder_diagram() sage: c (0,0,1,1,2,2)-(3,3) sage: c.stratum() == Q True sage: Q = Stratum([5,-1], k=2) sage: c = Q.unique_component().one_cylinder_diagram() sage: c (0,1,1,2)-(3,0,3,2) sage: c.stratum() == Q True sage: Stratum({-1:4}, k=2).unique_component().one_cylinder_diagram() (0,0)-(1,1) sage: Stratum({-1:4,0:1}, k=2).unique_component().one_cylinder_diagram() (0,0)-(1,1,2,2)
- orientation_cover_component(fake_zeros=False)[source]¶
Return the connected component of Abelian stratum component which contains the set of orientation cover of quadratic differentials in this connected component.
ALGORITHM:
The spin only depends on the component and the only components for which the double cover belongs to a hyperelliptic component are Q(k,-1^k+4) and Q(2g-1,2g-1,-1,-1)^hyp
OPTIONS:
fake_zeros
- boolean - if True, add fake zeros which corresponds to the double cover of poles.
EXAMPLES:
sage: from surface_dynamics import * sage: cc = Stratum({5:1, -1:9}, k=2).unique_component() sage: cc.orientation_cover_component() H_4(6)^hyp sage: cc = Stratum({5:1, -1:5}, k=2).unique_component() sage: cc.orientation_cover_component() H_4(6)^odd sage: cc = Stratum({5:1, -1:1}, k=2).unique_component() sage: cc.orientation_cover_component() H_4(6)^even sage: cc = Stratum({1: 2, -1: 6}, k=2).unique_component() sage: cc.orientation_cover_component() H_3(2^2)^odd sage: cc = Stratum({4:1, -1:8}, k=2).unique_component() sage: cc.orientation_cover_component() H_3(2^2)^hyp sage: cc = Stratum({1:2, -1:2}, k=2).unique_component() sage: cc.orientation_cover_component() H_3(2^2)^hyp
- random_cylindric_permutation(nsteps=64)[source]¶
Return a cylindric permutation of the form
p = ((0,...),(..., 0))
where 0 can be any label.EXAMPLES:
sage: from surface_dynamics import * sage: Q = Stratum({4:1,-1:4}, k=2) sage: Q Q_1(4, -1^4) sage: c = Q.unique_component() sage: p = c.random_cylindric_permutation() sage: p.stratum_component() Q_1(4, -1^4)^c sage: Q = Stratum([6,6], k=2) sage: c_hyp, c_reg, c_irr = Q.components() sage: (c_hyp, c_reg, c_irr) (Q_4(6^2)^hyp, Q_4(6^2)^reg, Q_4(6^2)^irr) sage: all(c_hyp.random_cylindric_permutation().stratum_component() == c_hyp for _ in range(4)) True sage: all(c_reg.random_cylindric_permutation().stratum_component() == c_reg for _ in range(4)) True sage: all(c_irr.random_cylindric_permutation().stratum_component() == c_irr for _ in range(4)) True
- surface_dynamics.flat_surfaces.quadratic_strata.REQSC¶
- class surface_dynamics.flat_surfaces.quadratic_strata.RegularExceptionalQuadraticStratumComponent(stratum)[source]¶
Bases:
QuadraticStratumComponent
This class is intended to be called internally rather than directly. Call only with appropriate parameters, in particular correct genus: no consistency check inside, no prediction as to what may happen otherwise.
- permutation_representative(reduced=True, alphabet=None, relabel=True)[source]¶
Returns a generalized permutation representative.
EXAMPLES:
sage: from surface_dynamics import * sage: cc = Stratum([9,-1], k=2).regular_component() sage: p = cc.permutation_representative(); p 0 1 2 1 2 3 3 4 5 6 5 6 4 0 sage: p.stratum_component() Q_3(9, -1)^reg sage: cc = Stratum([6,3,-1], k=2).regular_component() sage: p = cc.permutation_representative(); p 0 1 2 3 1 2 4 4 5 6 7 6 7 3 5 0 sage: p.stratum_component() Q_3(6, 3, -1)^reg sage: cc = Stratum([12], k=2).regular_component() sage: p = cc.permutation_representative(); p 0 1 2 1 2 3 4 3 4 5 5 6 7 6 7 0 sage: p.stratum_component() Q_4(12)^reg
Masur Veech volumes¶
Masur-Veech volumes of Abelian strata and their connected components
- surface_dynamics.flat_surfaces.masur_veech_volumes.masur_veech_volume(C, rational=False, method=None)[source]¶
Return the Masur-Veech volume of the stratum or component of stratum
C
.INPUT:
C
– a stratum or a connected component of stratumrational
(boolean) - ifFalse
(default) return the Masur-Veech volume and ifTrue
return the Masur-Veech volume divided by zeta(2g).method
- the method to use to compute the volume either"table"
- for a table lookup (all strata up to dimension 9 and some strata up to dimension 11)"CMSZ"
- the Chen-Möller-Sauvaget-Zagier recursion (currently only implemented for the principal stratum)
- surface_dynamics.flat_surfaces.masur_veech_volumes.minimal_strata_CMSZ(gmax, rational=False)[source]¶
Return the volumes of cH(2g-2) for the genus g going from
1
up togmax-1
.The algorithm is the one from Sauvaget [Sau18] involving an implicit equation. As explained in [CheMoeSauZag20], one could go through Lagrange inversion. Note that they miss factor 2 in their theorem 4.1.
EXAMPLES:
sage: from surface_dynamics.flat_surfaces.masur_veech_volumes import minimal_strata_CMSZ sage: minimal_strata_CMSZ(6, True) [2, 3/4, 305/576, 87983/207360, 1019547/2867200] sage: minimal_strata_CMSZ(6, False) [1/3*pi^2, 1/120*pi^4, 61/108864*pi^6, 12569/279936000*pi^8, 12587/3311616000*pi^10] sage: from surface_dynamics import Stratum sage: from surface_dynamics.flat_surfaces.masur_veech_volumes import masur_veech_volume sage: for rat in [True, False]: ....: V0, V2, V4, V6 = minimal_strata_CMSZ(5, rational=rat) ....: MV0 = masur_veech_volume(Stratum([0], k=1), rat, 'table') ....: assert V0 == MV0, (V0, MV0, rat) ....: MV2 = masur_veech_volume(Stratum([2], k=1), rat, 'table') ....: assert V2 == MV2, (V2, MV2, rat) ....: MV4 = masur_veech_volume(Stratum([4], k=1), rat, 'table') ....: assert V4 == MV4, (V4, MV4, rat) ....: MV6 = masur_veech_volume(Stratum([6], k=1), rat, 'table') ....: assert V6 == MV6, (V6, MV6, rat)
- surface_dynamics.flat_surfaces.masur_veech_volumes.minimal_strata_hyp(g, rational=False)[source]¶
Return the volume of the hyperelliptic component H^{hyp}(2g-2).
The explicit formula appears in section 6.5 of [CheMoeSauZag20].
EXAMPLES:
sage: from surface_dynamics.flat_surfaces.masur_veech_volumes import minimal_strata_hyp sage: minimal_strata_hyp(2) 1/120*pi^4 sage: minimal_strata_hyp(4) 1/580608*pi^8 sage: minimal_strata_hyp(10) 1/137733277917118464000*pi^20 sage: minimal_strata_hyp(10, rational=True) 668525/10499279483305984
- surface_dynamics.flat_surfaces.masur_veech_volumes.minimal_strata_spin_diff(gmax, rational=False)[source]¶
Return the differences of volumes between even and odd components in H(2g-2) for the genus g going from
1
up togmax-1
.If there are no even/odd components, the corresponding total volume is 0. Formulas are from [CheMoeSauZag20].
EXAMPLES:
sage: from surface_dynamics.flat_surfaces.masur_veech_volumes import minimal_strata_spin_diff sage: minimal_strata_spin_diff(5) [-1/3*pi^2, -1/120*pi^4, -143/544320*pi^6, -15697/1959552000*pi^8] sage: minimal_strata_spin_diff(5, rational=True) [-2, -3/4, -143/576, -15697/207360]