Constructors
These functions allow the construction of GKM spaces.
GKMtools.gkm_graph — Function
gkm_graph(g, labels, M, w; check=true, checkLabels=true) -> AbstractGKM_graphCreate a GKM graph from the given data.
Arguments
g::Graph: An unoriented OSCAR graph.labels::Vector{String}: A vector of strings, used to denote the vertices.M::AbstractAlgebra.Generic.FreeModule{R}: A OSCAR free module over $\mathbb{Z}$ or $\mathbb{Q}$, it denotes the character group.Ris eitherZZRingElemorQQFieldElem.w::Dict{Edge, AbstractAlgebra.Generic.FreeModuleElem{R}}: The axial function. Note that it is enough to specify the weight of each edge in one orientation here. The opposite oriented edge will automatically be given minus that weight.check::Bool=true: Check if the data inserted are consistent.checkLabels::Bool=true: Check that the labels don't contain the characters<,[,], which are reserved for the output of special constructions like blowups and projective bundles.
Example
Let us construct the GKM graph of the projective line. First of all, we create a graph with two vertices, and one edge.
julia> g = Graph{Undirected}(2)
Undirected graph with 2 nodes and no edges
julia> add_edge!(g, 1, 2);Let us define our array of labels.
julia> labels = ["a", "b"];Now, we create the character group. We take a free module of rank 2 over the integers.
julia> M = free_module(ZZ, 2)
Free module of rank 2 over ZZWe create the axial function. It is a dictionary from the set of edges to the character group. This time we have only one edge.
julia> e = first(edges(g));
julia> w = Dict(e => gens(M)[1] - gens(M)[2])
Dict{Edge, AbstractAlgebra.Generic.FreeModuleElem{ZZRingElem}} with 1 entry:
Edge(2, 1) => (1, -1)Finally, we create the GKM graph.
julia> gkm_graph(g, labels, M, w)
GKM graph with 2 nodes, valency 1 and axial function:
b -> a => (1, -1)GKMtools.empty_gkm_graph — Function
empty_gkm_graph(n::Int64, r::Int64, labels::Vector{String}) -> AbstractGKM_graphIt returns the GKM graph with n fixed points, no edges, torus rank r and vertices labelled by labels.
julia> G = empty_gkm_graph(2, 2, ["a", "b"])
GKM graph with 2 nodes, valency 0 and axial function:
GKMtools.flags_only_gkm_graph — Function
flags_only_gkm_graph(labels::Vector{String}, M::AbstractAlgebra.Generic.FreeModule{R}, w::Vector{Vector{AbstractAlgebra.Generic.FreeModuleElem{R}}}; check::Bool=true, checkLabels::Bool=true) -> AbstractGKM_graphSame as gkm_graph, but constructs an empty GKM graph without any edges and only standalone flags. The input w[v][i] is the weight of the i-th flag at vertex v. Edges may be added later using connect_flags!.
Example
julia> M = free_module(ZZ, 2);
julia> g1, g2 = gens(M);
julia> G = flags_only_gkm_graph(["v1", "v2"], M, [[g1, g2], [-g1, g1+g2]])
GKM graph with 2 nodes, valency 2 and axial function:
Standalone flags:
v1.1 => (1, 0)
v1.2 => (0, 1)
v2.1 => (-1, 0)
v2.2 => (1, 1)
julia> connect_flags!(G, 1, 2, 1, 1);
julia> G
GKM graph with 2 nodes, valency 2 and axial function:
v2 -> v1 => (-1, 0)
Standalone flags:
v1.2 => (0, 1)
v2.2 => (1, 1)Oscar.add_edge! — Function
add_edge!(G::AbstractGKM_graph, s::String, d::String, weight::AbstractAlgebra.Generic.FreeModuleElem{R}) -> Tuple{Int64, Int64} where R<:GKM_weight_typeAdd an edge to G from the vertex labelled s to the vertex labelled d, the axial function takes value weight in that edge. The returned tuple (i,j) gives the indices of the two flags of the newly created edge at the vertex s and d, respectively.
Let us construct the same example of gkm_graph, that is the GKM graph of the projective space.
julia> G = empty_gkm_graph(2, 2, ["a", "b"])
GKM graph with 2 nodes, valency 0 and axial function:
julia> wei = gens(G.M)[1] - gens(G.M)[2]
(1, -1)
julia> add_edge!(G, "b", "a", wei)
(1, 1)
julia> G
GKM graph with 2 nodes, valency 1 and axial function:
b -> a => (1, -1)
add_edge!(G::AbstractGKM_graph, s::String, d::String, weight::AbstractAlgebra.Generic.FreeModuleElem{R}) where R<:GKM_weight_typeSame as before, but using the number of the vertex instead of the label.
GKMtools.add_standalone_flag! — Function
add_standalone_flag!(G::AbstractGKM_graph, v::Int64, weight::AbstractAlgebra.Generic.FreeModuleElem{R}) -> Int64 where R<:GKM_weight_typeAdd a standalone flag (not associated with an edge) at vertex v with the given weight and return the index of the newly created flag at v.
Example
julia> G = projective_space(GKM_graph, 2)
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)
julia> g1, g2, g3 = gens(G.M);
julia> add_standalone_flag!(G, 1, g1)
3
julia> add_standalone_flag!(G, 2, g2);
julia> add_standalone_flag!(G, 3, g3);
julia> valency(G)
3
julia> G
GKM graph with 3 nodes, valency 3 and axial function:
2 -> 1 => (-1, 1, 0)
3 -> 1 => (-1, 0, 1)
3 -> 2 => (0, -1, 1)
Standalone flags:
1.3 => (1, 0, 0)
2.3 => (0, 1, 0)
3.3 => (0, 0, 1)add_standalone_flag!(G::AbstractGKM_graph, v::String, weight::AbstractAlgebra.Generic.FreeModuleElem{R}) where R<:GKM_weight_typeSame as above, but using vertex label instead of index.
GKMtools.connect_flags! — Function
connect_flags!(G::AbstractGKM_graph, v1::Int64, v2::Int64, f1::Int64, f2::Int64) -> EdgeConnect flag f1 at vertex v1 and flag f2 at vertex v2 to form a new edge of G, and return the new edge. This requires that vertices v1 and v2 are not yet connected by an edge, and that the weights of the two flags sum to zero.
Add all edges immediately after creation. Any curve class or cohomology functionality should only be used after all edges have been added. The same holds for initialize!.
An example of this function is provided in flags_only_gkm_graph above.
GKMtools.initialize! — Function
initialize!(gkm::AbstractGKM_graph; connection::Bool=true, curveClasses::Bool=true)You may optionally call this function as soon as all edges have been added to the GKM graph to calculate the GKM connection (if unique) and the curve classes of the gkm graph. This will set the fields gkm.connection and gkm.curveClasses that are initially nothing. If you don't call this, these fields will be initialized later if possible, which might take some time at unexpected moments (especially for curveClasses). If any of those fields are already set, this will not overwrite them.
GKMtools.convert_weights — Function
convert_weights(G::AbstractGKM_graph) -> AbstractGKM_graph{QQFieldElem}It returns $G$, but the character group will be embedded into a free $\mathbb{Q}$-module.
Examples
julia> G_over_Z = generalized_gkm_flag(root_system(:A, 1))
GKM graph with 2 nodes, valency 1 and axial function:
s1 -> id => (-1, 1)
julia> typeof(G_over_Z)
GKMtools.AbstractGKM_graph{ZZRingElem}
julia> G_over_Q = convert_weights(G_over_Z)
GKM graph with 2 nodes, valency 1 and axial function:
s1 -> id => (-1, 1)
julia> typeof(G_over_Q)
GKMtools.AbstractGKM_graph{QQFieldElem}GKMtools.substitute_torus — Function
substitute_torus(G::AbstractGKM_graph{R}, f::AbstractAlgebra.Generic.ModuleHomomorphism{R}) where R <: GKM_weight_typeReturn a copy of the GKM graph G where the weights of all flags and edges are substituted according to the module homomorphism f.
If G has a natural connection (i.e. if it is 3-independent or a connection has been set using set_connection!), then it is copied to the result.
Example
julia> G = projective_space(GKM_graph, 2)
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)
julia> M = free_module(ZZ, 2);
julia> g1, g2 = gens(M);
julia> f = ModuleHomomorphism(G.M, M, [zero(M), g1, g2]);
julia> G2 = substitute_torus(G, f)
GKM graph with 3 nodes, valency 2 and axial function:
2 -> 1 => (1, 0)
3 -> 1 => (0, 1)
3 -> 2 => (-1, 1)GKMtools.enlarge_torus — Function
enlarge_torus(G::AbstractGKM_graph, r::Int64) -> AbstractGKM_graphReturn a copy of the GKM graph $G$ where the acting torus has been enlarged by $r$ dimensions which act trivially. This function is sometimes used in the construction of vector bundles, when one would like the vector bundle and the base space to have the same weight lattice.
Example
julia> P2 = projective_space(GKM_graph, 2)
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)
julia> enlarge_torus(P2, 2)
GKM graph with 3 nodes, valency 2 and axial function:
2 -> 1 => (-1, 1, 0, 0, 0)
3 -> 1 => (-1, 0, 1, 0, 0)
3 -> 2 => (0, -1, 1, 0, 0)Base.isvalid — Method
isvalid(gkm::AbstractGKM_graph; printDiagnostics::Bool=true) -> BoolReturn true if the GKM graph is valid. This means:
- Every vertex has the same degree (i.e. number of flags).
- All flag weights are defined and belong to the weight lattice.
- For edges: the flag weight at each end of an edge sums to zero.
- Edge-to-flag mappings are consistent.
- There are the right number of vertex labels.
- If the valency is at least two, the flag weights are 2-independent.
- Vertex labels must be unique.
- The equivariant cohomology ring has rank = number of vertices of graph.
- The coefficient ring of the equivariant cohomology ring has number of generators = torus rank.
Examples
The standard constructions always produce valid GKM graphs, e.g. the complex projective space $\mathbb{P}^3$:
julia> isvalid(projective_space(GKM_graph, 3))
true