Documentation for the Hodge diamond cutter#

A tool to work with Hodge diamonds, comes with many varieties and constructions built into it.

Hodge diamonds encode the Hodge numbers of a variety, and provide interesting information about its structure. They provide a numerical incarnation of many operations one can perform in algebraic geometry, such as blowups, projective bundles, products. They are also computed for many more specific constructions such as certain moduli spaces of sheaves, or flag varieties, …

These Hodge numbers are defined as the dimensions of the sheaf cohomology of exterior powers of the cotangent bundle, i.e.

\[\mathrm{h}^{p,q}(X)=\dim\mathrm{H}^q(X,\Omega_X^p)\]

Here $p$ and $q$ range from $0$ to $n=\dim X$. These numbers satisfy additional symmetry properties:

  • Hodge symmetry: $\mathrm{h}^{p,q}(X)=\mathrm{h}^{q,p}(X)$

  • Serre duality: $\mathrm{h}^{p,q}(X)=\mathrm{h}^{n-p,n-q}(X)$

Because of these symmetries they are usually displayed as a diamond (it’s really just a square tilted 45 degrees), so that for a surface it would be:

                h^{2,2}
        h^{2,1}         h^{1,2}
h^{2,0}         h^{1,1}         h^{0,2}
        h^{1,0}         h^{0,1}
                h^{0,0}

One of their famous applications is the mirror symmetry prediction that every Calabi-Yau 3-fold has a mirror Calabi-Yau threefold, which should imply that their Hodge diamonds are transpositions. The first instance of this is the quintic 3-fold and its mirror, whose Hodge diamonds are:

              1
         0         0
    0         1         0
1       101       101       1
    0         1         0
         0         0
              1

and:

             1
        0         0
    0       101       0
1       1         1       1
    0       101       0
        0         0
             1

The following are some very basic examples of operations and constructions one can use within the Hodge diamond cutter. To get started we do:

sage: from diamond import *

after starting Sage.

Pretty print the Hodge diamond of a genus 2 curve:

sage: X = HodgeDiamond.from_matrix([[1, 2], [2, 1]])
sage: print(X)
      1
  2       2
      1

Compute the Euler characteristic of the product of X with itself:

sage: print((X*X).euler())
4

Pretty print the Hodge diamond of the Hilbert square of a K3 surface:

sage: S = HodgeDiamond.from_matrix([[1, 0, 1], [0, 20, 0], [1, 0, 1]])
sage: print(hilbn(S, 2))
                    1
               0         0
          1        21        1
      0        0         0        0
  1       21       232       21       1
      0        0         0        0
          1        21        1
               0         0
                    1

It also possible to generate LaTeX code:

sage: latex(K3().pprint())
\begin{tabular}{ccccc}
 &  & $1$ &  &  \\
 & $0$ &  & $0$ &  \\
$1$ &  & $20$ &  & $1$ \\
 & $0$ &  & $0$ &  \\
 &  & $1$ &  &  \\
\end{tabular}

There are many varieties built in, e.g. the previously defined K3 surface can be compared to the built-in one:

sage: print(S == K3())
True

