Chow rings

QuiverTools implements Chow rings computations for quivers and their representations. There also is an implementation of Bundle objects in the Chow ring, which enable tensor calculus in the Chow ring.

Bundle objects can also carry Teleman weights, and these behave well with respect to tensor calculus.

A QuiverModuliSpace comes with an intermediary structure, ChowRing, which is functionally just a container for various Chow ring data.

QuiverTools.ChowRingType

Summary

struct ChowRing

A Type used to encode various Chow ring data.

Fields

parent :: Any
ring :: Singular.PolyRing{Singular.n_Q}
chi :: AbstractVector{Int}
point :: Union{Singular.spoly{Singular.n_Q},UndefInitializer}
todd :: Union{Singular.spoly{Singular.n_Q},UndefInitializer}
_R :: Singular.PolyRing{Singular.n_Q}
_inclusion :: Singular.SAlgHom{Singular.Rationals}

source

Presentation of Chow rings

Chow rings must be initialized manually, passing a choice of linearization to the constructor. If no linearization is passed, the default one is used.

QuiverTools.chow_ringFunction
chow_ring(Q::Quiver, d::AbstractVector{Int}, theta::AbstractVector{Int}=canonical_stability(Q, d); chi::AbstractVector{Int}=extended_gcd(d)[2])

Compute the Chow ring of the moduli space of theta-semistable representations of Q with dimension vector d, for a choice of linearization a.

This method of the function chow_ring also returns the ambient ring $R$ and the inclusion morphism.

Input

  • Q::Quiver: a quiver.
  • d::AbstractVector{Int}: a dimension vector.
  • theta::AbstractVector{Int}: a stability parameter. Default is canonical_stability(Q, d).
  • chi: a linearization. Default is the extended gcd of extended_gcd(d)[2].

Output

A tuple containing:

  • the Chow ring of the moduli space,
  • the polynomial ring above it,
  • the inclusion map $\iota : A \to R$.

Examples

The Chow ring for the projective line has two generators:

julia> Q = kronecker_quiver(2); M = QuiverModuliSpace(Q, [1, 1]);

julia> CH = chow_ring(M);

julia> QuiverTools.gens(QuiverTools.quotient_ideal(CH))
2-element Vector{Singular.spoly{Singular.n_Q}}:
 x21
 x11^2

The Chow ring for our favourite 6-fold has, in this implementation, 16 generators:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> CH = chow_ring(M); I = QuiverTools.quotient_ideal(CH);

julia> length(QuiverTools.gens(I))
16
source
chow_ring(M::QuiverModuliSpace; chi::Union{AbstractVector{Int},UndefInitializer}=undef)

Compute the Chow ring of the moduli space M for the given linearization chi.

Input

  • M::QuiverModuliSpace: a moduli space of representations of a quiver.
  • chi::AbstractVector{Int}: a choice of linearization for the trivial line bundle. Default is extended_gcd(M.d)[2].

Output

  • the Chow ring of the moduli space.
source

chow_ring(F::Bundle)

source
QuiverTools.point_classFunction
point_class(M::QuiverModuliSpace)

Compute the point class of the moduli space M.

Input

  • M::QuiverModuliSpace: a moduli space of representations of a quiver.

Output

  • the point class of the moduli space, as a polynomial in its Chow ring.

Examples

A projective 7-fold:

julia> Q = kronecker_quiver(8);

julia> M = QuiverModuliSpace(Q, [1, 1]);

julia> chow_ring(M; chi=[1, 0]); point_class(M)
x21^7

Our favourite 6-fold:

julia> Q = kronecker_quiver(3);

julia> M = QuiverModuliSpace(Q, [2, 3]);

julia> point_class(M)
x23^2
source
QuiverTools.todd_classFunction
todd_class(M::QuiverModuliSpace)

Compute the Todd class of the moduli space M.

Input

  • M::QuiverModuliSpace: a moduli space of representations of a quiver.

Output

  • the Todd class of the moduli space, as a polynomial in its Chow ring.

Examples

The Todd class of our favourite 3-Kronecker quiver moduli:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> todd_class(M)
-17//8*x12*x21 + x21^2 + 823//360*x12*x22 - 823//1080*x22^2 + 553//1080*x21*x23 - 77//60*x22*x23 + x23^2 + 5//12*x12 - 3//2*x21 + 9//8*x23 + 1
source
QuiverTools.chern_class_line_bundleFunction
chern_class_line_bundle(M::QuiverModuliSpace, eta::AbstractVector{Int})

Compute the first Chern class of the line bundle L(eta).

This is given by $L(eta) = \bigoplus_{i \in Q_0} \det(U_i)^{-eta_i}$.

