From f4c48429db12e844596f9c5ba1c359612d045c70 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Fri, 27 Oct 2023 12:17:19 +0200 Subject: [PATCH] Refactor algorithm input and some Lie algebra stuff - completely rewrite operator generation (by index, by coeffs of simple roots, lustzig) - more accessors for Lie algebra data - remove some type conversions - rename all vars `lie_algebra` to avoid shadowing of function - Update user functions' arguments to Ghislain's whishes --- .../src/BasisLieHighestWeight.jl | 1 - .../BasisLieHighestWeight/src/LieAlgebras.jl | 68 ++++---- .../src/MainAlgorithm.jl | 165 +++++++++--------- .../src/RootConversion.jl | 4 +- .../src/UserFunctions.jl | 116 ++++++++---- .../BasisLieHighestWeight/src/WeylPolytope.jl | 12 +- .../src/WordCalculations.jl | 154 ---------------- .../test/MainAlgorithm-test.jl | 4 +- .../test/RootConversion-test.jl | 10 +- .../test/WordCalculations-test.jl | 12 -- .../BasisLieHighestWeight/test/runtests.jl | 1 - 11 files changed, 209 insertions(+), 338 deletions(-) delete mode 100644 experimental/BasisLieHighestWeight/src/WordCalculations.jl delete mode 100644 experimental/BasisLieHighestWeight/test/WordCalculations-test.jl diff --git a/experimental/BasisLieHighestWeight/src/BasisLieHighestWeight.jl b/experimental/BasisLieHighestWeight/src/BasisLieHighestWeight.jl index 3fbe375d96a1..a2134560b332 100644 --- a/experimental/BasisLieHighestWeight/src/BasisLieHighestWeight.jl +++ b/experimental/BasisLieHighestWeight/src/BasisLieHighestWeight.jl @@ -47,7 +47,6 @@ include("TensorModels.jl") include("MonomialOrder.jl") include("RootConversion.jl") include("WeylPolytope.jl") -include("WordCalculations.jl") include("MainAlgorithm.jl") include("UserFunctions.jl") diff --git a/experimental/BasisLieHighestWeight/src/LieAlgebras.jl b/experimental/BasisLieHighestWeight/src/LieAlgebras.jl index 9da3ab844a68..afe22536dcf7 100644 --- a/experimental/BasisLieHighestWeight/src/LieAlgebras.jl +++ b/experimental/BasisLieHighestWeight/src/LieAlgebras.jl @@ -2,12 +2,14 @@ lie_type::Symbol rank::Int lie_algebra_gap::GAP.Obj + chevalley_basis::NTuple{3,Vector{GAP.Obj}} function LieAlgebraStructure(lie_type::Symbol, rank::Int) lie_algebra_gap = GAP.Globals.SimpleLieAlgebra( GAP.Obj(lie_type), rank, GAP.Globals.Rationals ) - return new(lie_type, rank, lie_algebra_gap) + chevalley_basis = NTuple{3,Vector{GAP.Obj}}(GAP.Globals.ChevalleyBasis(lie_algebra_gap)) + return new(lie_type, rank, lie_algebra_gap, chevalley_basis) end end @@ -23,25 +25,37 @@ end return inv(cartan_matrix(L)) end -function Base.show(io::IO, lie_algebra::LieAlgebraStructure) - print(io, "Lie-Algebra of type ", lie_algebra.lie_type, " and rank ", lie_algebra.rank) +function Base.show(io::IO, L::LieAlgebraStructure) + print(io, "Lie-Algebra of type ", L.lie_type, " and rank ", L.rank) end -function lie_algebra_with_basis(type::Symbol, rk::Int) - lie_algebra = LieAlgebraStructure(type, rk) - chevalley_basis = NTuple{3,Vector{GAP.Obj}}( - GAP.Globals.ChevalleyBasis(lie_algebra.lie_algebra_gap) - ) - return lie_algebra, chevalley_basis +function lie_algebra(type::Symbol, rk::Int) + return LieAlgebraStructure(type, rk) +end + +function chevalley_basis_gap(L::LieAlgebraStructure) + return L.chevalley_basis +end + +function cartan_sub_basis(L::LieAlgebraStructure) + return L.chevalley_basis[3] +end + +function root_system_gap(L::LieAlgebraStructure) + return GAP.Globals.RootSystem(L.lie_algebra_gap) +end + +function num_positive_roots(L::LieAlgebraStructure) + return length(GAP.Globals.PositiveRoots(root_system_gap(L))) end function matricesForOperators( - lie_algebra::GAP.Obj, highest_weight::Vector{ZZRingElem}, operators::Vector{GAP.Obj} + L::GAP.Obj, highest_weight::Vector{ZZRingElem}, operators::Vector{GAP.Obj} )::Vector{SMat{ZZRingElem}} """ used to create tensorMatricesForOperators """ - M = GAP.Globals.HighestWeightModule(lie_algebra, GAP.Obj(Vector{Int}(highest_weight))) + M = GAP.Globals.HighestWeightModule(L, GAP.Obj(Vector{Int}(highest_weight))) matrices_of_operators = [ sparse_matrix(transpose(matrix(QQ, GAP.Globals.MatrixOfAction(GAPWrap.Basis(M), o)))) for o in operators @@ -53,32 +67,16 @@ function matricesForOperators( return matrices_of_operators end -function weights_for_operators( - lie_algebra::GAP.Obj, cartan_sub::Vector{GAP.Obj}, operators::Vector{GAP.Obj} -)::Vector{Vector{ZZRingElem}} +function weight(L::LieAlgebraStructure, operator::GAP.Obj) """ - Calculates the weight weights[i] in w_i for each operator operators[i] + Calculates the weight in w_i for operator """ - """cartan = [Vector{Int}(x) for x in GAP.Globals.ExtRepOfObj.(cartan)] - operators = [Vector{Int}(x) for x in GAP.Globals.ExtRepOfObj.(operators)] - if any(iszero.(operators)) - error("ops should be non-zero") - end - println([findfirst(v .!= 0) for v in operators]) - - return [ - [(dot(h, v))[findfirst(v .!= 0)] / (v)[findfirst(v .!= 0)] for h in cartan] for v in operators - ] - """ - if any(iszero, operators) - error("ops should be non-zero") - end - basis = GAP.Globals.Basis(lie_algebra) + @req !iszero(operator) "Operators should be non-zero" + basis = GAP.Globals.Basis(L.lie_algebra_gap) + basis_ind = GAP.Globals.Position(basis, operator) + denom = GAP.Globals.Coefficients(basis, operator)[basis_ind] return [ - begin - ind = GAP.Globals.Position(basis, v) - denom = GAP.Globals.Coefficients(basis, v)[ind] - [ZZ(GAP.Globals.Coefficients(basis, h * v)[ind]//denom) for h in cartan_sub] - end for v in operators + ZZ(GAP.Globals.Coefficients(basis, h * operator)[basis_ind]//denom) for + h in cartan_sub_basis(L) ] end diff --git a/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl b/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl index fba318174e90..9e8e278f7d57 100644 --- a/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl +++ b/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl @@ -1,6 +1,6 @@ function basis_lie_highest_weight_compute( - lie_algebra::LieAlgebraStructure, + L::LieAlgebraStructure, chevalley_basis::NTuple{3,Vector{GAP.Obj}}, highest_weight::Vector{Int}, operators::Vector{GAP.Obj}, # operators are represented by our monomials. x_i is connected to operators[i] @@ -43,10 +43,8 @@ function basis_lie_highest_weight_compute( # The function precomputes objects that are independent of the highest weight and that can be used in all recursion # steps. Then it starts the recursion and returns the result. - weights_w = weights_for_operators( - lie_algebra.lie_algebra_gap, chevalley_basis[3], operators - ) # weights of the operators - weights_alpha = [w_to_alpha(lie_algebra, QQ.(weight_w)) for weight_w in weights_w] # other root system + weights_w = [weight(L, op) for op in operators] # weights of the operators + weights_alpha = [w_to_alpha(L, weight_w) for weight_w in weights_w] # other root system asVec(v) = Oscar.GAP.gap_to_julia(GAPWrap.ExtRepOfObj(v)) # TODO birational_sequence = BirationalSequence( @@ -58,14 +56,14 @@ function basis_lie_highest_weight_compute( # save computations from recursions calc_highest_weight = Dict{Vector{ZZRingElem},Set{ZZMPolyRingElem}}( - [ZZ(0) for i in 1:rank(lie_algebra)] => Set([ZZx(1)]) + [ZZ(0) for i in 1:rank(L)] => Set([ZZx(1)]) ) # save all highest weights, for which the Minkowski-sum did not suffice to gain all monomials no_minkowski = Set{Vector{ZZRingElem}}() # start recursion over highest_weight set_mon = compute_monomials( - lie_algebra, + L, birational_sequence, ZZx, highest_weight, @@ -79,17 +77,12 @@ function basis_lie_highest_weight_compute( # output return MonomialBasis( - lie_algebra, - highest_weight, - monomial_ordering, - monomials, - minkowski_gens, - birational_sequence, + L, highest_weight, monomial_ordering, monomials, minkowski_gens, birational_sequence ) end function compute_monomials( - lie_algebra::LieAlgebraStructure, + L::LieAlgebraStructure, birational_sequence::BirationalSequence, ZZx::ZZMPolyRing, highest_weight::Vector{ZZRingElem}, @@ -112,7 +105,7 @@ function compute_monomials( # 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 highest_weight == [ZZ(0) for i in 1:(lie_algebra.rank)] # we mathematically know the solution + elseif highest_weight == [ZZ(0) for i in 1:(L.rank)] # we mathematically know the solution return Set(ZZx(1)) end @@ -121,12 +114,12 @@ function compute_monomials( # if highest_weight is a fundamental weight, partition into smaller summands is possible. This is the basecase of # the recursion. gap_dim = GAP.Globals.DimensionOfHighestWeightModule( - lie_algebra.lie_algebra_gap, GAP.Obj(Int.(highest_weight)) + L.lie_algebra_gap, GAP.Obj(Int.(highest_weight)) ) # fundamental weights if is_fundamental(highest_weight) || sum(abs.(highest_weight)) == 0 push!(no_minkowski, highest_weight) set_mon = add_by_hand( - lie_algebra, + L, birational_sequence, ZZx, highest_weight, @@ -148,7 +141,7 @@ function compute_monomials( lambda_1 = sub_weights_w[i] lambda_2 = highest_weight .- lambda_1 mon_lambda_1 = compute_monomials( - lie_algebra, + L, birational_sequence, ZZx, lambda_1, @@ -157,7 +150,7 @@ function compute_monomials( no_minkowski, ) mon_lambda_2 = compute_monomials( - lie_algebra, + L, birational_sequence, ZZx, lambda_2, @@ -181,7 +174,7 @@ function compute_monomials( if length(set_mon) < gap_dim push!(no_minkowski, highest_weight) set_mon = add_by_hand( - lie_algebra, birational_sequence, ZZx, highest_weight, monomial_ordering_lt, set_mon + L, birational_sequence, ZZx, highest_weight, monomial_ordering_lt, set_mon ) end push!(calc_highest_weight, highest_weight => set_mon) @@ -216,7 +209,7 @@ function add_known_monomials!( end function add_new_monomials!( - lie_algebra::LieAlgebraStructure, + L::LieAlgebraStructure, birational_sequence::BirationalSequence, ZZx::ZZMPolyRing, matrices_of_operators::Vector{SMat{ZZRingElem}}, @@ -241,7 +234,7 @@ function add_new_monomials!( poss_mon_in_weightspace = convert_lattice_points_to_monomials( ZZx, get_lattice_points_of_weightspace( - birational_sequence.weights_alpha, w_to_alpha(lie_algebra, QQ.(weight_w)) + birational_sequence.weights_alpha, w_to_alpha(L, weight_w) ), ) isempty(poss_mon_in_weightspace) && error("The input seems to be invalid.") @@ -285,7 +278,7 @@ function add_new_monomials!( end function add_by_hand( - lie_algebra::LieAlgebraStructure, + L::LieAlgebraStructure, birational_sequence::BirationalSequence, ZZx::ZZMPolyRing, highest_weight::Vector{ZZRingElem}, @@ -303,14 +296,14 @@ function add_by_hand( # initialization # matrices g_i for (g_1^a_1 * ... * g_k^a_k)*v matrices_of_operators = tensorMatricesForOperators( - lie_algebra.lie_algebra_gap, highest_weight, birational_sequence.operators + L.lie_algebra_gap, highest_weight, birational_sequence.operators ) space = Dict(ZZ(0) * birational_sequence.weights_w[1] => SparseVectorSpaceBasis([], [])) # span of basis vectors to keep track of the basis v0 = sparse_row(ZZ, [(1, 1)]) # starting vector v push!(set_mon, ZZx(1)) # required monomials of each weightspace - weightspaces = get_dim_weightspace(lie_algebra, highest_weight) + weightspaces = get_dim_weightspace(L, highest_weight) # sort the monomials from the minkowski-sum by their weightspaces set_mon_in_weightspace = Dict{Vector{ZZRingElem},Set{ZZMPolyRingElem}}() @@ -345,7 +338,7 @@ function add_by_hand( for (weight_w, dim_weightspace) in weightspaces # print("*") add_new_monomials!( - lie_algebra, + L, birational_sequence, ZZx, matrices_of_operators, @@ -374,68 +367,78 @@ function sub_simple_refl(word::Vector{Int}, lie_algebra_gap::GAP.Obj)::Vector{GA return operators end -function get_operators_normal( - lie_algebra::LieAlgebraStructure, +function operators_by_index( + L::LieAlgebraStructure, + chevalley_basis::NTuple{3,Vector{GAP.Obj}}, + birational_sequence::Vector{Int}, +)::Vector{GAP.Obj} + @req all(i -> 1 <= i <= num_positive_roots(L), birational_sequence) "Entry of birational_sequence out of bounds" + + return [chevalley_basis[1][i] for i in birational_sequence] # TODO: change to [2] +end + +function operators_by_simple_roots( + L::LieAlgebraStructure, chevalley_basis::NTuple{3,Vector{GAP.Obj}}, - reduced_expression::Union{String,Vector{Union{Int,Vector{Int}}},Vector{GAP.GapObj},Any}, + birational_sequence::Vector{Vector{Int}}, )::Vector{GAP.Obj} + rs = root_system_gap(L) + simple_roots = Vector{Vector{Int}}(GAP.Globals.SimpleSystem(rs)) + positive_roots = Vector{Vector{Int}}(GAP.Globals.PositiveRoots(rs)) + + root_inds = Int[] + for whgt_alpha in birational_sequence + @req length(whgt_alpha) == rank(L) "Length mismatch" + @req all(>=(0), whgt_alpha) "Only positive roots are allowed as input" + root = sum(whgt_alpha .* simple_roots) + root_ind = findfirst(==(root), positive_roots) + @req !isnothing(root_ind) "$whgt_alpha is not a positive root" + push!(root_inds, root_ind) + end + + return operators_by_index(L, chevalley_basis, root_inds) +end + +function operators_lustzig( + L::LieAlgebraStructure, + chevalley_basis::NTuple{3,Vector{GAP.Obj}}, + reduced_expression::Vector{Int}, +) + root_inds = operators_lustzig_indices(L, reduced_expression) + return operators_by_index(L, chevalley_basis, root_inds) +end + +function operators_lustzig_indices(L::LieAlgebraStructure, word::Vector{Int}) """ - handles user input for operators - "regular" for all operators - "longest-word" for random longest-word in Weyl-group (currently not implemented) - reduced_expression::Vector{Int} for explicit longest-word + Computes the operators for the lustzig polytopes for a longest weyl-word + reduced_expression. + + \beta_k := s_{i_1} … s_{i_{k-1}} (\alpha_{i_k}) + + F.e. for A, 2, [1, 2, 1], we get + \beta_1 = \alpha_1 + \beta_2 = \alpha_1 + \alpha_2 + \beta_3 = \alpha_2 """ - if typeof(reduced_expression) == GAP.Obj # If user already submitted gap-roots as operators, keep - return reduced_expression - elseif reduced_expression == "regular" # create standard reduced_expression, use reduced_expression as specified by GAP - return chevalley_basis[1] - # The functionality longest-word required Coxetergroups from Gapjm.jl (https://github.com/jmichel7/Gapjm.jl and was - # temporarily deleted - # choose a random longest word. Created by extending by random not leftdescending reflections until total length is - # reached - #elseif operators == "longest-word" - # operators = longest_weyl_word(t,n) - # operators = sub_simple_refl(operators, lie_algebra, n) - # return operators - end + rs = root_system_gap(L) - # use user defined operator - # Check for incorrect input: - for x in reduced_expression - if isa(x, Int) - if !(1 <= x <= lie_algebra.rank) - error( - "Each integer in reduced_expression should be between 1 and the rank of the lie-algebra", - ) - end - elseif isa(x, Vector{Int}) - if !(all(1 <= i <= lie_algebra.rank for i in x)) - error( - "All integers in each vector of reduced_expression should be between 1 and the rank of the lie-algebra", - ) - end - else - error("Each item in reduced_expression needs to be an Int or Vector{Int}") - end - end - # If one of the conditions is met, the algorithms works. Otherwise a warning is printed (and can be ignored). - #if !(is_longest_weyl_word(type, rank, reduced_expression)) && !(Set(reduced_expression) == [i for i=1:n]) - # println("WARNING: reduced_expression may be incorrect input.") - #end - sanitized_reduced_expression = Vector{Union{Int,Vector{Int}}}() # creates an empty array of the desired type - for item in reduced_expression - if isa(item, Int) - push!(sanitized_reduced_expression, item) - elseif isa(item, Vector{Int}) - push!(sanitized_reduced_expression, item) - else - error("Wrong type") + simple_roots = GAP.Globals.SimpleSystem(rs) + positive_roots = Vector{Vector{Int}}(GAP.Globals.PositiveRoots(rs)) + sparse_cartan_matrix = GAP.Globals.SparseCartanMatrix(GAP.Globals.WeylGroup(rs)) + + root_inds = Int[] + + for k in 1:length(word) + # Calculate betas by applying simple reflections step-by-step. + root = copy(simple_roots[word[k]]) + for j in (k - 1):-1:1 + GAP.Globals.ApplySimpleReflection(sparse_cartan_matrix, word[j], root) end + root_ind = findfirst(==(Vector{Int}(root)), positive_roots) + @req !isnothing(root_ind) "$root is not a positive root" + push!(root_inds, root_ind) end - operators = get_operators_simple_reflections( - lie_algebra, chevalley_basis, sanitized_reduced_expression - ) - return operators + return root_inds end @doc """ diff --git a/experimental/BasisLieHighestWeight/src/RootConversion.jl b/experimental/BasisLieHighestWeight/src/RootConversion.jl index e223bbdb40d5..c1f83d9a0964 100644 --- a/experimental/BasisLieHighestWeight/src/RootConversion.jl +++ b/experimental/BasisLieHighestWeight/src/RootConversion.jl @@ -1,4 +1,6 @@ -function w_to_alpha(L::LieAlgebraStructure, weight_w::Vector{QQFieldElem}) +function w_to_alpha( + L::LieAlgebraStructure, weight_w::Union{Vector{ZZRingElem},Vector{QQFieldElem}} +) return weight_w * inv_cartan_matrix(L) end diff --git a/experimental/BasisLieHighestWeight/src/UserFunctions.jl b/experimental/BasisLieHighestWeight/src/UserFunctions.jl index 0a4c1303dd5a..c6f385b26bc9 100644 --- a/experimental/BasisLieHighestWeight/src/UserFunctions.jl +++ b/experimental/BasisLieHighestWeight/src/UserFunctions.jl @@ -9,22 +9,20 @@ julia> BasisLieHighestWeight.basis_lie_highest_weight_operators(:B, 2) ``` """ function basis_lie_highest_weight_operators(type::Symbol, rank::Int) - lie_algebra, chevalley_basis = lie_algebra_with_basis(type, rank) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) operators = chevalley_basis[1] # TODO: change to [2] - weights_w = weights_for_operators( - lie_algebra.lie_algebra_gap, chevalley_basis[3], operators - ) - weights_alpha = [w_to_alpha(lie_algebra, QQ.(weight_w)) for weight_w in weights_w] + weights_alpha = [w_to_alpha(L, weight(L, op)) for op in operators] return collect(enumerate(weights_alpha)) end @doc """ basis_lie_highest_weight( type::Symbol, - rank::Int, - highest_weight::Vector{Int}; - reduced_expression::Union{String, Vector{Union{Int, Vector{Int}}}} = "regular", - monomial_ordering::Union{Symbol, Function} = :degrevlex, + rank::Int, + highest_weight::Vector{Int}, + birational_sequence::Union{String, Vector{Union{Int, Vector{Int}}}}; + monomial_ordering::Union{Symbol, Function} = :degrevlex, ) Computes a monomial basis for the highest weight module with highest weight @@ -35,9 +33,7 @@ Computes a monomial basis for the highest weight module with highest weight - `type`: type of liealgebra we want to investigate, one of :A, :B, :C, :D, :E, :F, :G - `rank`: rank of liealgebra - `highest_weight`: highest-weight -- `reduced_expression`: list of operators, either "regular" or integer array. The functionality of choosing a random longest word - is currently not implemented, because we used https://github.com/jmichel7/Gapjm.jl to work with coxeter - groups need a method to obtain all non left descending elements to extend a word +- `birational_sequence`: list of operators - `monomial_ordering`: monomial order in which our basis gets defined with regards to our operators. If this is a weighted ordering, the height of the corresponding root is used as weight. @@ -75,7 +71,20 @@ over lie-Algebra of type A and rank 3 [0, 1, 0] [0, 0, 1] -julia> base = BasisLieHighestWeight.basis_lie_highest_weight(:A, 2, [1, 0]; birational_sequence=[1,2,1]) +julia> base = BasisLieHighestWeight.basis_lie_highest_weight(:A, 2, [1, 0], [1,2,1]) +Monomial basis of a highest weight module + of highest weight [1, 0] + of dimension 3 + with monomial ordering degrevlex +over lie-Algebra of type A and rank 2 + where the birational sequence used consists of operators to the following weights (given as coefficients w.r.t. alpha_i): + [1, 0] + [0, 1] + [1, 0] + and the basis was generated by Minkowski sums of the bases of the following highest weight modules: + [1, 0] + +julia> base = BasisLieHighestWeight.basis_lie_highest_weight(:A, 2, [1, 0], [[1,0], [0,1], [1,0]]) Monomial basis of a highest weight module of highest weight [1, 0] of dimension 3 @@ -116,23 +125,50 @@ function basis_lie_highest_weight( type::Symbol, rank::Int, highest_weight::Vector{Int}; - birational_sequence::Union{String,Vector{Int},Vector{GAP.GapObj},Any}="regular", # regular = all pos. roots in order of GAP monomial_ordering::Union{Symbol,Function}=:degrevlex, ) - """ - Standard function with all options - """ - lie_algebra, chevalley_basis = lie_algebra_with_basis(type, rank) - operators = get_operators_normal(lie_algebra, chevalley_basis, birational_sequence) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = chevalley_basis[1] # TODO: change to [2] + return basis_lie_highest_weight_compute( + L, chevalley_basis, highest_weight, operators, monomial_ordering + ) +end + +function basis_lie_highest_weight( + type::Symbol, + rank::Int, + highest_weight::Vector{Int}, + birational_sequence::Vector{Int}; + monomial_ordering::Union{Symbol,Function}=:degrevlex, +) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = operators_by_index(L, chevalley_basis, birational_sequence) + return basis_lie_highest_weight_compute( + L, chevalley_basis, highest_weight, operators, monomial_ordering + ) +end + +function basis_lie_highest_weight( + type::Symbol, + rank::Int, + highest_weight::Vector{Int}, + birational_sequence::Vector{Vector{Int}}; + monomial_ordering::Union{Symbol,Function}=:degrevlex, +) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = operators_by_simple_roots(L, chevalley_basis, birational_sequence) return basis_lie_highest_weight_compute( - lie_algebra, chevalley_basis, highest_weight, operators, monomial_ordering + L, chevalley_basis, highest_weight, operators, monomial_ordering ) end @doc """ # Examples ```jldoctest -julia> base = BasisLieHighestWeight.basis_lie_highest_weight_lustzig(:D, 4, [1,1,1,1]; reduced_expression=[4,3,2,4,3,2,1,2,4,3,2,1]) +julia> base = BasisLieHighestWeight.basis_lie_highest_weight_lustzig(:D, 4, [1,1,1,1], [4,3,2,4,3,2,1,2,4,3,2,1]) Monomial basis of a highest weight module of highest weight [1, 1, 1, 1] of dimension 4096 @@ -160,7 +196,7 @@ over lie-Algebra of type D and rank 4 ``` """ function basis_lie_highest_weight_lustzig( - type::Symbol, rank::Int, highest_weight::Vector{Int}; reduced_expression::Vector{Int} + type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int} ) """ Lustzig polytope @@ -168,17 +204,18 @@ function basis_lie_highest_weight_lustzig( """ # operators = some sequence of the String / Littelmann-Berenstein-Zelevinsky polytope monomial_ordering = :wdegrevlex - lie_algebra, chevalley_basis = lie_algebra_with_basis(type, rank) - operators = get_operators_lustzig(lie_algebra, chevalley_basis, reduced_expression) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = operators_lustzig(L, chevalley_basis, reduced_expression) return basis_lie_highest_weight_compute( - lie_algebra, chevalley_basis, highest_weight, operators, monomial_ordering + L, chevalley_basis, highest_weight, operators, monomial_ordering ) end @doc """ # Examples ```jldoctest -julia> BasisLieHighestWeight.basis_lie_highest_weight_string(:B, 3, [1,1,1]; reduced_expression=[3,2,3,2,1,2,3,2,1]) +julia> BasisLieHighestWeight.basis_lie_highest_weight_string(:B, 3, [1,1,1], [3,2,3,2,1,2,3,2,1]) Monomial basis of a highest weight module of highest weight [1, 1, 1] of dimension 512 @@ -201,7 +238,7 @@ over lie-Algebra of type B and rank 3 ``` """ function basis_lie_highest_weight_string( - type::Symbol, rank::Int, highest_weight::Vector{Int}; reduced_expression::Vector{Int} + type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int} ) """ String / Littelmann-Berenstein-Zelevinsky polytope @@ -211,10 +248,11 @@ function basis_lie_highest_weight_string( """ # reduced_expression = some sequence of the String / Littelmann-Berenstein-Zelevinsky polytope monomial_ordering = :neglex - lie_algebra, chevalley_basis = lie_algebra_with_basis(type, rank) - operators = get_operators_normal(lie_algebra, chevalley_basis, reduced_expression) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = operators_by_index(L, chevalley_basis, reduced_expression) return basis_lie_highest_weight_compute( - lie_algebra, chevalley_basis, highest_weight, operators, monomial_ordering + L, chevalley_basis, highest_weight, operators, monomial_ordering ) end @@ -246,17 +284,18 @@ function basis_lie_highest_weight_pbw(type::Symbol, rank::Int, highest_weight::V BasisLieHighestWeight.basis_lie_highest_weight_pbw(:A, 3, [1,1,1]) """ monomial_ordering = :neglex - lie_algebra, chevalley_basis = lie_algebra_with_basis(type, rank) - operators = reverse(get_operators_normal(lie_algebra, chevalley_basis, "regular")) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = reverse(chevalley_basis[1]) # TODO: change to [2] return basis_lie_highest_weight_compute( - lie_algebra, chevalley_basis, highest_weight, operators, monomial_ordering + L, chevalley_basis, highest_weight, operators, monomial_ordering ) end @doc """ # Examples ```jldoctest -julia> BasisLieHighestWeight.basis_lie_highest_weight_nz(:C, 3, [1,1,1]; reduced_expression=[3,2,3,2,1,2,3,2,1]) +julia> BasisLieHighestWeight.basis_lie_highest_weight_nz(:C, 3, [1,1,1], [3,2,3,2,1,2,3,2,1]) Monomial basis of a highest weight module of highest weight [1, 1, 1] of dimension 512 @@ -279,7 +318,7 @@ over lie-Algebra of type C and rank 3 ``` """ function basis_lie_highest_weight_nz( - type::Symbol, rank::Int, highest_weight::Vector{Int}; reduced_expression::Vector{Int} + type::Symbol, rank::Int, highest_weight::Vector{Int}, reduced_expression::Vector{Int} ) """ Nakashima-Zelevinsky polytope @@ -287,9 +326,10 @@ function basis_lie_highest_weight_nz( BasisLieHighestWeight.basis_lie_highest_weight_nz(:A, 4, [1,1,1,1], [4,3,2,1,2,3,4,3,2,3]) """ monomial_ordering = :degrevlex - lie_algebra, chevalley_basis = lie_algebra_with_basis(type, rank) - operators = get_operators_normal(lie_algebra, chevalley_basis, reduced_expression) + L = lie_algebra(type, rank) + chevalley_basis = chevalley_basis_gap(L) + operators = operators_by_index(L, chevalley_basis, reduced_expression) return basis_lie_highest_weight_compute( - lie_algebra, chevalley_basis, highest_weight, operators, monomial_ordering + L, chevalley_basis, highest_weight, operators, monomial_ordering ) end diff --git a/experimental/BasisLieHighestWeight/src/WeylPolytope.jl b/experimental/BasisLieHighestWeight/src/WeylPolytope.jl index 4af73f040bc9..eb3c0cb5c35f 100644 --- a/experimental/BasisLieHighestWeight/src/WeylPolytope.jl +++ b/experimental/BasisLieHighestWeight/src/WeylPolytope.jl @@ -1,13 +1,11 @@ -function orbit_weylgroup( - lie_algebra::LieAlgebraStructure, weight_vector_w::Vector{ZZRingElem} -) +function orbit_weylgroup(L::LieAlgebraStructure, weight_vector_w::Vector{ZZRingElem}) """ operates weyl-group of type type and rank rank on vector weight_vector and returns list of vectors in orbit input and output weights in terms of w_i """ # initialization - weyl_group = GAP.Globals.WeylGroup(GAP.Globals.RootSystem(lie_algebra.lie_algebra_gap)) + weyl_group = GAP.Globals.WeylGroup(GAP.Globals.RootSystem(L.lie_algebra_gap)) orbit_iterator = GAP.Globals.WeylOrbitIterator(weyl_group, GAP.Obj(Int.(weight_vector_w))) vertices = Vector{Int}[] @@ -22,7 +20,7 @@ function orbit_weylgroup( end function get_dim_weightspace( - lie_algebra::LieAlgebraStructure, highest_weight::Vector{ZZRingElem} + L::LieAlgebraStructure, highest_weight::Vector{ZZRingElem} )::Dict{Vector{ZZRingElem},Int} """ Calculates dictionary with weights as keys and dimension of corresponding weightspace as value. GAP computes the @@ -30,7 +28,7 @@ function get_dim_weightspace( calculate the dimension of each weightspace. Returns weights in w_i """ # calculate dimension for dominant weights with GAP - root_system = GAP.Globals.RootSystem(lie_algebra.lie_algebra_gap) + root_system = GAP.Globals.RootSystem(L.lie_algebra_gap) dominant_char = GAP.Globals.DominantCharacter(root_system, GAP.Obj(Int.(highest_weight))) dominant_weights_w = map(weight -> ZZ.(weight), dominant_char[1]) dominant_weights_dim = Int.(dominant_char[2]) @@ -38,7 +36,7 @@ function get_dim_weightspace( # calculate dimension for the rest by checking which positive weights lies in the orbit. for i in 1:length(dominant_weights_w) - orbit_weights = orbit_weylgroup(lie_algebra, dominant_weights_w[i]) + orbit_weights = orbit_weylgroup(L, dominant_weights_w[i]) dim_weightspace = dominant_weights_dim[i] for weight in orbit_weights weightspaces[highest_weight - weight] = dim_weightspace diff --git a/experimental/BasisLieHighestWeight/src/WordCalculations.jl b/experimental/BasisLieHighestWeight/src/WordCalculations.jl deleted file mode 100644 index 52d3e3088475..000000000000 --- a/experimental/BasisLieHighestWeight/src/WordCalculations.jl +++ /dev/null @@ -1,154 +0,0 @@ -function compute_betas_lustzig( - lie_algebra::LieAlgebraStructure, word::Vector{Int} -)::Vector{Vector{Int}} - """ - Calculate betas from type, rank and a longest-word from the weylgroup. - """ - # Construct Gap-Objects - root_system = GAP.Globals.RootSystem(lie_algebra.lie_algebra_gap) - - simple_roots = GAP.Globals.SimpleSystem(root_system) - weyl_group = GAP.Globals.WeylGroup(root_system) - sparse_cartan_matrix = GAP.Globals.SparseCartanMatrix(weyl_group) - - # Calculate betas by applying simple-reflections step-by-step. - betas = [] - - for k in 1:length(word) - beta = copy(simple_roots[word[k]]) - for j in (k - 1):-1:1 # Iterate in reverse - GAP.Globals.ApplySimpleReflection(sparse_cartan_matrix, word[j], beta) - end - push!(betas, beta) - end - - julia_betas = [Int[i for i in GAP.Globals.List(gap_obj)] for gap_obj in betas] - return julia_betas -end - -function compute_betas_simple_reflections( - lie_algebra::LieAlgebraStructure, word::Vector{<:Union{Int,Vector{Int}}} -)::Vector{Vector{Int}} - """ - Calculate betas from type, rank and a longest-word from the weylgroup. - """ - # Construct Gap-Objects - root_system = GAP.Globals.RootSystem(lie_algebra.lie_algebra_gap) - - simple_roots = GAP.Globals.SimpleSystem(root_system) - weyl_group = GAP.Globals.WeylGroup(root_system) - sparse_cartan_matrix = GAP.Globals.SparseCartanMatrix(weyl_group) - - # Positive roots - root_system = GAP.Globals.RootSystem(lie_algebra.lie_algebra_gap) - positive_roots = Vector{Vector{Int}}(GAP.Globals.PositiveRoots(root_system)) - - # Calculate betas by adding roots for vectors - # Root-system Gap-Objects - betas = [] - for root in word - if isa(root, Int) - push!(betas, positive_roots[root]) - elseif isa(root, Vector{Int}) - result = zeros(Int, length(first(positive_roots))) - for idx in root - result .+= positive_roots[idx] - end - push!(betas, result) - else - error("Invalid input, only accepts Vector of Int and Vector{Int}") - end - end - return betas -end - -function roots_to_root_vectors( - lie_algebra::LieAlgebraStructure, - chevalley_basis::NTuple{3,Vector{GAP.Obj}}, - roots::Vector{Vector{Int}}, -)::Vector{GAP.Obj} - """ - Returns for list of roots the corresponding root-vectors from GAP - """ - # Root-system Gap-Objects - root_system = GAP.Globals.RootSystem(lie_algebra.lie_algebra_gap) - - # positive-roots - positive_roots = Vector{Vector{Int}}(GAP.Globals.PositiveRoots(root_system)) - positive_root_vectors = chevalley_basis[1] - - # negative-roots - negative_roots = Vector{Vector{Int}}(GAP.Globals.NegativeRoots(root_system)) - negative_root_vectors = chevalley_basis[2] - - return [ - find_root_in_chevalley_basis( - positive_roots, positive_root_vectors, negative_roots, negative_root_vectors, root - ) for root in roots - ] -end - -function find_root_in_chevalley_basis( - positive_roots::Vector{Vector{Int}}, - positive_root_vectors::Vector{GAP.Obj}, - negative_roots::Vector{Vector{Int}}, - negative_root_vectors::Vector{GAP.Obj}, - root::Vector{Int}, -)::GAP.Obj - """ - For a given positive or negative root, return the GAP root vector. - """ - # Check if root is positive-root - for (i, root_i) in enumerate(positive_roots) - if root == root_i - return positive_root_vectors[i] - end - end - - # Check if root is negative-root - for (i, root_i) in enumerate(negative_roots) - if root == root_i - return negative_root_vectors[i] - end - end - - return false -end - -function get_operators_lustzig( - lie_algebra::LieAlgebraStructure, - chevalley_basis::NTuple{3,Vector{GAP.Obj}}, - reduced_expression::Vector{Int}, -)::Vector{GAP.Obj} - """ - Computes the operators for the lustzig and nz polytopes for a longest weyl-word - reduced_expression. - - \beta_k := s_{i_1} … s_{i_{k-1}} (\alpha_{i_k}) - - F.e. for A, 2, [1, 2, 1], we get - \beta_1 = \alpha_1 - \beta_2 = \alpha_1 + \alpha_2 - \beta_3 = \alpha_2 - """ - betas = compute_betas_lustzig(lie_algebra, reduced_expression) - operators = roots_to_root_vectors(lie_algebra, chevalley_basis, betas) - return operators -end - -function get_operators_simple_reflections( - lie_algebra::LieAlgebraStructure, - chevalley_basis::NTuple{3,Vector{GAP.Obj}}, - reduced_expression::Vector{Union{Int,Vector{Int}}}, -)::Vector{GAP.Obj} - """ - Computes the operators given a Vector of either the index of a positive root, or - a vector that gets evaluated as its sum. F.e. - - B3, [1, [1, 2]] -> [positive root 1, positive root 4] - """ - betas = compute_betas_simple_reflections(lie_algebra, reduced_expression) - operators = roots_to_root_vectors(lie_algebra, chevalley_basis, betas) - - return operators -end diff --git a/experimental/BasisLieHighestWeight/test/MainAlgorithm-test.jl b/experimental/BasisLieHighestWeight/test/MainAlgorithm-test.jl index 0b962b4a7b8c..9ac2a707d77b 100644 --- a/experimental/BasisLieHighestWeight/test/MainAlgorithm-test.jl +++ b/experimental/BasisLieHighestWeight/test/MainAlgorithm-test.jl @@ -77,9 +77,7 @@ end base = BasisLieHighestWeight.basis_lie_highest_weight(:A, 2, [1, 0]) mons = monomials(base) @test issetequal(string.(mons), Set(["1", "x3", "x1"])) - base = BasisLieHighestWeight.basis_lie_highest_weight( - :A, 2, [1, 0]; birational_sequence=[1, 2, 1] - ) + base = BasisLieHighestWeight.basis_lie_highest_weight(:A, 2, [1, 0], [1, 2, 1]) mons = monomials(base) @test issetequal(string.(mons), Set(["1", "x2*x3", "x3"])) end diff --git a/experimental/BasisLieHighestWeight/test/RootConversion-test.jl b/experimental/BasisLieHighestWeight/test/RootConversion-test.jl index a191fd3f54da..f4f8fb66de35 100644 --- a/experimental/BasisLieHighestWeight/test/RootConversion-test.jl +++ b/experimental/BasisLieHighestWeight/test/RootConversion-test.jl @@ -3,9 +3,9 @@ w_to_alpha = BasisLieHighestWeight.w_to_alpha alpha_to_w = BasisLieHighestWeight.alpha_to_w - function test_inverse_alpha_w(lie_algebra, weight) - @test w_to_alpha(lie_algebra, alpha_to_w(lie_algebra, weight)) == weight # alpha -> w -> alpha - @test alpha_to_w(lie_algebra, w_to_alpha(lie_algebra, weight)) == weight # w -> alpha -> w + function test_inverse_alpha_w(L, weight) + @test w_to_alpha(L, alpha_to_w(L, weight)) == weight # alpha -> w -> alpha + @test alpha_to_w(L, w_to_alpha(L, weight)) == weight # w -> alpha -> w end @testset "Dynkin type $dynkin" for dynkin in (:A, :B, :C, :D, :E, :F, :G) @@ -20,8 +20,8 @@ ) weight = [rand(QQ, -10:10) for _ in 1:n] print(".") - lie_algebra = BasisLieHighestWeight.LieAlgebraStructure(dynkin, n) - test_inverse_alpha_w(lie_algebra, weight) + L = BasisLieHighestWeight.lie_algebra(dynkin, n) + test_inverse_alpha_w(L, weight) end end end diff --git a/experimental/BasisLieHighestWeight/test/WordCalculations-test.jl b/experimental/BasisLieHighestWeight/test/WordCalculations-test.jl deleted file mode 100644 index d1099135faf6..000000000000 --- a/experimental/BasisLieHighestWeight/test/WordCalculations-test.jl +++ /dev/null @@ -1,12 +0,0 @@ -@testset "Test CalculateBetas for A2" begin - type = :A - rank = 2 - word = [1, 2, 1] - lie_algebra = BasisLieHighestWeight.LieAlgebraStructure(type, rank) - - betas = BasisLieHighestWeight.compute_betas_lustzig(lie_algebra, word) - - # Expected beta values - expected_betas = [[2, -1], [1, 1], [-1, 2]] - @test betas == expected_betas -end diff --git a/experimental/BasisLieHighestWeight/test/runtests.jl b/experimental/BasisLieHighestWeight/test/runtests.jl index 8e884ea1524e..492f8925bfa1 100644 --- a/experimental/BasisLieHighestWeight/test/runtests.jl +++ b/experimental/BasisLieHighestWeight/test/runtests.jl @@ -2,4 +2,3 @@ include("VectorSpaceBases-test.jl") include("NewMonomial-test.jl") include("RootConversion-test.jl") include("MainAlgorithm-test.jl") -include("WordCalculations-test.jl")