CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutSign UpSign In
| Download

Some example calculations with diffstrata.

Views: 49
Image: ubuntu2004
Kernel: SageMath 9.8


The purpose of diffstrata is to make computations in the tautological ring of the moduli space of multi-scale kk-differentials, which is a compactification of strata of k-differentials.

One of the main goals during the developements was to compute the Euler characteristic of strata of k-differentials ΩkMg,n(μ)\Omega^k\mathcal{M}_{g,n}(\mu) where μ=(m1,,mn)\mu = (m_1, \dots, m_n) such that imi=k(2g2)\sum_i m_i = k(2g-2).

The tautological ring

As diffstrata does computations in the (vertical) tautological ring, we first describe how to obtain and evaluate the elements of this ring.

The abelian case

We first consider the case k=1k=1, i.e. the case of abelian differentials. Recall that the boundary of the moduli space of multi-scales differentials is stratified by enhanced level graphs.

Diffstrata only knows those level graphs without horizontal edges. As a first example, we create a stratum and list all 2-level graphs (called BICs for bi-colored) in the boundary of PΞM2,1(2)\mathbb{P}\Xi\overline{\mathcal{M}}_{2,1}(2).

%display unicode_art from admcycles.diffstrata import Stratum X = Stratum((2,)) for b in X.bics: show(b)
╭───────╮ │╭────────╮ 00 -2-2 ╭┴┴───╮ ╭┴─┴───╮ │1 (0)│ │0 (-1)│ ╰─────╯ ╰┬─────╯ 2
╭───────╮ 0 -2 ╭┴────╮ ╭┴─────╮ │1 (0)│ │1 (-1)│ ╰─────╯ ╰┬─────╯ 2

In the above images, the rectangles are the vertices of the graphs, the numbers inside are the genera, the numbers in brackets are the level the vertex is contained in, and the number at the edges and legs are the orders of the differential at the corresponding point.

Each boundary stratum in codimensions cc is the intersection of cc BICs b1,,bcb_1,\dots,b_c. We would like to index this boundary stratum with the tuple (b1,,bc)(b_1, \dots, b_c), but there might be more than one graph that is the intersection of those BICs. Assume that there are pp such graphs. We index those graphs with the so-called enhanced profiles ((b1,,bc),1),((b1,,bc),p)((b_1, \dots, b_c), 1), \, \dots ((b_1, \dots, b_c), p).

In the above example, there is only one graph in codimension 22:

print("All enhanced profiles of length 2:", X.enhanced_profiles_of_length(2)) enh_p = X.enhanced_profiles_of_length(2)[0] show(X.lookup_graph(*enh_p))
All enhanced profiles of length 2: (((1, 0), 0),)
╭─────────╮ │ ╭────────╮ │ │╭─────────╮ 0 00-2 -2-2 ╭┴────╮ ╭┴┴┴───╮ ╭┴─┴───╮ │1 (0)│ │0 (-1)│ │0 (-2)│ ╰─────╯ ╰──────╯ ╰┬─────╯ 2

The (vertical) tautological ring is the ring generated by the BICs and the ψ\psi-classes. Other important classes contained in this ring are the κ\kappa-classes and the first Chern class of the tautological bundle ξ:=c1(O(1))\xi := c_1(\mathcal{O}(-1)). We pick up our previouse example and compute some intersection numbers.

b1 = X.taut_from_graph((0,), 0) # The tautological class corresponding to the enhanced profile ((0,), 0), i.e. first BIC. b2 = X.taut_from_graph((1,), 0) # The tautological class corresponding to the enhanced profile ((1,), 0), i.e. second BIC. psi = X.psi(1) # The psi-class supported on the first leg kappa = X.kappa_1_AC # The (Arabello-Cornalba-)kappa class. xi = X.xi # The class xi. print("\\xi * \\psi_1 * b1 =", (xi * psi * b1).evaluate()) print("\\xi * \\psi_1 * b2 =", (xi * psi * b2).evaluate()) print("\\xi * b1 * b2 =", (b1*b2*xi).evaluate()) print("\\xi^3 =", (xi**3).evaluate()) # For powers of xi there is a dedicated function that is usually faster print("\\xi^3 =", X.xi_pow(3).evaluate()) # For top-powers of xi tere is an even faster function print("\\xi^3 =", X.xi_pow_immediate_evaluation(3))
\xi * \psi_1 * b1 = 0 \xi * \psi_1 * b2 = 1/192 \xi * b1 * b2 = 1/48 \xi^3 = -1/640 \xi^3 = -1/640 \xi^3 = -1/640

The case of kk-differentials

We now consider the case k>1k>1. There is a stratifications of the boundary by the decorated dual graphs of the curves underlying the kk-differentials (we will call those graphs kk-graphs in the following). This stratification turns out to be too coarse for our purposes.

To obtain a finer stratification, recall that each kk-differential comes with a canonical cover (that is an abelian differential together with an automorphism of order kk such that the abelian differential is in the ζk\zeta_k eigenspace of the automorphism for a primitive kk-th root of unity ζk\zeta_k). This construction extends to the boundary by gluing the canonical covers of all irreducible components of the nodal curves to obtain an admissible cover. Note however that a given kk-graph might have multiple canonical covers. Hence the canonical covers give a finer stratification of the boundary, and this stratification is the one diffstrata works with.

When printing a graph in a stratum of kk-differentials, diffstrata will a priori print the canonical cover, but you can explicitly ask for the kk-graph.

Q = Stratum((-1,5), 2) show(Q.bics[0]) show(Q.bics[0].LG.quotient())
╭───────────────╮ │ ╭─────────╮ │╭──────────────────╮ ││ │╭────────────╮ 00 00 -2-2-2-2 ╭┴┴───╮ ╭┴┴───╮ ╭┴─┴─┴─┴─╮ │1 (0)│ │1 (0)│ │0 (-1) │ ╰─────╯ ╰─────╯ ╰┬┬──────╯ 06
╭────────╮ ╭───────╮ │ 00 -4-4 ╭┴┴───╮ ╭┴─┴───╮ │1 (0)│ │0 (-1)│ ╰─────╯ ╰┬─┬───╯ -15

Everything that was said about the tautological ring in the abelian case is still true, with one exception: The first Chern class of the tautological bundle is no longer called ξ\xi, but ζ\zeta. (For k=1k=1 actually ξ=ζ\xi = \zeta, so you might simply always use ζ\zeta.)

print("\\zeta^3 =", Q.zeta_pow(3).evaluate())
\zeta^3 = -7/180

Higher level functions

There are some interesting invariants of the stratum that can be computed via intersection theory and for which the formulas are already implemented.

Euler characteristic

The Euler characteristic of the projectivized strata can be computed as follows.

print("\\chi(X) =", X.euler_characteristic()) print("\\chi(Q) =", Q.euler_characteristic())
\chi(X) = -1/40 \chi(Q) = -7/15

Masur-Veech volume

For k2k \leq 2, the Masur-Veech volume of the strata can be computed as follows.

print("vol(X) =", X.masur_veech_volume()) print("vol(Q) =", Q.masur_veech_volume())
vol(X) = 1/120*pi^4 vol(Q) = 28/135*pi^4