Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BasisLieHightestWeight: Extend functionality to Demazure modules #4570

Draft
wants to merge 15 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ using Oscar.LieAlgebras: lie_algebra_simple_module_struct_consts_gap

using AbstractAlgebra.PrettyPrinting

import Oscar: base_lie_algebra
import Oscar: character
import Oscar: dim
import Oscar: monomial_ordering
import Oscar: monomials
Expand All @@ -26,6 +28,7 @@ import Base: length
# - the list of Minkowski gens contains too many elements, only include those that give us something new

include("LieAlgebras.jl")
include("ModuleData.jl")
include("BirationalSequence.jl")
include("MonomialBasis.jl")
include("NewMonomial.jl")
Expand Down
95 changes: 48 additions & 47 deletions experimental/BasisLieHighestWeight/src/MainAlgorithm.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
function basis_lie_highest_weight_compute(
L::LieAlgebra,
highest_weight::Vector{Int},
V::ModuleData,
operators::Vector{RootSpaceElem}, # monomial x_i is corresponds to f_operators[i]
monomial_ordering_symb::Symbol,
)
Expand All @@ -17,7 +16,7 @@ function basis_lie_highest_weight_compute(
# else
# set_mon = {}
# go through all partitions lambda_1 + lambda_2 = highest_weight
# add compute_monomials(lambda_1) (+) compute_monomials(lambda_1) to set_mon
# add compute_monomials(lambda_1) (+) compute_monomials(lambda_2) to set_mon
# if set_mon too small
# add_by_hand(highest_weight, set_mon)
# return set_mon
Expand All @@ -33,9 +32,8 @@ function basis_lie_highest_weight_compute(
# go through them one by one in monomial_ordering until basis is full
# return set_mon

R = root_system(L)
highest_weight = WeightLatticeElem(R, highest_weight)

R = root_system(base_lie_algebra(V))

birational_seq = birational_sequence(operators)

ZZx, _ = polynomial_ring(ZZ, length(operators)) # for our monomials
Expand All @@ -50,10 +48,9 @@ function basis_lie_highest_weight_compute(

# start recursion over highest_weight
monomials = compute_monomials(
L,
V,
birational_seq,
ZZx,
highest_weight,
monomial_ordering,
calc_highest_weight,
no_minkowski,
Expand All @@ -64,7 +61,7 @@ function basis_lie_highest_weight_compute(
by=(gen -> (sum(coefficients(gen)), reverse(Oscar._vec(coefficients(gen))))),
)
# output
mb = MonomialBasis(L, highest_weight, birational_seq, monomial_ordering, monomials)
mb = MonomialBasis(V, birational_seq, monomial_ordering, monomials)
set_attribute!(
mb, :algorithm => basis_lie_highest_weight_compute, :minkowski_gens => minkowski_gens
)
Expand Down Expand Up @@ -173,18 +170,17 @@ function basis_coordinate_ring_kodaira_compute(
end

function compute_monomials(
L::LieAlgebra,
V::ModuleData,
birational_seq::BirationalSequence,
ZZx::ZZMPolyRing,
highest_weight::WeightLatticeElem,
monomial_ordering::MonomialOrdering,
calc_highest_weight::Dict{WeightLatticeElem,Set{ZZMPolyRingElem}},
no_minkowski::Set{WeightLatticeElem},
)
# This function calculates the monomial basis M_{highest_weight} recursively. The recursion saves all computed
# results in calc_highest_weight and we first check, if we already encountered this highest weight in a prior step.
# If this is not the case, we need to perform computations. The recursion works by using the Minkowski-sum.
# If M_{highest_weight} is the desired set of monomials (identified by the exponents as lattice points), it is know
# If M_{highest_weight} is the desired set of monomials (identified by the exponents as lattice points), it is known
# that for lambda_1 + lambda_2 = highest_weight we have M_{lambda_1} + M_{lambda_2} subseteq M_{highest_weight}.
# The complexity grows exponentially in the size of highest_weight. Therefore, it is very helpful to obtain a part of
# M_{highest_weight} by going through all partitions of highest_weight and using the Minkowski-property. The base
Expand All @@ -193,51 +189,58 @@ function compute_monomials(

# simple cases
# we already computed the highest_weight result in a prior recursion step
if haskey(calc_highest_weight, highest_weight)
return calc_highest_weight[highest_weight]
elseif is_zero(highest_weight) # we mathematically know the solution
if haskey(calc_highest_weight, highest_weight(V))
return calc_highest_weight[highest_weight(V)]
elseif is_zero(highest_weight(V)) # we mathematically know the solution
return Set(ZZx(1))
end
# calculation required
# dim is number of monomials that we need to find, i.e. |M_{highest_weight}|.
# if highest_weight is not a fundamental weight, partition into smaller summands is possible. This is the base case of
# the recursion.
dim = dim_of_simple_module(L, highest_weight)
if is_zero(highest_weight) || is_fundamental_weight(highest_weight)
push!(no_minkowski, highest_weight)
if is_zero(highest_weight(V)) || is_fundamental_weight(highest_weight(V))
push!(no_minkowski, highest_weight(V))
monomials = add_by_hand(
L, birational_seq, ZZx, highest_weight, monomial_ordering, Set{ZZMPolyRingElem}()
V, birational_seq, ZZx, monomial_ordering, Set{ZZMPolyRingElem}()
)
push!(calc_highest_weight, highest_weight => monomials)
push!(calc_highest_weight, highest_weight(V) => monomials)
return monomials
else
# use Minkowski-Sum for recursion
monomials = Set{ZZMPolyRingElem}()
sub_weights = sub_weights_proper(highest_weight)
sub_weights = sub_weights_proper(highest_weight(V))
sort!(sub_weights; by=x -> sum(coefficients(x) .^ 2))
# go through all partitions lambda_1 + lambda_2 = highest_weight until we have enough monomials or used all partitions
for (ind_lambda_1, lambda_1) in enumerate(sub_weights)
length(monomials) >= dim && break
length(monomials) >= dim(V) && break

lambda_2 = highest_weight - lambda_1
lambda_2 = highest_weight(V) - lambda_1
ind_lambda_2 = findfirst(==(lambda_2), sub_weights)::Int

ind_lambda_1 > ind_lambda_2 && continue

if isa(V, SimpleModuleData)
M_lambda_1 = SimpleModuleData(base_lie_algebra(V), lambda_1)
M_lambda_2 = SimpleModuleData(base_lie_algebra(V), lambda_2)
elseif isa(V, DemazureModuleData)
M_lambda_1 = DemazureModuleData(base_lie_algebra(V), lambda_1, weyl_group_elem(V))
M_lambda_2 = DemazureModuleData(base_lie_algebra(V), lambda_2, weyl_group_elem(V))
else
error("unreachable")
end

mon_lambda_1 = compute_monomials(
L,
M_lambda_1,
birational_seq,
ZZx,
lambda_1,
monomial_ordering,
calc_highest_weight,
no_minkowski,
)
mon_lambda_2 = compute_monomials(
L,
M_lambda_2,
birational_seq,
ZZx,
lambda_2,
monomial_ordering,
calc_highest_weight,
no_minkowski,
Expand All @@ -248,28 +251,28 @@ function compute_monomials(
end
# check if we found enough monomials

if length(monomials) < dim
if length(monomials) < dim(V)
push!(no_minkowski, highest_weight)
monomials = add_by_hand(
L, birational_seq, ZZx, highest_weight, monomial_ordering, monomials
V, birational_seq, ZZx, monomial_ordering, monomials
)
end

push!(calc_highest_weight, highest_weight => monomials)
push!(calc_highest_weight, highest_weight(V) => monomials)
return monomials
end

end

function add_new_monomials!(
L::LieAlgebra,
V::ModuleData,
birational_seq::BirationalSequence,
ZZx::ZZMPolyRing,
matrices_of_operators::Vector{<:SMat{ZZRingElem}},
monomial_ordering::MonomialOrdering,
weightspaces::Dict{WeightLatticeElem,Int},
dim_weightspace::Int,
weightspaces::Dict{WeightLatticeElem,ZZRingElem},
dim_weightspace::ZZRingElem,
weight_w::WeightLatticeElem,
highest_weight::WeightLatticeElem,
monomials_in_weightspace::Dict{WeightLatticeElem,Set{ZZMPolyRingElem}},
space::Dict{WeightLatticeElem,<:SMat{QQFieldElem}},
v0::SRow{ZZRingElem},
Expand All @@ -286,7 +289,7 @@ function add_new_monomials!(
poss_mon_in_weightspace = convert_lattice_points_to_monomials(
ZZx,
get_lattice_points_of_weightspace(
operators_as_roots(birational_seq), RootSpaceElem(highest_weight - weight_w),
operators_as_roots(birational_seq), RootSpaceElem(highest_weight(V) - weight_w),
zero_coordinates,
),
)
Expand All @@ -297,7 +300,7 @@ function add_new_monomials!(

# check which monomials should get added to the basis
i = 0
if highest_weight == weight_w # check if [0 0 ... 0] already in basis
if highest_weight(V) == weight_w # check if [0 0 ... 0] already in basis
i += 1
end
number_mon_in_weightspace = length(monomials_in_weightspace[weight_w])
Expand All @@ -309,12 +312,12 @@ function add_new_monomials!(
continue
end

# check if the weight ob each suffix is a weight of the module
# check if the weight of each suffix is a weight of the module
cancel = false
for i in 1:(nvars(ZZx) - 1)
if !haskey(
weightspaces,
highest_weight - sum(
highest_weight(V) - sum(
exp * weight for (exp, weight) in
Iterators.drop(zip(degrees(mon), operators_as_weights(birational_seq)), i)
),
Expand Down Expand Up @@ -346,10 +349,9 @@ function add_new_monomials!(
end

function add_by_hand(
L::LieAlgebra,
V::ModuleData,
birational_seq::BirationalSequence,
ZZx::ZZMPolyRing,
highest_weight::WeightLatticeElem,
monomial_ordering::MonomialOrdering,
basis::Set{ZZMPolyRingElem},
)
Expand All @@ -358,23 +360,23 @@ function add_by_hand(

# initialization
# matrices g_i for (g_1^a_1 * ... * g_k^a_k)*v
R = root_system(L)
R = root_system(base_lie_algebra(V))
matrices_of_operators = tensor_matrices_of_operators(
L, highest_weight, operators_as_roots(birational_seq)
base_lie_algebra(V), highest_weight(V), operators_as_roots(birational_seq)
)
space = Dict(zero(weight_lattice(R)) => sparse_matrix(QQ)) # span of basis vectors to keep track of the basis
v0 = sparse_row(ZZ, [(1, 1)]) # starting vector v

push!(basis, ZZx(1))
# required monomials of each weightspace
weightspaces = character(R, highest_weight)
weightspaces = character(V)
# sort the monomials from the minkowski-sum by their weightspaces
monomials_in_weightspace = Dict{WeightLatticeElem,Set{ZZMPolyRingElem}}()
for (weight_w, _) in weightspaces
monomials_in_weightspace[weight_w] = Set{ZZMPolyRingElem}()
end
for mon in basis
push!(monomials_in_weightspace[highest_weight - weight(mon, birational_seq)], mon)
push!(monomials_in_weightspace[highest_weight(V) - weight(mon, birational_seq)], mon)
end

# only inspect weightspaces with missing monomials
Expand All @@ -400,21 +402,20 @@ function add_by_hand(
end

# identify coordinates that are trivially zero because of the action on the generator
zero_coordinates = compute_zero_coordinates(birational_seq, highest_weight)
zero_coordinates = compute_zero_coordinates(birational_seq, highest_weight(V))

# calculate new monomials
for weight_w in weights_with_non_full_weightspace
dim_weightspace = weightspaces[weight_w]
add_new_monomials!(
L,
V,
birational_seq,
ZZx,
matrices_of_operators,
monomial_ordering,
weightspaces,
dim_weightspace,
weight_w,
highest_weight,
monomials_in_weightspace,
space,
v0,
Expand Down
84 changes: 84 additions & 0 deletions experimental/BasisLieHighestWeight/src/ModuleData.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
abstract type ModuleData end

# To be implemented by subtypes:
# Mandatory:
# base_lie_algebra(V::MyModuleData) -> LieAlgebra
# highest_weight(V::MyModuleData) -> WeightLatticeElem
# dim(V::MyModuleData) -> ZZRingElem
# character(V::MyModuleData) -> Dict{WeightLatticeElem,ZZRingElem}


mutable struct SimpleModuleData <: ModuleData
L::LieAlgebra
highest_weight::WeightLatticeElem

# The following fields are not set by default, just for caching
dim::ZZRingElem
character::Dict{WeightLatticeElem, ZZRingElem}

function SimpleModuleData(L::LieAlgebra, highest_weight::WeightLatticeElem)
new(L, highest_weight)
end
end

function base_lie_algebra(V::SimpleModuleData)
return V.L
end

function highest_weight(V::SimpleModuleData)
return V.highest_weight
end

function dim(V::SimpleModuleData)
if !isdefined(V, :dim)
V.dim = dim_of_simple_module(ZZRingElem, base_lie_algebra(V), highest_weight(V))
end
return V.dim
end

function character(V::SimpleModuleData)
if !isdefined(V, :character)
V.character = character(ZZRingElem, base_lie_algebra(V), highest_weight(V))
end
return V.character
end

mutable struct DemazureModuleData <: ModuleData
L::LieAlgebra
highest_weight::WeightLatticeElem
weyl_group_elem::WeylGroupElem

# The following fields are not set by default, just for caching
dim::ZZRingElem
character::Dict{WeightLatticeElem, ZZRingElem}

function DemazureModuleData(L::LieAlgebra, highest_weight::WeightLatticeElem, weyl_group_elem::WeylGroupElem)
new(L, highest_weight, weyl_group_elem)
end
end

function base_lie_algebra(V::DemazureModuleData)
return V.L
end

function highest_weight(V::DemazureModuleData)
return V.highest_weight
end

function character(V::DemazureModuleData)
if !isdefined(V, :character)
V.character = demazure_character(ZZRingElem, base_lie_algebra(V), highest_weight(V), V.weyl_group_elem)
end
return V.character
end

function dim(V::DemazureModuleData)
if !isdefined(V, :dim)
V.dim = sum(values(character(V)); init=zero(ZZ))
end
return V.dim
end

function weyl_group_elem(V::DemazureModuleData)
return V.weyl_group_elem
end
Loading
Loading