diff --git a/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl b/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl index efd944b6f4a4..97bcd0ab19d2 100644 --- a/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl +++ b/experimental/BasisLieHighestWeight/src/MainAlgorithm.jl @@ -455,7 +455,7 @@ function operators_lusztig(L::LieAlgebra, reduced_expression::Vector{Int}) # Computes the operators for the lusztig polytopes for a longest weyl-word # reduced_expression. - # \beta_k := s_{i_1} … s_{i_{k-1}} (\alpha_{i_k}) + # \beta_k := (\alpha_{i_k}) s_{i_{k-1}} … s_{i_1} # F.e. for A, 2, [1, 2, 1], we get # \beta_1 = \alpha_1 @@ -465,7 +465,7 @@ function operators_lusztig(L::LieAlgebra, reduced_expression::Vector{Int}) R = root_system(L) W = weyl_group(R) operators = map(1:length(reduced_expression)) do k - root = W(reduced_expression[1:(k - 1)]) * simple_root(R, reduced_expression[k]) + root = simple_root(R, reduced_expression[k]) * W(reduced_expression[(k - 1):-1:1]) fl = is_positive_root(root) @req fl "Only positive roots may occur here" root diff --git a/experimental/BasisLieHighestWeight/src/UserFunctions.jl b/experimental/BasisLieHighestWeight/src/UserFunctions.jl index 1e2db62f0eb3..8271aadce0b0 100644 --- a/experimental/BasisLieHighestWeight/src/UserFunctions.jl +++ b/experimental/BasisLieHighestWeight/src/UserFunctions.jl @@ -162,7 +162,7 @@ for a simple Lie algebra $L$ of type `type_rank`. Let $\omega_0 = s_{i_1} \cdots s_{i_N}$ be a reduced expression of the longest element in the Weyl group of $L$ given as indices $[i_1, \dots, i_N]$ in `reduced_expression`. -Then the birational sequence used consists of $\beta_1, \dots, \beta_N$ where $\beta_1 := \alpha_{i_1}$ and \beta_k := s_{i_1} \cdots s_{i_{k-1}} \alpha_{i_k}$ for $k = 2, \dots, N$. +Then the birational sequence used consists of $\beta_1, \dots, \beta_N$ where $\beta_1 := \alpha_{i_1}$ and \beta_k := \alpha_{i_k} s_{i_{k-1}} \cdots s_{i_1}$ for $k = 2, \dots, N$. The monomial ordering is fixed to `wdegrevlex` (weighted degree reverse lexicographic order). diff --git a/experimental/LieAlgebras/docs/src/weyl_groups.md b/experimental/LieAlgebras/docs/src/weyl_groups.md index 471f762aaadb..97364f5258c9 100644 --- a/experimental/LieAlgebras/docs/src/weyl_groups.md +++ b/experimental/LieAlgebras/docs/src/weyl_groups.md @@ -8,10 +8,9 @@ DocTestSetup = Oscar.doctestsetup() Weyl groups are represented by objects of type `WeylGroup <: Group`, and their elements by `WeylGroupElem <: GroupElement`. !!! warning - Weyl groups in OSCAR afford both left and right actions on roots and weights. - Note however, that **the left action** is the default (to align with the literature), - and all more complex functionality is defined with respect to the left action, e.g. - [`conjugate_dominant_weight_with_elem(::WeightLatticeElem)`](@ref). + Weyl groups in OSCAR only afford **right** actions on roots and weights. + Note however, that this may differ from the literature, but is to stay + consistent with the conventions in the rest of OSCAR. ## Table of contents @@ -82,7 +81,6 @@ reduced_expressions(::WeylGroupElem) ## Action on roots and weights ```@docs -*(::WeylGroupElem, ::Union{RootSpaceElem,WeightLatticeElem}) *(::Union{RootSpaceElem,WeightLatticeElem}, ::WeylGroupElem) ``` diff --git a/experimental/LieAlgebras/src/LieAlgebraModule.jl b/experimental/LieAlgebras/src/LieAlgebraModule.jl index 76ece8a7b749..37b3e7204514 100644 --- a/experimental/LieAlgebras/src/LieAlgebraModule.jl +++ b/experimental/LieAlgebras/src/LieAlgebraModule.jl @@ -1594,7 +1594,7 @@ end demazure_character([T = Int], L::LieAlgebra, w::Vector{<:IntegerUnion}, reduced_expr::Vector{<:IntegerUnion}) -> Dict{WeightLatticeElem, T} Computes all weights occurring in the Demazure module of the Lie algebra `L`` -with extremal weight `x*w`, together with their multiplicities. +with extremal weight `w * x`, together with their multiplicities. Instead of a Weyl group element `x`, a reduced expression for `x` can be supplied. This function may return arbitrary results if the provided expression is not reduced. @@ -1603,7 +1603,7 @@ This function may return arbitrary results if the provided expression is not red ```jldoctest julia> L = lie_algebra(QQ, :A, 2); -julia> demazure_character(L, [1, 1], [1, 2]) +julia> demazure_character(L, [1, 1], [2, 1]) Dict{WeightLatticeElem, Int64} with 5 entries: 2*w_1 - w_2 => 1 w_1 + w_2 => 1 diff --git a/experimental/LieAlgebras/src/RootSystem.jl b/experimental/LieAlgebras/src/RootSystem.jl index d304d93bc3ba..a9a196f6198c 100644 --- a/experimental/LieAlgebras/src/RootSystem.jl +++ b/experimental/LieAlgebras/src/RootSystem.jl @@ -1561,7 +1561,7 @@ function _action_matrices_on_weights(W::WeylGroup) return map(1:rank(R)) do i x = gen(W, i) matrix( - ZZ, reduce(vcat, coefficients(x * fundamental_weight(R, j)) for j in 1:rank(R)) + ZZ, reduce(vcat, coefficients(fundamental_weight(R, j) * x) for j in 1:rank(R)) ) end end @@ -1840,7 +1840,7 @@ end demazure_character([T = Int], R::RootSystem, w::Vector{<:IntegerUnion}, reduced_expr::Vector{<:IntegerUnion}) -> Dict{WeightLatticeElem, T} Computes all weights occurring in the Demazure module of the Lie algebra defined by the root system `R` -with extremal weight `x*w`, together with their multiplicities. +with extremal weight `w * x`, together with their multiplicities. Instead of a Weyl group element `x`, a reduced expression for `x` can be supplied. This function may return arbitrary results if the provided expression is not reduced. @@ -1849,7 +1849,7 @@ This function may return arbitrary results if the provided expression is not red ```jldoctest julia> R = root_system(:B, 3); -julia> demazure_character(R, [0, 1, 0], [3, 2, 1]) +julia> demazure_character(R, [0, 1, 0], [1, 2, 3]) Dict{WeightLatticeElem, Int64} with 4 entries: w_1 + w_2 - 2*w_3 => 1 w_1 => 1 @@ -1884,7 +1884,7 @@ function demazure_character( @req root_system(w) === R "parent root system mismatch" @req is_dominant(w) "not a dominant weight" char = Dict{WeightLatticeElem,T}(w => T(1)) - for i in Iterators.reverse(reduced_expression) + for i in reduced_expression char = demazure_operator(simple_root(root_system(w), Int(i)), char) end return char diff --git a/experimental/LieAlgebras/src/WeightLattice.jl b/experimental/LieAlgebras/src/WeightLattice.jl index 7f534d0a4b5d..f883ee817b9c 100644 --- a/experimental/LieAlgebras/src/WeightLattice.jl +++ b/experimental/LieAlgebras/src/WeightLattice.jl @@ -337,9 +337,7 @@ end conjugate_dominant_weight_with_elem(w::WeightLatticeElem) -> Tuple{WeightLatticeElem, WeylGroupElem} Returns the unique dominant weight `dom` conjugate to `w` and a Weyl group element `x` -such that `x * w == dom`. - -If one wants a group element that takes `w` to`dom` using a right action, one can use `inv(x)`. +such that `w * x == dom`. """ function conjugate_dominant_weight_with_elem(w::WeightLatticeElem) return conjugate_dominant_weight_with_elem!(deepcopy(w)) @@ -362,7 +360,7 @@ function conjugate_dominant_weight_with_elem!(w::WeightLatticeElem) # reversing word means it is in short revlex normal form # and it is the element taking original w to new w - return w, weyl_group(root_system(w))(reverse!(word); normalize=false) + return w, weyl_group(root_system(w))(word; normalize=true) # TODO: is normalize=true necessary? end function dot(w1::WeightLatticeElem, w2::WeightLatticeElem) diff --git a/experimental/LieAlgebras/src/WeylGroup.jl b/experimental/LieAlgebras/src/WeylGroup.jl index 556825287754..73a50b662e47 100644 --- a/experimental/LieAlgebras/src/WeylGroup.jl +++ b/experimental/LieAlgebras/src/WeylGroup.jl @@ -248,23 +248,8 @@ function Base.:*(x::WeylGroupElem, y::WeylGroupElem) return p end -@doc raw""" - *(x::WeylGroupElem, r::RootSpaceElem) -> RootSpaceElem - *(x::WeylGroupElem, w::WeightLatticeElem) -> WeightLatticeElem - -Return the result of acting with `x` **from the left** on `r` or `w`. - -See also: [`*(::Union{RootSpaceElem,WeightLatticeElem}, ::WeylGroupElem)`](@ref). -""" -function Base.:*(x::WeylGroupElem, rw::Union{RootSpaceElem,WeightLatticeElem}) - @req root_system(parent(x)) === root_system(rw) "Incompatible root systems" - - rw2 = deepcopy(rw) - for s in Iterators.reverse(word(x)) - reflect!(rw2, Int(s)) - end - - return rw2 +function Base.:*(::WeylGroupElem, ::Union{RootSpaceElem,WeightLatticeElem}) + error("OSCAR only supports the right action of Weyl groups") end @doc raw""" @@ -697,7 +682,7 @@ end # Iterates over all weights in the Weyl group orbit of the dominant weight `weight`, # or analogously over all elements in the quotient W/W_P -# The iterator returns a tuple (wt, x), such that x*wt == iter.weight; +# The iterator returns a tuple (wt, x), such that wt*x == iter.weight; # this choice is made to align with conjugate_dominant_weight_with_elem function Base.IteratorSize(::Type{WeylIteratorNoCopy}) @@ -719,7 +704,10 @@ function Base.iterate(iter::WeylIteratorNoCopy, state::WeylIteratorNoCopyState) if isnothing(state) return nothing end - return state, state + # return state, state + # TODO: change internals of iterator to return (wt, x) with wt*x == iter.weight instead of the hack below + wt, x = state + return (wt, inv(x)), state end function _iterate_nocopy(state::WeylIteratorNoCopyState) diff --git a/experimental/LieAlgebras/test/LieAlgebraModule-test.jl b/experimental/LieAlgebras/test/LieAlgebraModule-test.jl index 6e392826f6dd..33a1c2161e31 100644 --- a/experimental/LieAlgebras/test/LieAlgebraModule-test.jl +++ b/experimental/LieAlgebras/test/LieAlgebraModule-test.jl @@ -1235,22 +1235,22 @@ #x = s[1]*s[2] char = demazure_character(R, fundamental_weight(R, 1), W([1, 2])) @test char == Dict( + WeightLatticeElem(R, [0, -1]) => 1, WeightLatticeElem(R, [-1, 1]) => 1, WeightLatticeElem(R, [1, 0]) => 1, ) char = demazure_character(R, fundamental_weight(R, 2), W([1, 2])) @test char == Dict( - WeightLatticeElem(R, [-1, 0]) => 1, WeightLatticeElem(R, [1, -1]) => 1, WeightLatticeElem(R, [0, 1]) => 1, ) char = demazure_character(R, weyl_vector(R), W([1, 2])) @test char == Dict( - WeightLatticeElem(R, [-1, 2]) => 1, - WeightLatticeElem(R, [-2, 1]) => 1, WeightLatticeElem(R, [2, -1]) => 1, + WeightLatticeElem(R, [1, -2]) => 1, + WeightLatticeElem(R, [-1, 2]) => 1, WeightLatticeElem(R, [0, 0]) => 1, WeightLatticeElem(R, [1, 1]) => 1, ) @@ -1258,22 +1258,22 @@ #x = s[2]*s[1] char = demazure_character(R, fundamental_weight(R, 1), W([2, 1])) @test char == Dict( - WeightLatticeElem(R, [0, -1]) => 1, WeightLatticeElem(R, [-1, 1]) => 1, WeightLatticeElem(R, [1, 0]) => 1, ) char = demazure_character(R, fundamental_weight(R, 2), W([2, 1])) @test char == Dict( + WeightLatticeElem(R, [-1, 0]) => 1, WeightLatticeElem(R, [1, -1]) => 1, WeightLatticeElem(R, [0, 1]) => 1, ) char = demazure_character(R, weyl_vector(R), W([2, 1])) @test char == Dict( - WeightLatticeElem(R, [2, -1]) => 1, - WeightLatticeElem(R, [1, -2]) => 1, WeightLatticeElem(R, [-1, 2]) => 1, + WeightLatticeElem(R, [-2, 1]) => 1, + WeightLatticeElem(R, [2, -1]) => 1, WeightLatticeElem(R, [0, 0]) => 1, WeightLatticeElem(R, [1, 1]) => 1, ) @@ -1435,8 +1435,8 @@ WeightLatticeElem(R, [1, 2, -1]) => 1, ) - #x=s[3]*s[2]*s[1] - char = demazure_character(R, fundamental_weight(R, 1), W([3, 2, 1])) + #x=s[1]*s[2]*s[3] + char = demazure_character(R, fundamental_weight(R, 1), W([1, 2, 3])) @test char == Dict( WeightLatticeElem(R, [0, 0, 0]) => 1, WeightLatticeElem(R, [0, 1, -2]) => 1, @@ -1445,7 +1445,7 @@ WeightLatticeElem(R, [0, -1, 2]) => 1, ) - char = demazure_character(R, fundamental_weight(R, 2), W([3, 2, 1])) + char = demazure_character(R, fundamental_weight(R, 2), W([1, 2, 3])) @test char == Dict( WeightLatticeElem(R, [0, 1, 0]) => 1, WeightLatticeElem(R, [1, -1, 2]) => 1, @@ -1453,13 +1453,13 @@ WeightLatticeElem(R, [1, 1, -2]) => 1, ) - char = demazure_character(R, fundamental_weight(R, 3), W([3, 2, 1])) + char = demazure_character(R, fundamental_weight(R, 3), W([1, 2, 3])) @test char == Dict( WeightLatticeElem(R, [0, 1, -1]) => 1, WeightLatticeElem(R, [0, 0, 1]) => 1, ) - char = demazure_character(R, weyl_vector(R), W([3, 2, 1])) + char = demazure_character(R, weyl_vector(R), W([1, 2, 3])) @test char == Dict( WeightLatticeElem(R, [2, 0, 1]) => 1, WeightLatticeElem(R, [1, 2, -3]) => 1, @@ -1602,7 +1602,7 @@ L = lie_algebra(QQ, R) w_int = [0, 1, 0] w_weight = WeightLatticeElem(R, w_int) - x = W([3, 2, 1]) + x = W([1, 2, 3]) reduced_expression = word(x) result = Dict( WeightLatticeElem(R, [0, 1, 0]) => 1, diff --git a/experimental/LieAlgebras/test/RootSystem-test.jl b/experimental/LieAlgebras/test/RootSystem-test.jl index 51b72df8b162..f51f40fe4bd5 100644 --- a/experimental/LieAlgebras/test/RootSystem-test.jl +++ b/experimental/LieAlgebras/test/RootSystem-test.jl @@ -61,7 +61,7 @@ n_roots(R) >= 1 && for _ in 1:10 r = root(R, rand(1:n_roots(R))) w = rand(W) - @test is_root(w * r) + @test is_root(r * w) end @test length(simple_coroots(R)) == n_simple_roots(R) diff --git a/experimental/LieAlgebras/test/WeightLattice-test.jl b/experimental/LieAlgebras/test/WeightLattice-test.jl index 5d1d13f98e1e..905dfda4d330 100644 --- a/experimental/LieAlgebras/test/WeightLattice-test.jl +++ b/experimental/LieAlgebras/test/WeightLattice-test.jl @@ -1,4 +1,8 @@ @testset "LieAlgebras.WeightLattice" begin + function is_in_normal_form(x::WeylGroupElem) + return word(parent(x)(word(x))) == word(x) + end + @testset "WeightLatticeElem" begin R = root_system(:A, 2) w = WeightLatticeElem(R, [2, 2]) @@ -19,8 +23,8 @@ wt = WeightLatticeElem(R, vec) d, x = conjugate_dominant_weight_with_elem(wt) @test is_dominant(d) - @test x * wt == d - @test wt * inv(x) == d + @test is_in_normal_form(x) + @test wt * x == d end end end diff --git a/experimental/LieAlgebras/test/WeylGroup-test.jl b/experimental/LieAlgebras/test/WeylGroup-test.jl index a38215dcf461..8e2282499372 100644 --- a/experimental/LieAlgebras/test/WeylGroup-test.jl +++ b/experimental/LieAlgebras/test/WeylGroup-test.jl @@ -6,6 +6,10 @@ include( ) @testset "LieAlgebras.WeylGroup" begin + function is_in_normal_form(x::WeylGroupElem) + return word(parent(x)(word(x))) == word(x) + end + b3_w0 = UInt8[3, 2, 3, 1, 2, 3, 1, 2, 1] b4_w0 = UInt8[4, 3, 4, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 1, 2, 1] f4_w0 = UInt8[4, 3, 2, 3, 1, 2, 3, 4, 3, 2, 3, 1, 2, 3, 4, 3, 2, 3, 1, 2, 3, 1, 2, 1] @@ -195,11 +199,11 @@ include( return true end - wt = x * weyl_vector(root_system(parent(x))) + wt = weyl_vector(root_system(parent(x))) * x j = length(x) - for i in 1:length(y) - if wt[Int(y[i])] < 0 - reflect!(wt, Int(y[i])) + for y_i in Iterators.reverse(word(y)) + if wt[Int(y_i)] < 0 + reflect!(wt, Int(y_i)) j -= 1 if j == 0 @@ -237,6 +241,7 @@ include( W = weyl_group(fam, rk) for x in W ix = inv(x) + @test is_in_normal_form(ix) @test length(ix) == length(x) @test isone(ix * x) == isone(x * ix) == true end @@ -250,33 +255,46 @@ include( elems = collect(W) @test allunique(elems) @test length(elems) == order(W) + @test all(is_in_normal_form, W) end end @testset "longest_element(W::WeylGroup)" begin # A1 W = weyl_group(:A, 1) - @test longest_element(W) == gen(W, 1) + w0 = longest_element(W) + @test is_in_normal_form(w0) + @test w0 == gen(W, 1) # A2 W = weyl_group(:A, 2) - @test word(longest_element(W)) == UInt8[1, 2, 1] + w0 = longest_element(W) + @test is_in_normal_form(w0) + @test word(w0) == UInt8[1, 2, 1] # B2 W = weyl_group(:B, 2) - @test word(longest_element(W)) == UInt8[2, 1, 2, 1] + w0 = longest_element(W) + @test is_in_normal_form(w0) + @test word(w0) == UInt8[2, 1, 2, 1] # B3 W = weyl_group(:B, 3) - @test word(longest_element(W)) == b3_w0 + w0 = longest_element(W) + @test is_in_normal_form(w0) + @test word(w0) == b3_w0 # F4 W = weyl_group(:F, 4) - @test word(longest_element(W)) == f4_w0 + w0 = longest_element(W) + @test is_in_normal_form(w0) + @test word(w0) == f4_w0 # G2 W = weyl_group(:G, 2) - @test word(longest_element(W)) == g2_w0 + w0 = longest_element(W) + @test is_in_normal_form(w0) + @test word(w0) == g2_w0 end @testset "ngens(W::WeylGroup)" begin @@ -352,22 +370,13 @@ include( W = weyl_group(R) a = positive_root(R, n_positive_roots(R)) # highest root - @test one(W) * a == a @test a * one(W) == a - @test W([1]) * a == simple_root(R, 2) @test a * W([1]) == simple_root(R, 2) - @test W([2]) * a == simple_root(R, 1) @test a * W([2]) == simple_root(R, 1) - @test longest_element(W) * a == -a @test a * longest_element(W) == -a - @test W([1, 2]) * a == -simple_root(R, 1) @test a * W([1, 2]) == -simple_root(R, 2) - @test W([1, 2]) * a != a * W([1, 2]) a_copy = deepcopy(a) - b = W([1]) * a - @test a != b - @test a == a_copy b = a * W([1]) @test a != b @test a == a_copy @@ -380,30 +389,18 @@ include( W = weyl_group(R) a = positive_root(R, n_positive_roots(R)) # highest (long) root - @test one(W) * a == a @test a * one(W) == a - @test W([1]) * a == a @test a * W([1]) == a - @test W([2]) * a == simple_root(R, 1) @test a * W([2]) == simple_root(R, 1) - @test longest_element(W) * a == -a @test a * longest_element(W) == -a - @test W([1, 2]) * a == -simple_root(R, 1) @test a * W([1, 2]) == simple_root(R, 1) - @test W([1, 2]) * a != a * W([1, 2]) a = simple_root(R, 1) - @test one(W) * a == a @test a * one(W) == a - @test W([1]) * a == -a @test a * W([1]) == -a - @test W([2]) * a == positive_root(R, n_positive_roots(R)) @test a * W([2]) == positive_root(R, n_positive_roots(R)) - @test longest_element(W) * a == -a @test a * longest_element(W) == -a - @test W([1, 2]) * a == positive_root(R, n_positive_roots(R)) @test a * W([1, 2]) == -positive_root(R, n_positive_roots(R)) - @test W([1, 2]) * a != a * W([1, 2]) end end @@ -412,11 +409,7 @@ include( W = weyl_group(R) rho = weyl_vector(R) - @test longest_element(W) * rho == -rho @test rho * longest_element(W) == -rho - - x = W([1, 2]) - @test x * rho != rho * x end @testset "parent(::WeylGroupElem)" begin @@ -491,7 +484,8 @@ include( @test !isnothing(findfirst(==((wt, inv(conj))), orb)) @test allunique(first.(orb)) for (ow, x) in orb - @test x * ow == dom_wt + @test is_in_normal_form(x) + @test ow * x == dom_wt end gap_num = 0 @@ -527,7 +521,8 @@ include( @test !isnothing(findfirst(==((wt, inv(conj))), orb)) @test allunique(first.(orb)) for (ow, x) in orb - @test x * ow == dom_wt + @test is_in_normal_form(x) + @test ow * x == dom_wt end gap_num = 0