Check out the [documentation](https://pbelmans.ncag.info/hodge-diamond-cutter) for all the available functionality.

If you use the software in your work, please cite it as explained on [Zenodo](https://doi.org/10.5281/zenodo.3893509).

AUTHORS:

  • Pieter Belmans (2019-01-27): initial version

  • Pieter Belmans (2020-06-16): the version which got assigned a DOI

  • Pieter Belmans (2021-08-04): various additions, added unit tests and proper documentation

Hodge diamonds#

class diamond.HodgeDiamond(parent, m)[source]#

This class implements some methods to work with Hodge diamonds.

R = Multivariate Polynomial Ring in x, y over Integer Ring#

polynomial ring used internally for the Hodge-Poincaré polynomial and can be used externally to create new polynomials (and thus diamonds)

x = x#

variables in the polynomial ring for Hodge-Poincaré polynomials

y = y#

variables in the polynomial ring for Hodge-Poincaré polynomials

hide_zeroes = None#

static configuration variable for pretty-printing, see HodgeDiamond.pprint()

quarter = None#

static configuration variable for pretty-printing, see HodgeDiamond.pprint()

__init__(parent, m)[source]#

Constructor for a Hodge diamond if you know what you are doing

This just uses the given matrix. It is probably advised to use the class methods

in most cases though.

classmethod from_matrix(m, from_variety=False)[source]#

Construct a Hodge diamond from a matrix

INPUT:

  • m – square integer matrix representing a Hodge diamond

  • from_variety (default: False) – whether a check should be performed that it comes from a variety

EXAMPLES:

Hodge diamond of a K3 surface:

sage: from diamond import *
sage: S = HodgeDiamond.from_matrix([[1, 0, 1], [0, 20, 0], [1, 0, 1]])
sage: S == K3()
True

The following fails as the lack of symmetry prevents a geometric origin:

sage: HodgeDiamond.from_matrix([[1, 2], [0, 1]], from_variety=True)
Traceback (most recent call last):
...
AssertionError: The matrix does not
                satisfy the conditions satisfied by the Hodge diamond of a
                smooth projective variety.
classmethod from_polynomial(f, from_variety=False)[source]#

Construct a Hodge diamond from a Hodge–Poincaré polynomial

INPUT:

  • f – an integer polynomial in the ring HodgeDiamond.R representing the Hodge–Poincaré polynomial

  • from_variety (default: False) – whether a check should be performed that it comes from a variety

EXAMPLES:

Hodge diamond of a K3 surface:

sage: from diamond import *
sage: x, y = (HodgeDiamond.x, HodgeDiamond.y)
sage: S = HodgeDiamond.from_polynomial(1 + x**2 + 20*x*y + y**2 + x**2 * y**2)
sage: S == K3()
True

The following fails as the lack of symmetry prevents a geometric origin:

sage: HodgeDiamond.from_polynomial(1 + x, from_variety=True)
Traceback (most recent call last):
...
AssertionError: The matrix does not
                satisfy the conditions satisfied by the Hodge diamond of a
                smooth projective variety.
property polynomial#

The Hodge–Poincaré polynomial describing the Hodge diamond

Getter:

returns the Hodge–Poincaré polynomial

Setter:

sets the Hodge diamond using a Hodge–Poincaré polynomial

Type:

element of HodgeDiamond.R

EXAMPLES:

The Hodge–Poincaré polynomial of a K3 surface:

sage: from diamond import *
sage: print(K3().polynomial)
x^2*y^2 + x^2 + 20*x*y + y^2 + 1

Modifying the Hodge diamond of the projective plane:

sage: X = Pn(2)
sage: X.polynomial = X.polynomial + X.x * X.y
sage: print(X)
          1
      0       0
  0       2       0
      0       0
          1
property matrix#

The matrix describing the Hodge diamond

Getter:

returns the matrix

Setter:

sets the Hodge diamond using a matrix

Type:

square matrix of integers

size()[source]#

Internal method to determine the (relevant) size of the Hodge diamond

__eq__(other)[source]#

Check whether two Hodge diamonds are equal

This compares the Hodge polynomials, not the possibly oversized matrices describing the Hodge diamond.

EXAMPLES:

A quartic surface is a K3 surface:

sage: from diamond import *
sage: K3() == hypersurface(4, 2)
True
__ne__(other)[source]#

Check whether two Hodge diamonds are not equal

EXAMPLES:

The projective line is not a genus 2 curve:

sage: from diamond import *
sage: Pn(1) != curve(2)
True

The point is not the Lefschetz class:

sage: point() != lefschetz()
True
__pow__(power)[source]#

Raise a Hodge diamond to a power

This corresponds to iterated multiplication.

INPUT:

  • power – exponent for the iterated multiplication

EXAMPLES:

The product of 2 K3 surfaces in two ways:

sage: from diamond import *
sage: K3()**2 == K3()*K3()
True
__call__(i, y=None)[source]#

The calling operator either does a Lefschetz twist, or an evaluation

If one parameter is present, then twist by a power of the Lefschetz Hodge diamond. If two parameters are present, then evaluate the Hodge-Poincaré polynomial

Negative values are allowed to untwist, up to the appropriate power.

INPUT:

  • i – integer denoting the power of the Lefschetz class, or value for the first variable

  • y – value of the second variable (default: None), if it is non-zero then i is reinterpreted as the value of the first variable

EXAMPLES:

The Lefschetz class is by definition the twist of the point:

sage: from diamond import *
sage: lefschetz() == point()(1)
True

We can reconstruct projective space as a sum of twists of the point:

sage: Pn(10) == sum(point()(i) for i in range(11))
True

If we supply two parameters we are evaluation the Hodge-Poincaré polynomial, e.g. to find the Euler characteristic:

sage: Pn(10)(1, 1) == 11
True
__getitem__(index)[source]#

Get (p, q)th entry of Hodge diamond or the ith row of the Hodge diamond

__str__()[source]#

Pretty print Hodge diamond

This gets called when you specifically print the object.

EXAMPLES:

The projective line:

sage: from diamond import *
sage: print(Pn(1))
      1
  0       0
      1
pprint(format='table', hide_zeroes=None, quarter=None)[source]#

Pretty print the Hodge diamond

INPUT:

  • format – output format (default: “table”), if table it pretty prints a Hodge diamond; all else defaults to the polynomial

  • hide_zeroes (default: False) – whether to hide the zeroes if “table” is used as format

  • quarter (default: False) – whether to only print the top-left quarter if “table” is used for the format

The parameters hide_zeroes and quarter can be set using a static variable, in which case providing them will override this value (if it is set).

EXAMPLES:

The projective line:

sage: from diamond import *
sage: Pn(1).pprint()
      1
  0       0
      1
sage: Pn(1).pprint(format="polynomial")
x*y + 1

Don’t print the zeroes:

sage: from diamond import *
sage: (Pn(2) * curve(3)).pprint(hide_zeroes=True)
      1
  3       3
      2
  3       3
      2
  3       3
      1

Only print the top-left quarter:

sage: from diamond import *
sage: (Pn(2) * curve(3)).pprint(quarter=True)
              1
          3
      0       2
  0       3

Only print the top-left quarter whilst hiding zeroes:

sage: from diamond import *
sage: (Pn(2) * curve(3)).pprint(hide_zeroes=True, quarter=True)
      1
  3
      2
  3
is_hodge_symmetric()[source]#

Check whether the Hodge diamond satisfies Hodge symmetry

This checks the equality

\[\mathrm{h}^{p,q}(X)=\mathrm{h}^{q,p}(X)\]

for $p,q=0,\ldots,\dim X$.

Almost all of the constructions provided with the library satisfy Hodge symmetry, because we (somewhat implicitly) work with things which are (or behave like) smooth projective varieties over a field of characteristic zero.

Over the complex numbers this can fail for non-Kähler manifolds, such as the Hopf surface.

In positive characteristic this can fail too, with an example given by classical and singular Enriques surfaces in characteristic 2, see [MR0491720] and Proposition 1.4.2 in [MR0986969]

  • [MR0491720] Bombieri–Mumford, Enriques’ classification of surfaces in char. p. III.

  • [MR0986969] Cossec–Dolgachev, Enriques surfaces I, Progress in Mathematics, 1989

EXAMPLES:

Constructions satisfy this property:

sage: from diamond import *
sage: Pn(5).is_hodge_symmetric()
True

The Hopf surface over the complex numbers:

sage: S = HodgeDiamond.from_matrix([[1, 0, 0], [1, 0, 1], [0, 0, 1]])
sage: print(S)
          1
      0       1
  0       0       0
      1       0
          1
sage: S.is_hodge_symmetric()
False

Classical and singular Enriques surfaces in characteristic 2 (which are smooth, despite their name) also have a Hodge diamond violating Hodge symmetry:

sage: enriques(two="classical").is_hodge_symmetric()
False
sage: enriques(two="singular").is_hodge_symmetric()
False
sage: enriques(two="supersingular").is_hodge_symmetric()
True
is_serre_symmetric()[source]#

Check whether the Hodge diamond satisfies Serre symmetry

This checks the equality

\[\mathrm{h}^{p,q}(X)=\mathrm{h}^{\dim X-p,\dim X-q}(X)\]

for $p,q=0,\ldots,\dim X$.

Because Serre duality holds for all smooth projective varieties, independent of the characteristic, and also for non-Kähler varieties there are no examples where this condition fails. It can of course fail for motivic pieces, for silly reasons.

EXAMPLES:

The Hilbert scheme of 4 points on a K3 surface satisfies the symmetry:

sage: from diamond import *
sage: hilbn(K3(), 4).is_serre_symmetric()
True

The Lefschetz diamond fails it for silly reasons:

sage: lefschetz().is_serre_symmetric()
False
betti()[source]#

Betti numbers of the Hodge diamond

This gives an integer vector.

EXAMPLES:

Betti numbers of a K3 surface:

sage: from diamond import *
sage: K3().betti()
[1, 0, 22, 0, 1]

The second Betti number of the Hilbert scheme of points on a K3 surface is 23, not 22:

sage: [hilbn(K3(), n).betti()[2] for n in range(2, 10)]
[23, 23, 23, 23, 23, 23, 23, 23]
middle()[source]#

Middle cohomology of the Hodge diamond

For smooth projective varieties the middle cohomology sits in degree equal to the dimension.

EXAMPLES:

There is an interesting link between K3 surfaces and cubic fourfolds which can be seen on the level of middle cohomology:

sage: from diamond import *
sage: (hypersurface(3, 4) - lefschetz()**2).middle()
[0, 1, 20, 1, 0]
sage: K3().middle()
[1, 20, 1]
row(i, truncate=False)[source]#

Get the ith row of the Hodge diamond

For smooth projective varieties these are the Hodge numbers of the Hodge structure on the cohomology in degree i.

Alternatively, you can use HodgeDiamond.__getitem__ with a single index i (but then you have to truncate yourself).

INPUT:

  • i – the row of the Hodge diamond

  • truncate (default: False) – whether you want to omit leading and trailing zeroes

EXAMPLES:

For a smooth projective variety the middle cohomology is the row sitting in the middle dimension:

sage: from diamond import *
sage: hypersurface(3, 4).middle() == hypersurface(3, 4).row(4)
True

If you don’t want to truncate, HodgeDiamond.__getitem__ gives the same functionality:

sage: from diamond import *
sage: hypersurface(3, 4).row(4) == hypersurface(3, 4)[4]
True

For the moduli space of vector bundles on a curve, the cohomology in degree 3 is the same as the cohomology of the curve in degree 1:

sage: from diamond import *
sage: moduli_vector_bundles(3, 1, 9).row(3, truncate=True)
[9, 9]
signature()[source]#

The signature of the Hodge diamond

This is the index of the intersection form on middle cohomology taken with real coefficients. By the Hodge index theorem it is given by the formula in Theorem 6.33 of Voisin’s first book on Hodge theory.

\[\sigma=\sum_{p,q=0}^{\dim X}(-1)^p\mathrm{h}^{p,q}\]

This of course only makes sense if the diamond comes from a compact Kähler manifold.

EXAMPLES:

sage: from diamond import * sage: K3().signature() -16

euler()[source]#

The topological Euler characteristic of the Hodge diamond

This is the alternating sum of the Betti numbers, so that

\[\chi_{\mathrm{top}}=\sum_{p,q=0}^{\dim X}(-1)^{p+q}\mathrm{h}^{p,q}\]

EXAMPLES:

The Euler characteristic of projective space grows linearly:

sage: from diamond import *
sage: [Pn(n).euler() for n in range(10)]
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

For Hilbert schemes of points of K3 surfaces these are the coefficients of the series expansion of the Dedekind eta-function, see A006922 in the OEIS:

sage: [hilbn(K3(), n).euler() for n in range(10)]
[1, 24, 324, 3200, 25650, 176256, 1073720, 5930496, 30178575, 143184000]
holomorphic_euler()[source]#

Holomorphic Euler characteristic

This is the Euler characteristic of the structure sheaf, so

\[\chi(X)=\sum_{i=0}^{\dim X}(-1)^i\mathrm{h}^{0,i}(X)\]

EXAMPLES:

For projective space it is 1:

sage: from diamond import *
sage: all(Pn(n).holomorphic_euler() == 1 for n in range(10))
True

For a hyperkähler variety of dimension $2n$ this number is $n+1$:

sage: all(K3n(n).holomorphic_euler() == n+1 for n in range(5))
True
hirzebruch()[source]#

Hirzebruch’s chi_y genus

For a smooth projective variety $X$ Hirzebruch’s $\chi_y$-genus is defined as

\[\chi_y(X)=\sum_{p,q=0}^{\dim X}(-1)^{p+q}\mathrm{h}^{p,q}(X)y^p\]

which shows it is the specialisation of the Hodge-Poincaré polynomial for $x=-1$. A further specialisation to $y=-1$ gives the Euler characteristic.

EXAMPLES:

For a K3 surface we have:

sage: from diamond import *
sage: K3().hirzebruch()
2*y^2 - 20*y + 2
sage: K3().hirzebruch().subs(y=-1) == K3().euler()
True

For the Hilbert square of a K3 surface we get:

sage: hilbn(K3(), 2).hirzebruch()
3*y^4 - 42*y^3 + 234*y^2 - 42*y + 3
sage: hilbn(K3(), 2).hirzebruch().subs(y=-1) == hilbn(K3(), 2).euler()
True
homological_unit()[source]#

Dimensions of $\mathrm{H}^bullet(X,O_X)$

A notion introduced by Abuaf.

hochschild()[source]#

Dimensions of the Hochschild homology

Columns of the Hodge diamond are Hochschild homology, by the Hochschild- Kostant-Rosenberg theorem.

hh()[source]#

Shorthand for HodgeDiamond.hochschild()

arises_from_variety()[source]#

Check whether the Hodge diamond can arise from a smooth projective variety

The constraints are:

  • satisfy Hodge symmetry

  • satisfy Serre symmetry

  • there is no Lefschetz twist

is_zero()[source]#

Check whether the Hodge diamond is identically zero

lefschetz_power()[source]#

Return the twist by the Lefschetz motive that is present

In other words, we see how divisible the Hodge–Poincaré polynomial is with respect to the monomial $x^iy^i$

dimension()[source]#

Dimension of the Hodge diamond

This takes twists by the Lefschetz class into account: we untwist by the maximal power and only then determine how big the diamond is.

EXAMPLES:

A point is 0-dimensional:

sage: from diamond import *
sage: point().dimension()
0

The Lefschetz diamond is also 0-dimensional:

sage: print(lefschetz())
      0
  0       0
      1
sage: lefschetz().dimension()
0
level()[source]#

Compute the level (or complexity) of the Hodge diamond

This is a measure of the width of the non-zero part of the Hodge diamond.

EXAMPLES:

The simplest case is projective space, with level zero:

sage: from diamond import *
sage: all(Pn(n).level() == 0 for n in range(10))
True

For intersections of 2 quadrics it alternates between zero and one:

sage: all(complete_intersection([2,2], 2*n).level() == 0 for n in range(5))
True
sage: all(complete_intersection([2,2], 2*n+1).level() == 1 for n in range(5))
True

A Calabi-Yau variety (e.g. a hypersurface of degree $n+1$ in $\mathbb{P}^n$) has maximal level:

sage: all(hypersurface(n+2, n).level() == n for n in range(10))
True
blowup(other, codim=None)[source]#

Compute Hodge diamond of blowup

No consistency checks are performed, this just naively applies the blowup formula from Hodge theory.

INPUT:

  • other – Hodge diamond of the center of the blowup

  • codim – codimension of the center (optional), in case it is not the Hodge diamond of an honest variety

EXAMPLES:

A cubic surface is the blowup of $\mathbb{P}^2$ in 6 points:

sage: from diamond import *
sage: Pn(2).blowup(6*point()) == hypersurface(3, 2)
True
bundle(rank)[source]#

Compute the Hodge diamond of a projective bundle

This applies the bundle formula from Hodge theory without any consistency checks.

INPUT:

  • rank: rank of the vector bundle on self

EXAMPLES:

A projective bundle on a point is a projective space:

sage: from diamond import *
sage: point().bundle(3) == Pn(2)
True

A quadric surface is a $\mathbb{P}^1$-bundle on $\mathbb{P}^1$:

sage: Pn(1).bundle(2) == hypersurface(2, 2)
True
mirror()[source]#

Compute the mirror Hodge diamond

EXAMPLES:

The mirror to a quintic 3-fold is the following:

sage: from diamond import *
sage: print(hypersurface(5, 3).mirror())
                 1
            0         0
        0       101       0
    1       1         1       1
        0       101       0
            0         0
                 1
__hash__ = None#
__weakref__#

list of weak references to the object (if defined)

Hochschild homology#

class diamond.HochschildHomology(parent, L)[source]#

This class implements some methods to work with (the dimensions of) Hochschild homology spaces, associated to the HodgeDiamond class.

The documentation is not intended to be complete, as this is mostly for my own sake.

classmethod from_list(L)[source]#

Constructor for Hochschild homology dimensions from a list.

INPUT:

  • L – a list of integers representing $\mathrm{HH}_{-n}$ to $\mathrm{HH}_n$

EXAMPLES:

sage: from diamond import *
sage: HochschildHomology.from_list([1,0,22,0,1])
Hochschild homology vector of dimension 2
classmethod from_positive(L)[source]#

Constructor for Hochschild homology dimensions from a list when only the positive part is given.

INPUT:

  • L – a list of integers representing $\mathrm{HH}_0$ to $\mathrm{HH}_n$

EXAMPLES:

sage: from diamond import *
sage: HochschildHomology.from_positive([22,0,1])
Hochschild homology vector of dimension 2
classmethod from_polynomial(f)[source]#

Constructor for Hochschild homology dimensions from Hochschild–Poincaré Laurent polynomial

INPUT

  • f – the Hochschild–Poincaré Laurent polynomial

EXAMPLES:

sage: from diamond import *
sage: x = LaurentPolynomialRing(ZZ, 'x').gen()
sage: HochschildHomology.from_polynomial(x**-2+20+x**2)
Hochschild homology vector of dimension 2
property polynomial#

EXAMPLES:

sage: from diamond import *
sage: h = HochschildHomology.from_list([1,0,22,0,1])
sage: h.polynomial
t^-2 + 22 + t^2
dimension()[source]#

Largest index i such that $\mathrm{HH}_i\neq 0$

EXAMPLES:

sage: from diamond import *
sage: h = HochschildHomology.from_list([1,0,22,0,1])
sage: h.dimension()
2
is_zero()[source]#

EXAMPLES:

sage: from diamond import *
sage: h = HochschildHomology.from_list([1,0,22,0,1])
sage: h.is_zero()
False
euler()[source]#

Euler characteristic of Hochschild homology

EXAMPLES:

sage: from diamond import *
sage: h = HochschildHomology.from_list([1,0,22,0,1])
sage: h.euler()
24
symmetric_power(k)[source]#

Hochschild homology of the Ganter–Kapranov symmetric power of a smooth and proper dg category

This is possibly only a heuristic (I didn’t check for proofs in the literature) based on the decomposition of Hochschild homology for a quotient stack, as discussed in the paper of Polishchuk–Van den Bergh.

EXAMPLES:

sage: from diamond import *
sage: k = K3().hh()
sage: k.symmetric_power(2)
Hochschild homology vector of dimension 4
sage: print(_)
range(-4, 5)   [1, 0, 23, 0, 276, 0, 23, 0, 1]
+--------------+---------------------------------+
sym(k)[source]#

Shorthand for `HochschildHomology.symmetric_power`

Constructions#

Elementary constructions#

diamond.zero()[source]#

Hodge diamond for the empty space

EXAMPLES:

Zero:

sage: from diamond import *
sage: print(zero())
  0
diamond.point()[source]#

Hodge diamond for the point

EXAMPLES:

The point:

sage: from diamond import *
sage: print(point())
  1
diamond.lefschetz()[source]#

Hodge diamond for the Lefschetz motive

This is the Hodge-Poincaré polynomial of the affine line.

EXAMPLES:

The affine line:

sage: from diamond import *
sage: print(lefschetz())
      0
  0       0
      1

We can take powers of it, to get the Hodge-Poincaré polynomial for higher- dimensional affine spaces:

sage: print(lefschetz()**3)
              0
          0       0
      0       0       0
  0       0       0       0
      0       0       0
          0       0
              1
diamond.Pn(n)[source]#

Hodge diamond for projective space of dimension $n$

INPUT:

  • n: dimension, non-negative integer

EXAMPLES:

The zero-dimensional case is a point:

sage: from diamond import *
sage: Pn(0) == point()
True

In general projective space is the sum of powers of the Lefschetz class:

sage: all(Pn(n) == sum([lefschetz()**i for i in range(n + 1)]) for n in range(1, 10))
True
diamond.hypersurface(degree, dimension)[source]#

Shorthand for a complete intersection of the given dimension where $k=1$

diamond.weighted_hypersurface(degree, weights)[source]#

Hodge diamond for a weighted hypersurface of degree d in P(w_0,...,w_n)

Implementation taken from https://github.com/jxxcarlson/math_research/blob/master/hodge.sage. If I’m not mistaken, the generalisation to weighted complete intersection depends on which polynomials are used, not just the degrees, even if the result is smooth?

INPUT:

  • degree – degree of the hypersurface

  • weights – the weights of the weighted projective space, if it is an integer we interpret it as the dimension of P^n

EXAMPLES:

Elliptic curves can be realised as hypersurfaces in 3 ways:

sage: from diamond import *
sage: weighted_hypersurface(3, 2) == weighted_hypersurface(3, [1, 1, 1])
True
sage: weighted_hypersurface(3, 2) == curve(1)
True
sage: weighted_hypersurface(4, [1, 1, 2]) == curve(1)
True
sage: weighted_hypersurface(6, [1, 2, 3]) == curve(1)
True

The Fano 3-fold 1.1 is a weighted hypersurface:

sage: fano_threefold(1, 1) == weighted_hypersurface(6, [1,1,1,1,3])
True
diamond.cyclic_cover(ramification_degree, cover_degree, weights)[source]#

Hodge diamond of a cyclic cover of weighted projective space

Implementation taken from https://github.com/jxxcarlson/math_research/blob/master/hodge.sage.

INPUT:

  • ramification_degree – degree of the ramification divisor

  • cover_degree – size of the cover

  • weights – the weights of the weighted projective space, if it is an integer we interpret it as the dimension of P^n

EXAMPLES:

Some K3 surfaces are double covers of $\mathbb{P}^2$ in a sextic curve:

sage: from diamond import *
sage: cyclic_cover(6, 2, 2) == K3()
True

The Fano 3-fold 1.1 is a double cover of $\mathbb{P}^3$ in a sextic:

sage: cyclic_cover(6, 2, 3) == fano_threefold(1, 1)
True
diamond.complete_intersection(degrees, dimension)[source]#

Hodge diamond for a complete intersection of multidegree $(d_1,\ldots,d_k)$ in $\mathbb{P}^{n+k}$

For a proof, see théorème 2.3 of exposé XI in SGA7.

INPUT:

  • degrees – the multidegree, if it is an integer we interpret it as a hypersurface

  • dimension – the dimension of the complete intersection (not of the ambient space)

EXAMPLES:

For multidegrees $(1,\ldots,1) we get a lower-dimension projective space:

sage: from diamond import *
sage: complete_intersection(1, 2) == Pn(2)
True
sage: complete_intersection([1, 1], 2) == Pn(2)
True
sage: complete_intersection([1, 1], 5) == Pn(5)
True

The Euler characteristics of cubic hypersurfaces:

sage: [complete_intersection(3, n).euler() for n in range(10)]
[3, 0, 9, -6, 27, -36, 93, -162, 351, -672]

The Euler characteristics of intersections of 2 quadrics:

sage: [complete_intersection([2, 2], n).euler() for n in range(10)]
[4, 0, 8, 0, 12, 0, 16, 0, 20, 0]

Curves and moduli spaces of sheaves on them#

diamond.curve(genus)[source]#

Hodge diamond for a curve of a given genus.

INPUT:

  • genus: the genus of the curve, non-negative integer

EXAMPLE:

A curve of genus 0 is the 1-dimensional projective space:

sage: from diamond import *
sage: curve(0) == Pn(1)
True

A curve of genus 1 is an abelian variety of dimension 1:

sage: curve(1) == abelian(1)
True

A curve of genus 2:

sage: print(curve(2))
      1
  2       2
      1
diamond.symmetric_power(n, genus)[source]#

Hodge diamond for the nth symmetric power of a curve of given genus

For the proof, see Example 1.1(1) of [MR2777820]. An earlier reference, probably in Macdonald, should exist.

  • [MR2777820] Laurentiu–Schuermann, Hirzebruch invariants of symmetric products. Topology of algebraic varieties and singularities, 163–177, Contemp. Math., 538, Amer. Math. Soc., 2011.

INPUT:

  • n – exponent of the symmetric power

  • genus – genus of the curve, a non-negative integer

EXAMPLES:

The symmetric square of a genus 3 curve:

sage: from diamond import *
sage: print(symmetric_power(2, 3))
          1
      3        3
  3       10       3
      3        3
          1

If $n=1$ we get the curve back:

sage: all(symmetric_power(1, g) == curve(g) for g in range(10))
True

If $n=0$ we get the point:

sage: symmetric_power(0, 4) == point()
True

If $n<0$ we have the empty space:

sage: symmetric_power(-1, 4) == zero()
True
diamond.jacobian(genus)[source]#

Hodge diamond for the Jacobian of a genus $g$ curve

This is an abelian variety of dimension genus, so we call abelian()

INPUT:

  • genus – genus of the curve

EXAMPLES:

The Jacobian of a genus 3 curve:

sage: from diamond import *
sage: print(jacobian(3))
              1
          3       3
      3       9       3
  1       9       9       1
      3       9       3
          3       3
              1

For the projective line we get a point:

sage: jacobian(0) == point()
True

The Jacobian of an elliptic curve is isomorphic to it:

sage: jacobian(1) == curve(1)
True
diamond.moduli_vector_bundles(rank, degree, genus)[source]#

Hodge diamond for the moduli space of vector bundles of given rank and fixed determinant of given degree on a curve of a given genus.

For the proof, see Corollary 5.1 of [MR1817504].

  • [MR1817504] del Baño, On the Chow motive of some moduli spaces. J. Reine Angew. Math. 532 (2001), 105–132.

If the Hodge diamond for the moduli space with non-fixed determinant of degree d is required, this can be obtained by:

jacobian(g) * moduli_vector_bundles(r, d, g)

INPUT:

  • rank – rank of the bundles, at least 2

  • degree – degree of the fixed determinant, coprime to rank

  • genus – genus of the curve, at least 2

EXAMPLES:

The case of rank 2, degree 1 and genus 2 is famously the intersection of 2 quadrics in $\mathbb{P}^5$:

sage: from diamond import *
sage: moduli_vector_bundles(2, 1, 2) == complete_intersection([2, 2], 3)
True
diamond.seshadris_desingularisation(genus)[source]#

Hodge diamond for Seshadri’s desingularisation of the moduli space of rank 2 bundles with trivial determinant on a curve of a given genus $g$.

For the statement, see Corollary 3.18 of [MR1895918].

  • [MR1895918] del Baño, On the motive of moduli spaces of rank two vector bundles over a curve. Compositio Math. 131 (2002), 1-30.

INPUT:

  • genus – the genus $g$, at least 2

EXAMPLES:

For $g=2$ nothing needs to be desingularised, and the answer is $\mathbb{P}^3$:

sage: from diamond import *
sage: seshadris_desingularisation(2) == Pn(3)
True

Already for $g=3$ the result is not a familiar variety, so we just check the Euler characteristic:

sage: seshadris_desingularisation(3).euler() == 112
True
diamond.moduli_parabolic_vector_bundles_rank_two(genus, alpha)[source]#

Hodge diamond for the moduli space of parabolic rank 2 bundles with fixed determinant of odd degree on a curve of genus $g$.

See Corollary 5.34 of [2011.14872].

  • [2011.14872] Fu–Hoskins–Pepin Lehalleur, Motives of moduli spaces of bundles on curves via variation of stability and flips

This is not a proof of the formula we implemented per se, but it should be correct. Also, it could be that the choice of weights give something singular / stacky. Then it’ll give bad output without warning. You have been warned.

INPUT:

  • genus – the genus of the curve

  • alpha – the weights of the parabolic bundles

diamond.quot_scheme_curve(genus, length, rank)[source]#

Hodge diamond for the Quot scheme of zero-dimensional quotients of given length of a vector bundle of given rank on a curve of given genus.

For the proof, see Proposition 4.5 of [1907.00826] (or rather, the reference [Bif89] in there)

  • [1907.00826] Bagnarol–Fantechi–Perroni, On the motive of zero-dimensional Quot schemes on a curve

Surfaces and moduli spaces of sheaves on them#

diamond.surface(genus, irregularity, h11)[source]#

Hodge diamond for a surface $S$ with given invariants

These invariants are the geometric genus, the irregularity and the middle Hodge numbers h11.

INPUT:

  • genus – geometric genus of the surface, $\dim\mathrm{H}^2(S,\mathcal{O}_S)$,

    a non-negative integer

  • irregularity – irregularity of the surface, $\dim\mathrm{H}^1(S,\mathcal{O}_S)$,

    a non-negative integer

  • h11 – middle Hodge number, $\dim\mathrm{H}^1(S,\Omega_S^1)$,

    a non-negative integer

EXAMPLES:

The projective plane:

sage: from diamond import *
sage: Pn(2) == surface(0, 0, 1)
True

A K3 surface:

sage: K3() == surface(1, 0, 20)
True
diamond.ruled(genus)[source]#

Hodge diamond for a ruled surface

These are $\mathbb{P}^1$-bundles over a curve of given genus.

INPUT:

  • genus – genus of the base curve

EXAMPLES:

For genus 0 we get Hirzebruch surfaces, whose Hodge diamond is that of the quadric surface:

sage: from diamond import *
sage: ruled(0) == hypersurface(2, 2)
True

For higher genus the Hodge diamond looks as follows:

sage: print(ruled(5))
          1
      5       5
  0       2       0
      5       5
          1
diamond.K3()[source]#

Hodge diamond for a K3 surface

EXAMPLES:

The K3 surface:

sage: from diamond import *
sage: print(K3())
          1
      0        0
  1       20       1
      0        0
          1
diamond.enriques(two=None)[source]#

Hodge diamond for an Enriques surface

It is possible to ask for the Hodge diamond of a classical or (super)singular Enriques surface in characteristic 2.

In characteristic 2 the invariants are given in Proposition 1.4.2 of [MR0986969].

  • [MR0986969] Cossec–Dolgachev, Enriques surfaces I, Progress in Mathematics, 1989

INPUT:

  • two – optional parameter to indicate the type of surface in characteristic 2

    possible values are “classical”, “singular”, “supersingular”

EXAMPLES:

An ordinary Enriques surface:

sage: from diamond import *
sage: print(enriques())
          1
      0        0
  0       10       0
      0        0
          1

Enriques surfaces in characteristic 2:

sage: print(enriques(two="classical"))
          1
      0        1
  0       12       0
      1        0
          1
sage: print(enriques(two="singular"))
          1
      1        0
  1       10       1
      0        1
          1
sage: print(enriques(two="supersingular"))
          1
      1        1
  1       12       1
      1        1
          1
diamond.hilbn(surface, n)[source]#

Hodge diamond for Hilbert scheme of n points on a smooth projective surface S

For the proof, see Theorem 2.3.14 of [MR1312161].

  • [MR1312161] Göttsche, Hilbert schemes of zero-dimensional subschemes of smooth varieties. Lecture Notes in Mathematics, 1572. Springer-Verlag, Berlin, 1994. x+196 pp.

INPUT:

  • S – Hodge diamond for smooth projective surface

  • n – number of points

diamond.nestedhilbn(surface, n)[source]#

Hodge diamond for the nested Hilbert scheme S^{[n-1,n]}

This is the unique nested Hilbert scheme of a smooth projective surface S which is itself smooth (of dimension $2n$)

Fano varieties#

These are Hodge diamonds of Fano varieties in the sense that their anticanonical bundle is ample.

The term “Fano variety” can also mean a variety parametrising linear subspaces on another variety. Some of these are Fano in the first sense, others are not (always). See e.g. diamond.fano_variety_lines_cubic().

diamond.fano_threefold(rho, ID)[source]#

Hodge diamond of a Fano threefold

INPUT:

  • rho - Picard rank

  • ID - numbering from the Mori-Mukai classification

EXAMPLES:

The 17th Fano 3-fold of rank 1 is projective threespace:

sage: from diamond import *
sage: print(fano_threefold(1, 17))
              1
          0       0
      0       1       0
  0       0       0       0
      0       1       0
          0       0
              1

The 4th Fano 3-fold of rank 1 is an intersection of 3 quadrics:

sage: fano_threefold(1, 4) == complete_intersection((2, 2, 2), 3)
True

The 27th Fano 3-fold of rank 3 is the triple product of projective lines:

sage: fano_threefold(3, 27) == Pn(1)**3
True
diamond.gushel_mukai(n)[source]#

Hodge diamond for a smooth $n$-dimensional Gushel–Mukai variety

See Proposition 3.1 of [1605.05648v3].

  • [1605.05648v3] Debarre–Kuznetsov, Gushel-Mukai varieties: linear spaces and periods

INPUT:

  • n - the dimension, where $n=1,\ldots,6$

diamond.fano_variety_intersection_quadrics_even(g, k)[source]#

Hodge diamond for the Fano variety of $i-1$-planes on the intersection of two quadrics in $\mathbb{P}^{2g+1}$, using [1510.05986v3].

  • [1510.05986v3] Chen–Vilonen–Xue, Springer correspondence, hyperelliptic curves, and cohomology of Fano varieties

INPUT:

  • g – half of the dimension of the quadrics

  • k – dimension of the linear subspaces on the intersection of quadrics, at most $g-1$

EXAMPLES:

For $k=0$ we have the intersection of two quadrics:

sage: from diamond import *
sage: fano_variety_intersection_quadrics_even(2, 0) == complete_intersection([2, 2], 2)
True
sage: fano_variety_intersection_quadrics_even(5, 0) == complete_intersection([2, 2], 8)
True

We have that for $k = g-2$ we get the moduli space of parabolic bundles on $\mathbb{P}^1$ with weight $1/2$ in $2g+3$ points:

sage: from diamond import *
sage: moduli_parabolic_vector_bundles_rank_two(0, [1/2]*5) == fano_variety_intersection_quadrics_even(2, 0)
True
sage: moduli_parabolic_vector_bundles_rank_two(0, [1/2]*9) == fano_variety_intersection_quadrics_even(4, 2)
True

For $k=g-1$ we get a finite reduced scheme of length $4^g$:

sage: from diamond import *
sage: print(fano_variety_intersection_quadrics_even(4, 3))
  256
diamond.fano_variety_intersection_quadrics_odd(g, k)[source]#

Hodge diamond for the Fano variety of $k$-planes on the intersection of two quadrics in $\mathbb{P}^{2g+1}$, using [MR3689749].

We have that for $k=g-2$ we get M_C(2,L) as above, for deg L odd.

  • [MR3689749] Chen–Vilonen–Xue, On the cohomology of Fano varieties and the Springer correspondence, Adv. Math. 318 (2017), 515–533.

EXAMPLES:

For $k=0$ we have the intersection of two quadrics:

sage: from diamond import *
sage: fano_variety_intersection_quadrics_odd(2, 0) == complete_intersection([2, 2], 3)
True
sage: fano_variety_intersection_quadrics_odd(5, 0) == complete_intersection([2, 2], 9)
True

For $k=g-2$ we recover the moduli space of rank 2 bundles with odd determinant on a curve of genus $g$:

sage: from diamond import *
sage: fano_variety_intersection_quadrics_odd(11, 9) == moduli_vector_bundles(2, 1, 11)
True

For $k=g-1$ it is the Jacobian of $C$:

sage: from diamond import *
sage: fano_variety_intersection_quadrics_odd(12, 11) == jacobian(12)
True

For other $k$ it is an interesting variety:

sage: from diamond import *
sage: fano_variety_intersection_quadrics_odd(12, 9)
Hodge diamond of size 51 and dimension 50
diamond.fano_variety_lines_cubic(n)[source]#

Hodge diamond for the Fano variety of lines on a smooth $n$-dimensional cubic hypersurface.

This follows from the “beautiful formula” or X-F(X)-relation due to Galkin–Shinder, Theorem 5.1 of [1405.5154v2].

  • [1405.5154v2] Galkin–Shinder, The Fano variety of lines and rationality problem for a cubic hypersurface

INPUT:

  • n – the dimension, where n is at least 2

EXAMPLES:

There are 27 lines on a cubic surface:

sage: from diamond import *
sage: fano_variety_lines_cubic(2) == 27*point()
True

The Fano surface of lines on a cubic threefold is a surface of general type:

sage: fano_variety_lines_cubic(3) == surface(10, 5, 25)
True

The Fano fourfold of lines on a cubic fourfold is deformation equivalent to the Hilbert square on a K3 surface:

sage: fano_variety_lines_cubic(4) == hilbn(K3(), 2)
True

Moduli spaces attached to quivers#

diamond.quiver_moduli(Q, d, **kwargs)[source]#

Hodge diamond for the moduli space of semistable quiver representations for a quiver Q, dimension vector d, and slope-stability condition mu.

Taken from Corollary 6.9 of [MR1974891]

  • [MR1974891] Reineke, The Harder-Narasimhan system in quantum groups and cohomology of quiver moduli.

INPUT:

  • Q – adjacency matrix of an acyclic quiver

  • d – dimension vector

  • mu – stability condition, these can be produced using slope(), if left unspecified then the canonical stability condition is used

The canonical stability condition for dimension vector d is given by the antisymmetrised Euler form pairing with d.

EXAMPLES:

Let’s consider moduli spaces for the Kronecker quiver:

sage: from diamond import *
sage: def kronecker(d): return matrix([[0, d], [0, 0]])

For the 2-Kronecker quiver and dimension vector (1,1) a representation is given by 2 scalars, and the stability condition (1,-1) encodes that they are not both zero. This way we obtain the projective line:

sage: quiver_moduli(kronecker(2), (1, 1), mu=slope((1, -1))) == Pn(1)
True

There is only one relevant stability chamber here, which contains the canonical stability condition. Thus we get the same result not specifying the stability function:

sage: quiver_moduli(kronecker(2), (1, 1)) == Pn(1)
True

Similar to the first example, the $d$-Kronecker quiver gives rise to projective spaces:

sage: all(quiver_moduli(kronecker(d), (1, 1)) == Pn(d - 1) for d in range(3, 10))
True

We can also realise Grassmannians using the $d$-Kronecker quiver, for dimension vector $(1,k)$ and stability condition $(k,1)$ (or the canonical stability condition) we get the Grassmannian $\operatorname{Gr}(k,d)$:

sage: quiver_moduli(kronecker(4), (1, 2), mu=slope((2, 1))) == grassmannian(2, 4)
True
sage: quiver_moduli(kronecker(7), (1, 3)) == grassmannian(3, 7)
True

Any stability function in the same chamber gives the same variety:

sage: quiver_moduli(kronecker(7), (1, 3)) == quiver_moduli(kronecker(7), (1, 3), mu=slope((1, -1)))
True

The following is an example of wall-crossing, and thus different varieties:

sage: M = matrix([[0, 1, 1], [0, 0, 2], [0, 0, 0]])
sage: quiver_moduli(M, (1, 1, 1)) == Pn(2).blowup(point())
True
sage: quiver_moduli(M, (1, 1, 1), mu=slope((1, 0, 0))) == Pn(2)
True

The flag variety $\operatorname{Fl}(n,r_1,\ldots,r_s)$ is also a quiver moduli space, for $\mathrm{A}_s$ quiver prefixed with an $n$-Kronecker quiver, dimension vector $(1,r_1,\ldots,r_s)$ with $r_1>\ldots>r_s$ and stability condition the indicator function at the first vertex:

sage: def flags(n, s): return matrix(ZZ, s+1, s+1, lambda i,j: 0 if i != j-1 else (n if i == 0 else 1))
sage: quiver_moduli(flags(4, 1), (1, 1)) == Pn(3)
True
sage: quiver_moduli(flags(3, 2), (1, 2, 1)) == fano_threefold(2, 32)
True
sage: quiver_moduli(flags(5, 3), (1, 4, 3, 1)) == partial_flag_variety("A4", [2])
True

Hyperkähler varieties#

diamond.K3n(n)[source]#

Hodge diamond of the Hilbert scheme of $n$ points on a K3 surface

This is the first family of hyperkähler varieties, constructed by Beauville.

INPUT:

  • n – number of points

EXAMPLES:

For $n=1$ we have a K3 surface:

sage: from diamond import *
sage: K3n(1) == K3()
True

For $n\geq 2$ we have second Betti number 23:

sage: all(K3n(n).betti()[2] == 23 for n in range(2, 5))
True
diamond.generalised_kummer(n)[source]#

Hodge diamond of the $n$th generalised Kummer variety

For the proof, see Corollary 1 of [MR1219901].

  • [MR1219901] Göttsche–Soergel, Perverse sheaves and the cohomology of Hilbert schemes of smooth algebraic surfaces. Math. Ann. 296 (1993), no. 2, 235–245.

EXAMPLES:

The first generalised Kummer is just a point:

sage: from diamond import *
sage: generalised_kummer(1) == point()
True

The second generalised Kummer is the Kummer K3 surface:

sage: generalised_kummer(2) == K3()
True

The higher generalised Kummers are hyperkähler varieties with second Betti number 7:

sage: all(generalised_kummer(n).betti()[2] == 7 for n in range(3, 10))
True
diamond.ogrady6()[source]#

Hodge diamond for O’Grady’s exceptional 6-dimensional hyperkähler variety

For the proof, see Theorem 1.1 of [MR3798592].

  • [MR3798592] Mongardi–Rapagnetta–Saccà, The Hodge diamond of O’Grady’s six-dimensional example. Compos. Math. 154 (2018), no. 5, 984–1013.

EXAMPLES:

The second Betti number is 8:

sage: from diamond import *
sage: ogrady6().betti()[2] == 8
True
diamond.ogrady10()[source]#

Hodge diamond for O’Grady’s exceptional 10-dimensional hyperkähler variety

For the proof, see theorem A of [1905.03217]

  • [1905.03217] de Cataldo–Rapagnetta–Saccà, The Hodge numbers of O’Grady 10 via Ngô strings

EXAMPLES:

The second Betti number is 24:

sage: from diamond import *
sage: ogrady10().betti()[2] == 24
True

Other#

diamond.Mzeronbar(n)[source]#

Hodge diamond for the moduli space of $n$-pointed stable curves of genus 0

Taken from (0.12) in [MR1363064]. Keel’s original paper has a recursion on page 550, but that seems to not work.

  • [MR1363064] Manin, Generating functions in algebraic geometry and sums over trees

EXAMPLES:

The first few cases are a point, the projective line, and the blowup of $\mathbb{P}^2$ in 4 points:

sage: from diamond import *
sage: Mzeronbar(3) == point()
True
sage: Mzeronbar(4) == Pn(1)
True
sage: Mzeronbar(5) == Pn(2).blowup(4*point())
True