Input

  • M::QuiverModuliSpace: a moduli space of representations of a quiver.
  • eta::AbstractVector{Int]: a choice of linearization for the trivial line bundle.

Output

  • the first Chern class of the line bundle L(eta) as a polynomial.

Examples

The line bundles $\mathcal{O}(i)$ on the projective line:

julia> Q = kronecker_quiver(2); M = QuiverModuliSpace(Q, [1, 1]);

julia> l = chern_class_line_bundle(M, [1, -1])
-x11

The line bundle corresponding to the canonical stability condition on our favourite 6-fold:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> chern_class_line_bundle(M, [9, -6])
-3*x21
source
QuiverTools.chern_character_line_bundleFunction
chern_character_line_bundle(M::QuiverModuliSpace, eta::AbstractVector{Int})

Compute the Chern character of the line bundle L(eta).

Input

  • M::QuiverModuliSpace: a moduli space of representations of a quiver.
  • eta::AbstractVector{Int}: a choice of linearization for the trivial line bundle.

Output

  • the Chern character of the line bundle L(eta).

Examples

Some line bundles on the projective line:

julia> Q = kronecker_quiver(2); M = QuiverModuliSpace(Q, [1, 1]);

julia> chern_character_line_bundle(M, [1, -1])
-x11 + 1

Some Chern characters for our favourite 6-fold:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> chern_character_line_bundle(M, [3, -2])
1//720*x21^6 - 1//120*x21^5 + 1//24*x21^4 - 1//6*x21^3 + 1//2*x21^2 - x21 + 1
source
QuiverTools.integralFunction
integral(M::QuiverModuliSpace, f)

Computes the integral of f according to the Hirzebruch-Riemann-Roch theorem.

In other words, it computes the Euler characteristic of the vector bundle whose Chern character is f.

Input

  • M::QuiverModuliSpace: a moduli space of representations of a quiver.
  • f: the Chern character in to integrate.

Output

  • the integral of f.

Examples

The integral of $\mathcal{O}(i)$ on the projective line for some is.

julia> Q = kronecker_quiver(2); M = QuiverModuliSpace(Q, [1, 1]);

julia> L = chern_character_line_bundle(M, [1, -1]);

julia> [integral(M, L^i) for i in 0:5]
6-element Vector{Singular.n_Q}:
 1
 2
 3
 4
 5
 6

Hilbert series for the 3-Kronecker quiver as in our favourite 6-fold:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> L = chern_character_line_bundle(M, [3, -2]);

julia> [integral(M, L^i) for i in 0:5]
6-element Vector{Singular.n_Q}:
 1
 20
 148
 664
 2206
 5999
source

Bundle objects

QuiverTools.BundleType

Summary

mutable struct Bundle

An abstract bundle on a quiver moduli. It is represented in practice by its Chern character.

Fields

parent :: ChowRing
rank :: Int
chern_character :: Singular.spoly{Singular.n_Q}
chern_class :: Dict{Int,Singular.spoly{Singular.n_Q}}
teleman_weights :: Dict{<:HNTypes,Vector{Int}}

source
AbstractAlgebra.degreeFunction
degree(F::Bundle)

Compute the degree of the bundle F. If rank(F) is larger than $1$, returns the degree of the determinant of F.

Input

  • F::Bundle: a bundle.

Output

  • the degree of F.

Example

The degrees of canonical bundles on the first projective spaces:

julia> d = [1, 1]; Pn = map(i -> QuiverModuliSpace(kronecker_quiver(i + 1), d), 1:5);

julia> omega = map(canonical_bundle, Pn);

julia> omega = map(dual, omega);

julia> map(degree, omega)
5-element Vector{Singular.spoly{Singular.n_Q}}:
 2
 9
 64
 625
 7776

An example from [arXiv:2411.15125]:

julia> Q = Quiver("1-2,1-3,2---3"); d = [1, 1, 1]; a = [1, 1, -1];

julia> M = QuiverModuliSpace(Q, d); chow_ring(M; chi=a);

julia> F = dual(canonical_bundle(M))
Bundle of rank 1

julia> chern_class(F)
2*x31 + 1

julia> degree(F)
56
source

A line bundle descending from a linearization above can be computed.

QuiverTools.line_bundleFunction
line_bundle(M::QuiverModuliSpace, eta::AbstractVector{Int})

Construct the descent of L(eta) on the quiver moduli space M.

Input

  • M::QuiverModuliSpace: a quiver moduli space.
  • eta::AbstractVector{Int}: a dimension vector.

Output

  • the line bundle on M with Chern class chern_class_line_bundle(M, eta).

Examples

The ample generator of the Picard group of our favourite 6-fold:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> chow_ring(M; chi=[-1, 1]);

