Cohomology
Let $X$ be a GKM space with respect to the complex torus $T$. By [GKM98] and [GZ01, Theorem 1.7.3], we have the following description of its equivariant cohomology ring $H^*_T(X;\mathbb{Q})$.
Each fixed point $x\in X$ gives a ring homomorphism $H^*_T(X;\mathbb{Q})\rightarrow H^*_T(\{x\};\mathbb{Q})\cong \mathbb{Q}[\mathfrak{t}]$. We may combine these maps by taking all fixed points at once. Let $V$ be the set of fixed points of $X$ and $E$ the set of $T$-invariant rational curves. That is, $V$ are the vertices of the GKM graph and $E$ the edges. Then the map
\[ H^*_T(X;\mathbb{Q}) \longrightarrow \bigoplus_{x\in V} \mathbb{Q}[\mathfrak{t}]\]
is injective and its image consists of all $(f_x)_{x\in V}$ such that $f_{\text{src}(e)}\equiv f_{\text{dst}(e)}$ mod $w(e)$ for all edges $e\in E$, where $w(e)$ is the weight of $e$.
We may further identify $\mathbb{Q}[\mathfrak{t}]\cong \mathbb{Q}[t_1,\dots,t_r]$ where $r=\dim_{\mathbb{C}}(T)$. Hence, this package represents elements of $H^*_T(X;\mathbb{Q})$ as tuples of polynomials indexed by vertices of the GKM graph.
The function equivariant_coefficient_ring returns the coefficient ring of the cohomology ring.
julia> G = projective_space(GKMGraph, 2);
julia> S = equivariant_coefficient_ring(G) # == \mathbb{Q}[t_1,\dots,t_r] == H^*_T(\{x\};\mathbb{Q})
Multivariate polynomial ring in 3 variables t1, t2, t3
over rational fieldIn order to construct an element of the cohomology ring of G, we first define a vector of elements of S of length num_vertices(G), such that each entry is the localization of that class to the vertex number. After that, we apply polynomial_class to that vector. This will check if the vector represents an element of the cohomology ring. If this check fails, we get an error. For example, the elements zero and one of the cohomology ring can be show as follows:
julia> v0 = [zero(S) for _ in 1:num_vertices(G)] # we constructed the vector
3-element Vector{QQMPolyRingElem}:
0
0
0
julia> polynomial_class(G, v0)
GKM class with restrictions:
[0, 0, 0]
julia> v1 = [one(S) for _ in 1:num_vertices(G)]
3-element Vector{QQMPolyRingElem}:
1
1
1
julia> polynomial_class(G, v1)
GKM class with restrictions:
[1, 1, 1]Taking a vector that does not satisfy the condition $f_{\text{src}(e)}\equiv f_{\text{dst}(e)}$ mod $w(e)$ leads to an error.
julia> v2 = [one(S) for _ in 1:num_vertices(G)];
julia> v2[1] = zero(S);
julia> polynomial_class(G, v2)
ERROR: ArgumentError: the restrictions do not satisfy the polynomial GKM edge relations
Stacktrace:General functions
GKMtools.GKMClass — Type
A GKM cohomology class, stored by its fixed-point restrictions.
GKMtools.is_gkm_spline — Function
is_gkm_spline(G, values) -> Bool
is_gkm_spline(c::GKMClass) -> BoolReturn whether the restrictions satisfy the polynomial GKM relations. For each edge $e=(v,w)$ of weight $α$, this requires values[v] - values[w] to be divisible by $α$ in $H_T^*(pt)$.
Examples
Standard functions for accessing cohomology classes always yield GKM classes:
julia> G = projective_space(GKMGraph, 1);
julia> is_gkm_spline(point_class(G, 1))
trueMoreover, equivariant cohomology is a ring and a module over the coefficient ring:
julia> is_gkm_spline(point_class(G, 1)^2 * point_class(G, 2))
trueHowever, it is possible to cook up non-GKM classes manually. In the example below, $e$ is the unique edge of the GKM graph of $\mathbb{P}^1$, and $t_1^2 - t_2$ is not divided by $w(e)=t_1-t_2$. Here,
julia> (t1, t2) = gens_coeffRing(G);
julia> (e1, e2) = gens_cohomRing(G);
julia> c = t1^2 * e1 + t2 * e2
GKM class with restrictions:
[t1^2, t2]
julia> is_gkm_spline(c)
falseOscar.restrictions — Function
restrictions(c::GKMClass)Return a vector representing the fixed-point restrictions of c, ordered by the vertices of its GKM graph.
julia> G = projective_space(GKMGraph, 2);
julia> c = point_class(G, 1)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]
julia> restrictions(c)
3-element Vector{AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}}:
t1^2 - t1*t2 - t1*t3 + t2*t3
0
0GKMtools.weight_class — Function
weight_class(G, e::Edge)Return the equivariant first Chern class represented by the weight of e. The result is an element of the localized equivariant coefficient ring of G.
Examples
julia> H7 = gkm_graph_of_toric(hirzebruch_surface(NormalToricVariety, 7))
GKM graph with 4 nodes, valency 2 and axial function:
2 -> 1 => (-1, 0, 1, 0)
3 -> 2 => (-7, -1, 0, 1)
4 -> 1 => (0, -1, -7, 1)
4 -> 3 => (1, 0, -1, 0)
Algorithmic connection for GKM graph with 4 nodes and valency 2
julia> weight_class(H7, Edge(3, 2))
-7*t1 - t2 + t4GKMtools.gens_coeffRing — Function
gens_coeffRing(G)Return the generators of the equivariant coefficient ring of G, that is the fraction field of $H^*_T(\mathrm{pt})$. The result is a vector of the same length as the torus rank of G.
julia> G = projective_space(GKMGraph, 2);
julia> gens_coeffRing(G)
3-element Vector{AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}}:
t1
t2
t3GKMtools.gens_cohomRing — Function
gens_cohomRing(G)Return the fixed-point basis of the localized equivariant cohomology of G, with restrictions equal to 1 at one vertex and 0 at all others. These basis elements need not satisfy the polynomial GKM edge relations.
julia> G = projective_space(GKMGraph, 2);
julia> g = gens_cohomRing(G)
3-element Vector{GKMClass{GKMGraph{ZZRingElem, GKMtools.FlagVertex{Tuple{Int64, Int64, Int64}}, FlagWeight{ZZRingElem}}, AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}}}:
GKM class with 3 nodes
GKM class with 3 nodes
GKM class with 3 nodes
julia> g[1]
GKM class with restrictions:
[1, 0, 0]GKMtools.unit_cohomology_ring — Function
unit_cohomology_ring(G)Return the multiplicative identity in the localized GKM cohomology of G. Its fixed-point restriction equals 1 at every vertex.
GKMtools.localize_at_vertex — Function
localize_at_vertex(G, c::GKMClass, v::Int)
localize_at_vertex(G, c::GKMClass, label::String)Return the fixed-point restriction of c at vertex index v or at the vertex with the given label. Throw an error if c belongs to another graph or the vertex does not exist.
julia> G = projective_space(GKMGraph, 2);
julia> (t1, t2, t3) = gens(equivariant_coefficient_ring(G));
julia> values = [t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0];
julia> c = polynomial_class(G, values)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]
julia> localize_at_vertex(G, c, 1)
t1^2 - t1*t2 - t1*t3 + t2*t3
julia> localize_at_vertex(G, c, 2)
0GKMtools.localize — Function
localize(c::GKMClass)Extend every restriction of c to the fraction field of $H_T^*(\mathrm{pt})$. If c is already localized, return it unchanged.
julia> G = projective_space(GKMGraph, 2);
julia> (t1, t2, t3) = gens(equivariant_coefficient_ring(G));
julia> values = [t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0];
julia> c = polynomial_class(G, values)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]
julia> c_localized = localize(c)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]
julia> c_delocalized = delocalize(G, c_localized)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]
julia> c == c_delocalized
true
julia> c[1]
t1^2 - t1*t2 - t1*t3 + t2*t3
julia> parent(c[1])
Multivariate polynomial ring in 3 variables t1, t2, t3
over rational field
julia> parent(c_localized[1])
Fraction field
of multivariate polynomial ring in 3 variables over QQGKMtools.delocalize — Function
delocalize(G, c::GKMClass; check=true)Convert a localized class to a polynomial GKM class on G.
Throw an ArgumentError if a restriction has a genuine denominator. When check is true, also verify the polynomial GKM edge relations.
Nemo.integrate — Function
integrate(c)
integrate(c, e::Edge)
integrate(c, source::String, destination::String)Integrate the GKM class c by equivariant localization.
With no edge argument, return the Atiyah–Bott sum over all vertices,
\[ \sum_{v\in V} \frac{c|_v}{e_T(T_vG)}.\]
With an edge or its endpoint labels, integrate over the corresponding invariant curve and return the quotient of (c|_v-c|_w) and weight_class(G,e).
The result belongs to the localized equivariant coefficient ring. Throw an ArgumentError if the supplied edge is not an edge of graph(c).
Example
julia> P2 = projective_space(GKMGraph, 2);
julia> integrate(first_chern_class(P2), Edge(1, 2))
3In contrast to integrate_gkm_class, we can also integrate tuples $(f_v)_{v\in X^T}$ that do not satisfy is_gkm_spline(c). For example, the following class is not a GKM spline, but we can still integrate it over the edge from vertex 1 to vertex 2:
julia> P1 = projective_space(GKMGraph, 1);
julia> (t1, t2) = gens_coeffRing(P1);
julia> (e1, e2) = gens_cohomRing(P1);
julia> c = t1^2 * e1 + t2 * e2
GKM class with restrictions:
[t1^2, t2]
julia> is_gkm_spline(c)
false
julia> integrate(c)
(-t1^2 + t2)//(t1 - t2)GKMtools.integrate_gkm_class — Function
integrate_gkm_class(c)Check that is_gkm_spline(c) is true, throwing an ArgumentError otherwise, then integrate c. The result is represented in the localized equivariant coefficient ring, as for integrate(c).
Examples
julia> P2 = projective_space(GKMGraph, 2);
julia> integrate_gkm_class(point_class(1, P2))
1
julia> P2inP1 = subgraph_from_vertices(P2, [1, 2]);
julia> pd = poincare_dual(P2inP1);
julia> integrate_gkm_class(pd)
0
julia> integrate_gkm_class(pd^2)
1
julia> (t1, t2, t3) = gens_coeffRing(P2);
julia> integrate_gkm_class(t3 * pd^2 + (t2^2 - t1)*point_class(3, P2))
-t1 + t2^2 + t3GKMtools.equivariant_coefficient_ring — Function
equivariant_coefficient_ring(G)
equivariant_coefficient_ring(H::GKMCohomology)Return the polynomial coefficient ring $H_T^*(pt)$ associated with a GKM graph or its cohomology parent.
julia> G = projective_space(GKMGraph, 2);
julia> equivariant_coefficient_ring(G)
Multivariate polynomial ring in 3 variables t1, t2, t3
over rational fieldGKMtools.polynomial_gkm_ring — Function
polynomial_gkm_ring(G)Return the internal struct giving the Cohomology on the GKM graphG.
julia> G = projective_space(GKMGraph, 2);
julia> polynomial_gkm_ring(G)
GKM cohomology ring with 3 vertices
Coefficient ring: Multivariate polynomial ring in 3 variables over QQGKMtools.polynomial_class — Function
polynomial_class(G, values; check=true)Construct a GKMClass over $H_T^*(\mathrm{pt})$ from its fixed-point restrictions. The length of values must equal the number of vertices of G.
When check is true, throw an ArgumentError if the restrictions do not satisfy the polynomial GKM edge relations. See also localized_class for non-polynomial restrictions. Use localize and delocalize for converting and deconverting a localized class to a polynomial class.
julia> G = projective_space(GKMGraph, 2);
julia> (t1, t2, t3) = gens(equivariant_coefficient_ring(G));
julia> values = [t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0];
julia> polynomial_class(G, values)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]Subvarieties
Oscar.IntersectionTheory.point_class — Function
point_class(G::AbstractGKMGraph, v::Int)
point_class(v::Int, G::AbstractGKMGraph)
point_class(G::AbstractGKMGraph, label::String)
point_class(label::String, G::AbstractGKMGraph)Return the equivariant cohomology class Poincaré dual to the fixed point at vertex v, or at the vertex with the given label. Its only nonzero restriction is the equivariant Euler class of the tangent representation at that vertex.
Throw an error when the vertex index or label does not exist.
Examples
julia> P2 = projective_space(GKMGraph, 2);
julia> point_class(1, P2)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]
julia> F3 = flag_variety(GKMGraph, [1, 1, 1]);
julia> point_class(1, F3)
GKM class with restrictions:
[-t1^2*t2 + t1^2*t3 + t1*t2^2 - t1*t3^2 - t2^2*t3 + t2*t3^2, 0, 0, 0, 0, 0]GKMtools.poincare_dual — Function
poincare_dual(S::AbstractGKMSubgraph)Return the equivariant Poincaré dual cohomology class of the subgraph S inside its ambient GKM graph.
For each vertex of the ambient graph that belongs to S, the class is formed by multiplying the corresponding ambient cohomology generator by the product of the weight classes of all ambient flags at that vertex that are not used by the subgraph.
Examples
julia> P2 = projective_space(GKMGraph, 2);
julia> P1inP2 = subgraph_from_vertices(P2, [1, 2])
GKM subgraph of:
GKM graph with 3 nodes, valency 2 and axial function:
2 -> 1 => (1, -1, 0)
3 -> 1 => (1, 0, -1)
3 -> 2 => (0, 1, -1)
Birkhoff-Grothendieck connection for GKM graph with 3 nodes and valency 2
Subgraph:
GKM graph with 2 nodes, valency 1 and axial function:
2 -> 1 => (1, -1, 0)
Algorithmic connection for GKM graph with 2 nodes and valency 1
julia> poincare_dual(P1inP2)
GKM class with restrictions:
[-t1 + t3, -t2 + t3, 0]
julia> is_gkm_spline(ans)
trueChern Classes
GKMtools.first_chern_class — Function
first_chern_class(E::AbstractGKMVectorBundle)
first_chern_class(G::AbstractGKMGraph)Return the first equivariant Chern class of E, or of the tangent bundle of G. This is equivalent to chern_class(E, 1) or chern_class(G, 1).
Examples
julia> P2 = projective_space(GKMGraph, 2);
julia> first_chern_class(P2)
GKM class with restrictions:
[-2*t1 + t2 + t3, t1 - 2*t2 + t3, t1 + t2 - 2*t3]
julia> H3 = gkm_graph_of_toric(hirzebruch_surface(NormalToricVariety, 3))
GKM graph with 4 nodes, valency 2 and axial function:
2 -> 1 => (-1, 0, 1, 0)
3 -> 2 => (-3, -1, 0, 1)
4 -> 1 => (0, -1, -3, 1)
4 -> 3 => (1, 0, -1, 0)
Algorithmic connection for GKM graph with 4 nodes and valency 2
julia> first_chern_class(H3)
GKM class with restrictions:
[t1 + t2 + 2*t3 - t4, 2*t1 + t2 + t3 - t4, -4*t1 - t2 + t3 + t4, t1 - t2 - 4*t3 + t4]Oscar.chern_class — Function
chern_class(E::AbstractGKMVectorBundle, k::Integer)
chern_class(G::AbstractGKMGraph, k::Integer)Return the k-th equivariant Chern class of a smooth or orbifold GKM vector bundle E. For a graph G, return the Chern class of its tangent bundle.
The result is a localized GKMClass, whose restriction at each vertex is the k-th elementary symmetric polynomial in the fiber weights. The zeroth Chern class is the unit, and classes above the bundle rank are zero.
Throw an error when k is negative or the torus ranks of the bundle and its base differ.
Examples
In the first example, we calculate the Chern classes of $\mathbb{P}^2$ and its Chern numbers $c_1^2$ and $c_2$.
julia> G = projective_space(GKMGraph, 2);
julia> chern_class(G, 0)
GKM class with restrictions:
[1, 1, 1]
julia> chern_class(G, 1)
GKM class with restrictions:
[-2*t1 + t2 + t3, t1 - 2*t2 + t3, t1 + t2 - 2*t3]
julia> chern_class(G, 2)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, -t1*t2 + t1*t3 + t2^2 - t2*t3, t1*t2 - t1*t3 - t2*t3 + t3^2]
julia> chern_class(G, 3)
GKM class with restrictions:
[0, 0, 0]
julia> integrate(chern_class(G, 1)*chern_class(G, 1))
9
julia> integrate(chern_class(G, 2))
3In the second example, we calculate the Chern number $c_1c_2$ for the twisted flag variety (see gkm_3d_twisted_flag). This number coincides with the sum of the Chern numbers of the edges by [GS14, Proposition 4.6].
julia> G = gkm_3d_twisted_flag();
julia> integrate(chern_class(G, 1) * chern_class(G, 2))
24
julia> sum([chern_number(e, G) for e in edges(G)])
24Let us compute the chern classes of the equivariant vector bundle $\mathcal{O}(-2)\oplus\mathcal{O}(3)\rightarrow\mathbb{P}^2$ where each summand has its own equivariant parameter.
julia> O1 = vector_bundle_O(2, [1]);
julia> V = O1^(-2)+O1^(3);
julia> c1 = chern_class(V, 1)
GKM class with restrictions:
[t1, 2*t1 - t2, 2*t1 - t3]
julia> c2 = chern_class(V, 2)
GKM class with restrictions:
[-6*t1^2, -24*t1^2 + 24*t1*t2 - 6*t2^2, -24*t1^2 + 24*t1*t3 - 6*t3^2]
julia> integrate(c2)
-6Oscar.IntersectionTheory.total_chern_class — Function
total_chern_class(E::AbstractGKMVectorBundle)
total_chern_class(G::AbstractGKMGraph)Return the total equivariant Chern class, defined as the sum of all Chern classes of E. For a graph, compute the total Chern class of its tangent bundle.
Examples
julia> X = hirzebruch_surface(NormalToricVariety, 2);
julia> E = [toric_line_bundle(X, [1, 0]), toric_line_bundle(X, [0, 1])];
julia> V = gkm_vector_bundle_of_toric(E);
julia> total_chern_class(V)
GKM class with restrictions:
[t3*t4 + 2*t3*t5 - t3*t6 + t3 - t4*t5 + t4 - 2*t5^2 + t5*t6 + t5 - t6 + 1, -2*t1^2 + 2*t1*t3 - t1*t4 + t1*t6 + t1 + t3*t4 - t3*t6 + t3 + t4 - t6 + 1, t1*t2 - t1*t4 - t1 - t2*t3 - t2 + t3*t4 + t3 + t4 + 1, -t2*t3 + t2*t5 - t2 + t3*t4 + t3 - t4*t5 + t4 - t5 + 1]Oscar.chern_classes — Function
chern_classes(E::AbstractGKMVectorBundle)
chern_classes(G::AbstractGKMGraph)Return all equivariant Chern classes from degree zero through the rank. For a graph, compute the classes of its tangent bundle. The first element is the unit class.
Examples
julia> X = hirzebruch_surface(NormalToricVariety, 2);
julia> E = [toric_line_bundle(X, [1, 0]), toric_line_bundle(X, [0, 1])];
julia> V = gkm_vector_bundle_of_toric(E);
julia> (c0, c1, c2) = chern_classes(V);
julia> c0
GKM class with restrictions:
[1, 1, 1, 1]
julia> c1
GKM class with restrictions:
[t3 + t4 + t5 - t6, t1 + t3 + t4 - t6, -t1 - t2 + t3 + t4, -t2 + t3 + t4 - t5]
julia> c2
GKM class with restrictions:
[t3*t4 + 2*t3*t5 - t3*t6 - t4*t5 - 2*t5^2 + t5*t6, -2*t1^2 + 2*t1*t3 - t1*t4 + t1*t6 + t3*t4 - t3*t6, t1*t2 - t1*t4 - t2*t3 + t3*t4, -t2*t3 + t2*t5 + t3*t4 - t4*t5]Localization, serialization, and scalars
GKMtools.localized_class — Function
localized_class(G, values)Construct a GKMClass whose restrictions lie in the fraction field of $H_T^*(\mathrm{pt})$. The values are not checked for polynomial GKM divisibility.
julia> G = projective_space(GKMGraph, 2);
julia> (t1, t2, t3) = gens_coeffRing(G);
julia> values = [t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0];
julia> localized_class(G, values)
GKM class with restrictions:
[t1^2 - t1*t2 - t1*t3 + t2*t3, 0, 0]GKMtools.serialize_polynomial_class — Function
serialize_polynomial_class(filename, c::GKMClass)Serialize only the polynomial fixed-point restrictions of c to filename. The GKM graph and the GKMClass wrapper are not stored.
Use deserialize_polynomial_class with a compatible graph to restore the class. A fraction-field representation is accepted when every restriction has unit denominator; genuine rational restrictions are rejected.
GKMtools.deserialize_polynomial_class — Function
deserialize_polynomial_class(filename, G; check=false)Deserialize polynomial restrictions from filename and attach them to G. Only the restriction vector is read from the file. Its entries are coerced into the equivariant coefficient ring of G, so the file can be used with a freshly constructed compatible graph.
By default the GKM divisibility relations are not checked. The writer serialize_polynomial_class checks polynomiality, but does not verify those relations. Set check=true to verify them on the target graph.
Base.:/ — Method
/(c::GKMClass, f::Number)
//(c::GKMClass, f::Number)Divide every fixed-point restriction by the scalar f, using exact rational arithmetic. Preserve the graph, cohomology parent, and restriction ring. Floating-point scalars are converted to their exact rational values. Other scalars must be coercible to QQ; division by zero throws DivideError. Oscar integer and rational scalars are also supported.