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.
GKMtools.is_gkm_class — Function
is_gkm_class(c::FreeModElem{QQMPolyRingElem}, G::AbstractGKM_graph) -> BoolReturn true if the given class represents an actual cohomology class. This holds if and only if the difference between localizations at fixed points connected through an edge e is divisible by the weight of e (see above)
Examples
Standard functions for accessing cohomology classes always yield GKM classes:
julia> G = projective_space(GKM_graph, 1);
julia> is_gkm_class(point_class(G, 1), G)
trueMoreover, equivariant cohomology is a ring and a module over the coefficient ring:
julia> is_gkm_class(point_class(G, 1)^2 * point_class(G, 2), G)
trueHowever, it is possible to cook up non-GKM classes manually. In the example below, this is because $w(e)=t_1-t_2$, which does not divide $t_1^2 - t_2$. Here, $e$ is the unique edge of the GKM graph of $\mathbb{P}^1$.
julia> (t1, t2) = gens(G.equivariantCohomology.coeffRing);
julia> (e0, e1) = gens(G.equivariantCohomology.cohomRing);
julia> c = t1^2 * e0 + t2 * e1
t1^2*e[1] + t2*e[2]
julia> is_gkm_class(c, G)
falseOscar.IntersectionTheory.point_class — Function
point_class(vertexLabel::String, G::AbstractGKM_graph) -> FreeModElem{QQMPolyRingElem}Return the equivariant Poincare dual of the fixed point with given label.
point_class(vertex::Int, G::AbstractGKM_graph) -> FreeModElem{QQMPolyRingElem}Return the equivariant Poincare dual of the given fixed point.
Examples
julia> P2 = projective_space(GKM_graph, 2);
julia> point_class(1, P2)
(t1^2 - t1*t2 - t1*t3 + t2*t3)*e[1]
julia> F3 = flag_variety(GKM_graph, [1, 1, 1]);
julia> point_class(1, F3)
(t1^2*t2 - t1^2*t3 - t1*t2^2 + t1*t3^2 + t2^2*t3 - t2*t3^2)*e[1]
GKMtools.poincare_dual — Function
poincare_dual(gkmSub::AbstractGKM_subgraph) -> FreeModElem{QQMPolyRingElem}Return the equivariant Poincare dual cohomology class of the GKM subgraph.
For a GKM subgraph, the Poincare dual is computed by taking the product of weight classes of all flags at each vertex that are not included in the subgraph.
The Poincare dual pd of a non compact GKM subspace does not necessarily satisfy is_gkm_class(pd) == true.
Example
julia> P2 = projective_space(GKM_graph, 2);
julia> P1inP2 = gkm_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)
Subgraph:
GKM graph with 2 nodes, valency 1 and axial function:
2 -> 1 => (-1, 1, 0)
julia> poincare_dual(P1inP2)
(t1 - t3)*e[1] + (t2 - t3)*e[2]
julia> is_gkm_class(ans, P2)
true
julia> N_P1inP2 = gkm_subgraph_from_vertices(P2, [1, 2]; include_all_flags = true)
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)
Subgraph:
GKM graph with 2 nodes, valency 2 and axial function:
2 -> 1 => (-1, 1, 0)
Standalone flags:
1.2 => (1, 0, -1)
2.2 => (0, 1, -1)
julia> poincare_dual(N_P1inP2)
e[1] + e[2]
julia> is_gkm_class(ans, P2)
falseGKMtools.weight_class — Function
weight_class(e::Edge, G::AbstractGKM_graph) -> QQMPolyRingElemReturn the weight of the edge e as an element of the coefficient ring of the equivariant cohomology theory.
Example
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)
julia> weight_class(Edge(3, 2), H7)
7*t1 + t2 - t4GKMtools.euler_class — Function
euler_class(vertex::Int, G::AbstractGKM_graph) -> QQMPolyRingElemReturn the Euler class of the normal bundle of the fixed point v. This is the localization of point_class(vertex, G) to the given vertex.
Example
julia> F3 = flag_variety(GKM_graph, [1, 1, 1]);
julia> euler_class(1, F3)
t1^2*t2 - t1^2*t3 - t1*t2^2 + t1*t3^2 + t2^2*t3 - t2*t3^2
julia> point_class(1, F3)
(t1^2*t2 - t1^2*t3 - t1*t2^2 + t1*t3^2 + t2^2*t3 - t2*t3^2)*e[1]euler_class(vertexLabel::String, G::AbstractGKM_graph) -> QQMPolyRingElemReturn the euler class of the normal bundle of the fixed point with the given label.
GKMtools.integrate_gkm_class — Function
integrate_gkm_class(class::FreeModElem{QQMPolyRingElem}, G::AbstractGKM_graph; check::Bool=true) -> QQMPolyRingElemIntegrate the GKM class, yielding an element of the coefficient ring. This checks if is_gkm_class(class,R) == true and throws an error otherwise.
Examples
julia> P2 = projective_space(GKM_graph, 2);
julia> integrate_gkm_class(point_class(1, P2), P2)
1
julia> P2inP1 = gkm_subgraph_from_vertices(P2, [1, 2]);
julia> pd = poincare_dual(P2inP1);
julia> integrate_gkm_class(pd, P2)
0
julia> integrate_gkm_class(pd^2, P2)
1
julia> (t1, t2, t3) = gens(P2.equivariantCohomology.coeffRing);
julia> integrate_gkm_class(t3 * pd^2 + (t2^2 - t1)*point_class(3, P2), P2)
-t1 + t2^2 + t3Nemo.integrate — Function
integrate(class::FreeModElem{QQMPolyRingElem}, G::AbstractGKM_graph, e::Edge) -> AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}Integrate the cohomology class over the curve represented by the GKM graph edge. In mathematical notation, if the edge is $e = (p\rightarrow q)$ and the class is $c=(f_v)_{v\in X^T}$ then $\int_e c = \frac{f_p - f_q}{w(e)}$ where $w(e)$ is the weight of $e$. If is_gkm_class(class, G) == true then the result is a polynomial in the variables gens(G.equivariantCohomology.coeffRing).
Example
julia> P2 = projective_space(GKM_graph, 2);
julia> integrate(first_chern_class(P2), P2, Edge(1, 2))
3integrate(class::FreeModElem{QQMPolyRingElem}, G::AbstractGKM_graph) -> AbstractAlgebra.Generic.FracFieldElem{QQMPolyRingElem}Integrate the cohomology class, yielding an element of the fraction field of the equivariant coefficient ring.
This uses the Atiyah–Bott localization formula: If $c = (f_v)_{v\in X^T}$ then $\int_X c = \sum_{v\in X^T}\frac{f_v}{e_T(T_vX)}$ where $e_T(T_vX)$ is the equivariant Euler class of the tangent bundle of $X$ at the fixed point $v$.
If is_gkm_class(class, G) == true, this fraction will be a polynomial.
Examples
julia> G24 = flag_variety(GKM_graph, [2, 4]); # Grassmannian of 2-planes in C^4
julia> integrate(point_class(G24, 1), G24)
1In contrast to integrate_gkm_class, we can also integrate tuples $(f_v)_{v\in X^T}$ that do not satisfy is_gkm_class(class) == true:
julia> P1 = projective_space(GKM_graph, 1);
julia> (t1, t2) = gens(P1.equivariantCohomology.coeffRing);
julia> (e0, e1) = gens(P1.equivariantCohomology.cohomRing);
julia> c = t1^2 * e0 + t2 * e1
t1^2*e[1] + t2*e[2]
julia> is_gkm_class(c, P1)
false
julia> integrate(c, P1)
(t1^2 - t2)//(t1 - t2)GKMtools.first_chern_class — Function
first_chern_class(G::AbstractGKM_graph) -> FreeModElem{QQMPolyRingElem}Return the equivariant first Chern class of the GKM space, i.e., $c_1^T(TX)$ where $TX$ is the ($T$-equivariant) tangent bundle of $X$.
Examples
julia> P2 = projective_space(GKM_graph, 2);
julia> first_chern_class(P2)
(2*t1 - t2 - t3)*e[1] + (-t1 + 2*t2 - t3)*e[2] + (-t1 - t2 + 2*t3)*e[3]
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)
julia> first_chern_class(H3)
(-t1 - t2 - 2*t3 + t4)*e[1] + (-2*t1 - t2 - t3 + t4)*e[2] + (4*t1 + t2 - t3 - t4)*e[3] + (-t1 + t2 + 4*t3 - t4)*e[4]first_chern_class(R::GKM_cohomology_ring) -> FreeModElem{QQMPolyRingElem}Return the equivariant first Chern class of the GKM space of which R is the cohomology ring.