julia> H = line_bundle(M, [3, -2]);

julia> chern_class(H)
-x21

julia> teleman_weights(H)
Dict{HNType{2}, Vector{Int64}} with 7 entries:
  [[2, 2], [0, 1]]         => [-30]
  [[2, 1], [0, 2]]         => [-40]
  [[1, 0], [1, 2], [0, 1]] => [-40]
  [[1, 0], [1, 3]]         => [-135]
  [[1, 0], [1, 1], [0, 2]] => [-105]
  [[1, 1], [1, 2]]         => [-5]
  [[2, 0], [0, 3]]         => [-90]
source

Some special bundles can be computed out of the box.

QuiverTools.canonical_bundleFunction
canonical_bundle(M::QuiverModuliSpace)

Compute the canonical bundle on the quiver moduli space M.

If $d$ is $theta$-coprime and amply stable, the canonical bundle is described in [Proposition 4.2, MR4352662].

This function computes both the Chern character and the Teleman weights of the canonical bundle.

Input

  • M::QuiverModuliSpace: a quiver moduli space.

Output

  • the canonical bundle on M.

Example

On various projective spaces:

julia> d = [1, 1]; Pn = map(i -> QuiverModuliSpace(kronecker_quiver(i + 1), d), 1:5);

julia> omega = map(canonical_bundle, Pn);

julia> map(chern_class, omega)
5-element Vector{Singular.spoly{Singular.n_Q}}:
 2*x11
 3*x11
 4*x11
 5*x11
 6*x11

julia> map(teleman_weights, omega)
5-element Vector{Dict{HNType{2}, Vector{Int64}}}:
 Dict([[1, 0], [0, 1]] => [8])
 Dict([[1, 0], [0, 1]] => [18])
 Dict([[1, 0], [0, 1]] => [32])
 Dict([[1, 0], [0, 1]] => [50])
 Dict([[1, 0], [0, 1]] => [72])

On our favourite 6-fold:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> omega = canonical_bundle(M);

julia> chern_class(omega)
3*x21

julia> QuiverTools.teleman_weights(omega)
Dict{HNType{2}, Vector{Int64}} with 7 entries:
  [[2, 2], [0, 1]]         => [90]
  [[2, 1], [0, 2]]         => [120]
  [[1, 0], [1, 2], [0, 1]] => [120]
  [[1, 0], [1, 3]]         => [405]
  [[1, 0], [1, 1], [0, 2]] => [315]
  [[1, 1], [1, 2]]         => [15]
  [[2, 0], [0, 3]]         => [270]
source
QuiverTools.universal_bundleFunction
universal_bundle(M:::QuiverModuliSpace, i::Int)

Compute the i-th universal bundle of M.

This function computes both the Chern classes and the Teleman weights of the universal bundle.

To use this method, the moduli space M must have a linearization. If not, this method will initialize the Chow ring of M by calling chow_ring(M) and it will use the default linearization.

Input

  • M::QuiverModuliSpace: a quiver moduli space.
  • i::Int: the universal bundle on the i-th vertex of the quiver.

Output

  • the i-th universal bundle on M.

Example

On the projective line:

julia> Q = kronecker_quiver(2); d = [1, 1];

julia> M = QuiverModuliSpace(Q, d); chow_ring(M; chi=[1, 0]);

julia> u1, u2 = universal_bundle(M, 1), universal_bundle(M, 2);

julia> map(chern_class, [u1, u2])
2-element Vector{Singular.spoly{Singular.n_Q}}:
 x11 + 1
 x21 + 1

julia> map(teleman_weights, [u1, u2])
2-element Vector{Dict{HNType{2}, Vector{Int64}}}:
 Dict([[1, 0], [0, 1]] => [0])
 Dict([[1, 0], [0, 1]] => [-4])

On our favourite 6-fold:

julia> Q = kronecker_quiver(3); M = QuiverModuliSpace(Q, [2, 3]);

julia> chow_ring(M; chi=[-1, 1]);

julia> u1, u2 = universal_bundle(M, 1), universal_bundle(M, 2);

julia> map(chern_character, [u1, u2])
2-element Vector{Singular.spoly{Singular.n_Q}}:
 1//6*x12*x21 + 1//2*x21^2 + 1//12*x12*x22 - 1//36*x22^2 - 7//72*x21*x23 - 1//120*x22*x23 - 1//720*x23^2 - x12 + x21 - 1//2*x23 + 2
 2//3*x12*x21 + 1//2*x21^2 - 1//6*x12*x22 - 1//2*x21*x22 + 1//12*x22^2 + 1//24*x21*x23 + 1//180*x22*x23 + x21 - x22 + 3

julia> w = map(teleman_weights, [u1, u2]);

julia> w[1]
Dict{HNType{2}, Vector{Int64}} with 7 entries:
  [[2, 2], [0, 1]]         => [15, 15]
  [[2, 1], [0, 2]]         => [20, 20]
  [[1, 0], [1, 2], [0, 1]] => [25, 15]
  [[1, 0], [1, 3]]         => [90, 45]
  [[1, 0], [1, 1], [0, 2]] => [60, 45]
  [[1, 1], [1, 2]]         => [5, 0]
  [[2, 0], [0, 3]]         => [45, 45]

julia> w[2]
Dict{HNType{2}, Vector{Int64}} with 7 entries:
  [[2, 2], [0, 1]]         => [15, 15, 0]
  [[2, 1], [0, 2]]         => [20, 10, 10]
  [[1, 0], [1, 2], [0, 1]] => [15, 15, 10]
  [[1, 0], [1, 3]]         => [45, 45, 45]
  [[1, 0], [1, 1], [0, 2]] => [45, 30, 30]
  [[1, 1], [1, 2]]         => [5, 0, 0]
  [[2, 0], [0, 3]]         => [30, 30, 30]
source

Tensor calculus

QuiverTools.dualFunction
dual(F::Bundle)

Compute the dual bundle of F.

Input

  • F::Bundle: a bundle.

Output

  • the dual bundle of F.

Example

On the projective line:

julia> Q = kronecker_quiver(2); d = [1, 1]; a = [1, 0];

julia> M = QuiverModuliSpace(Q, d); chow_ring(M; chi=a);

julia> td = Bundle(M, todd_class(M))
Bundle of rank 1

julia> chern_character(dual(td))
-x21 + 1

On our favourite 6-fold:

julia> Q, d = kronecker_quiver(3), [2, 3];

julia> M = QuiverModuliSpace(Q, d); chow_ring(M; chi=[-1, 1]);

julia> td = Bundle(M, todd_class(M));

julia> chern_character(td)
-17//8*x12*x21 + x21^2 + 823//360*x12*x22 - 823//1080*x22^2 + 553//1080*x21*x23 - 77//60*x22*x23 + x23^2 + 5//12*x12 - 3//2*x21 + 9//8*x23 + 1


julia> tdd = dual(td)
Bundle of rank 1

julia> chern_character(tdd)
17//8*x12*x21 + x21^2 + 823//360*x12*x22 - 823//1080*x22^2 + 553//1080*x21*x23 + 77//60*x22*x23 + x23^2 + 5//12*x12 + 3//2*x21 - 9//8*x23 + 1
source
QuiverTools.exterior_powerFunction
exterior_power(F::Bundle, k::Int)

Compute the k-th exterior power of F.

Input

  • F::Bundle: a bundle.
  • k::Int: the degree of the exterior power.

Output

  • the k-th exterior power of F.

Example

On the projective line:

julia> Q = kronecker_quiver(2); d = [1, 1]; a = [1, 0];

julia> M = QuiverModuliSpace(Q, d); chow_ring(M; chi=a);

julia> td = Bundle(M, todd_class(M))
Bundle of rank 1

julia> F = 3*td
Bundle of rank 3

julia> chern_character(F)
3*x21 + 3

julia> W = map(i -> exterior_power(F, i), 0:4);

julia> map(w -> (rank(w), chern_character(w)), W)
5-element Vector{Tuple{Int64, Singular.spoly{Singular.n_Q}}}:
 (1, 1)
 (3, 3*x21 + 3)
 (3, 6*x21 + 3)
 (1, 3*x21 + 1)
 (0, 0)
source
QuiverTools.symmetric_powerFunction
symmetric_power(F::Bundle, k::Int)

Compute the k-th symmetric power of F.

Input

  • F::Bundle: a bundle.
  • k::Int: the degree of the symmetric power.

Output

  • the k-th symmetric power of F.

Example

On the projective line:

julia> Q = kronecker_quiver(2); d = [1, 1]; a = [1, 0];

julia> M = QuiverModuliSpace(Q, d); chow_ring(M; chi=a);

julia> td = Bundle(M, todd_class(M));

julia> F = 3*td
Bundle of rank 3

julia> chern_character(F)
3*x21 + 3

julia> W = map(i -> symmetric_power(F, i), 0:4);

julia> map(w -> (rank(w), chern_character(w)), W)
5-element Vector{Tuple{Int64, Singular.spoly{Singular.n_Q}}}:
 (1, 1)
 (3, 3*x21 + 3)
 (6, 12*x21 + 6)
 (10, 30*x21 + 10)
 (15, 60*x21 + 15)
source
QuiverTools.detFunction
det(F::Bundle)

Compute the determinant of F. This is the top exterior power of F.

source