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

LieAlgebras: Adapt Demazure operator #4384

Merged
merged 21 commits into from
Jan 9, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
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
2 changes: 2 additions & 0 deletions docs/src/LieTheory/root_systems.md
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,8 @@ is_negative_root_with_index(::RootSpaceElem)
```@docs
reflect(::RootSpaceElem, ::Int)
reflect!(::RootSpaceElem, ::Int)
reflect(::RootSpaceElem, ::RootSpaceElem)
reflect!(::RootSpaceElem, ::RootSpaceElem)
```


Expand Down
2 changes: 2 additions & 0 deletions docs/src/LieTheory/weight_lattices.md
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ is_fundamental_weight_with_index(::WeightLatticeElem)
```@docs
reflect(::WeightLatticeElem, ::Int)
reflect!(::WeightLatticeElem, ::Int)
reflect(::WeightLatticeElem, ::RootSpaceElem)
reflect!(::WeightLatticeElem, ::RootSpaceElem)
```

### Conjugate dominant weight
Expand Down
14 changes: 13 additions & 1 deletion docs/src/LieTheory/weyl_groups.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@ weyl_group(::Vector{Tuple{Symbol,Int}})
## Basic properties
Basic group arithmetic like `*`, and `inv` are defined for `WeylGroupElem` objects.

Using `(W::WeylGroup)(word::Vector{<:Integer})`, one can construct group elements from a word in the generators.
Finite Weyl groups support iteration over all group elements (in an arbitrary order).

```@docs
Expand All @@ -50,6 +49,19 @@ order(::Type{T}, ::WeylGroup) where {T}
root_system(::WeylGroup)
```

### Element constructors

Using `(W::WeylGroup)(word::Vector{<:Integer})`, one can construct group elements from a word in the generators.

```@docs; canonical=false
gen(::WeylGroup, ::Int)
gens(::WeylGroup)
```

```@docs
reflection(::RootSpaceElem)
```

### Words and length
```@docs
word(::WeylGroupElem)
Expand Down
35 changes: 29 additions & 6 deletions experimental/LieAlgebras/src/RootSystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -335,13 +335,12 @@ end
###############################################################################
# demazures character formula
function _demazure_operator(r::RootSpaceElem, w::WeightLatticeElem)
fl, index_of_r = is_simple_root_with_index(r)
@req fl "not a simple root"
@req is_positive_root(r) "r is not a positive root"

d = 2 * dot(w, r)//dot(r, r)
list_of_occuring_weights = WeightLatticeElem[]

refl = reflect(w, index_of_r)
refl = reflect(w, r)

wlelem_r = WeightLatticeElem(r)
if d > -1
Expand All @@ -364,10 +363,30 @@ function _demazure_operator(r::RootSpaceElem, w::WeightLatticeElem)
end
end

function demazure_operator(r::RootSpaceElem, w::WeightLatticeElem)
return demazure_operator(r, Dict(w => 1))
end
@doc raw"""
demazure_operator(r::RootSpaceElem, w::WeightLatticeElem) -> Dict{WeightLatticeElem,<:IntegerUnion}
demazure_operator(r::RootSpaceElem, groupringelem::Dict{WeightLatticeElem,<:IntegerUnion}) -> Dict{WeightLatticeElem,<:IntegerUnion}

Computes the action of the Demazure operator associated to the positive root `r` on the given element of the group ring $\mathbb{Z}[P]$.

If a single Weight lattice element `w` is supplied, this is interpreted as `Dict(w => 1)`.

# Examples
```jldoctest
julia> R = root_system(:A, 3);

julia> pos_r = positive_root(R, 4)
a_1 + a_2

julia> w = fundamental_weight(R, 1)
w_1

julia> demazure_operator(pos_r, w)
Dict{WeightLatticeElem, Int64} with 2 entries:
-w_2 + w_3 => 1
w_1 => 1
```
"""
function demazure_operator(
r::RootSpaceElem, groupringelem::Dict{WeightLatticeElem,<:IntegerUnion}
)
Expand All @@ -386,6 +405,10 @@ function demazure_operator(
return dict
end

function demazure_operator(r::RootSpaceElem, w::WeightLatticeElem)
return demazure_operator(r, Dict(w => 1))
end

@doc raw"""
demazure_character([T = Int], R::RootSystem, w::WeightLatticeElem, x::WeylGroupElem) -> Dict{WeightLatticeElem, T}
demazure_character([T = Int], R::RootSystem, w::Vector{<:IntegerUnion}, x::WeylGroupElem) -> Dict{WeightLatticeElem, T}
Expand Down
31 changes: 31 additions & 0 deletions experimental/LieAlgebras/test/LieAlgebraModule-test.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1150,6 +1150,37 @@
end
end

@testset "demazure_operator" begin
R = root_system(:B, 2)
rho = weyl_vector(R)

@test demazure_operator(simple_root(R, 1), rho) == Dict(
WeightLatticeElem(R, [1, 1]) => 1,
WeightLatticeElem(R, [-1, 3]) => 1,
)

@test demazure_operator(simple_root(R, 2), rho) == Dict(
WeightLatticeElem(R, [1, 1]) => 1,
WeightLatticeElem(R, [2, -1]) => 1,
)

@test demazure_operator(root(R, 3), rho) == Dict(
WeightLatticeElem(R, [1, 1]) => 1,
WeightLatticeElem(R, [-2, 1]) => 1,
WeightLatticeElem(R, [0, 1]) => 1,
WeightLatticeElem(R, [-1, 1]) => 1,
)

@test demazure_operator(simple_root(R, 1), -rho) == Dict()

@test demazure_operator(simple_root(R, 2), -rho) == Dict()

@test demazure_operator(root(R, 3), -rho) == Dict(
WeightLatticeElem(R, [0, -1]) => -1,
WeightLatticeElem(R, [1, -1]) => -1,
)
end

@testset "demazure_character" begin
function demazure_character_trivial_tests(R::RootSystem, w::WeightLatticeElem)
W = weyl_group(R)
Expand Down
16 changes: 8 additions & 8 deletions src/Groups/spinor_norms.jl
Original file line number Diff line number Diff line change
Expand Up @@ -114,11 +114,11 @@ function _sigma_sharp(rkL, detL, q, p)
end

@doc raw"""
reflection(gram::QQMatrix, v::QQMatrix) -> QQMatrix
Oscar._reflection(gram::QQMatrix, v::QQMatrix) -> QQMatrix

Return the matrix representation of the orthogonal reflection in the row vector `v`.
"""
function reflection(gram::MatElem, v::MatElem)
function _reflection(gram::MatElem, v::MatElem)
n = ncols(gram)
E = identity_matrix(base_ring(gram), n)
c = base_ring(gram)(2) * ((v * gram * transpose(v)))[1,1]^(-1)
Expand Down Expand Up @@ -154,7 +154,7 @@ function spin(gram_diag::MatElem, isometry::MatElem, check::Bool=true)
r = v - w
s = r * G * transpose(r)
if !iszero(s)
tau = reflection(G, r)
tau = _reflection(G, r)
f = f * tau
@assert w * f == w
spinor_norm *= s
Expand All @@ -164,8 +164,8 @@ function spin(gram_diag::MatElem, isometry::MatElem, check::Bool=true)
r2 = v
s2 = r2 * G * transpose(r2)/2
@assert !iszero(s1) && !iszero(s2)
tau1 = reflection(G, r1)
tau2 = reflection(G, r2)
tau1 = _reflection(G, r1)
tau2 = _reflection(G, r2)
f = f * tau2 * tau1
@assert w * f == w
spinor_norm *= s1 * s2
Expand Down Expand Up @@ -219,15 +219,15 @@ function det_spin(G::QQMatrix, T::QQMatrix, p, nu)
bm = g - E[k:k,:]
qm = bm * G * transpose(bm)
if valuation(qm, p) <= gammaL[k] + 2*delta
tau1 = reflection(G, bm)
tau1 = _reflection(G, bm)
push!(reflection_vectors, bm)
tau2 = E
else
bp = g + E[k:k,:]
qp = bp * G * transpose(bp)
@assert valuation(qp, p) <= gammaL[k] + 2*delta
tau1 = reflection(G, bp)
tau2 = reflection(G, E[k:k,:])
tau1 = _reflection(G, bp)
tau2 = _reflection(G, E[k:k,:])
push!(reflection_vectors,bp)
push!(reflection_vectors,E[k:k,:])
end
Expand Down
44 changes: 41 additions & 3 deletions src/LieTheory/RootSystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1102,6 +1102,32 @@
return r
end

@doc raw"""
reflect(r::RootSpaceElem, beta::RootSpaceElem) -> RootSpaceElem

Return the reflection of `r` in the hyperplane orthogonal to root `beta`.

See also: [`reflect!(::RootSpaceElem, ::RootSpaceElem)`](@ref).
"""
function reflect(r::RootSpaceElem, beta::RootSpaceElem)
return reflect!(deepcopy(r), beta)

Check warning on line 1113 in src/LieTheory/RootSystem.jl

View check run for this annotation

Codecov / codecov/patch

src/LieTheory/RootSystem.jl#L1112-L1113

Added lines #L1112 - L1113 were not covered by tests
end

@doc raw"""
reflect!(r::RootSpaceElem, beta::RootSpaceElem) -> RootSpaceElem

Reflect `r` in the hyperplane orthogonal to the root `beta`, and return it.

This is a mutating version of [`reflect(::RootSpaceElem, ::RootSpaceElem)`](@ref).
"""
function reflect!(r::RootSpaceElem, beta::RootSpaceElem)
@req root_system(r) === root_system(beta) "Incompatible root systems"
for s in word(reflection(beta))
reflect!(r, Int(s))
end
return r

Check warning on line 1128 in src/LieTheory/RootSystem.jl

View check run for this annotation

Codecov / codecov/patch

src/LieTheory/RootSystem.jl#L1123-L1128

Added lines #L1123 - L1128 were not covered by tests
end

@doc raw"""
root_system(r::RootSpaceElem) -> RootSystem

Expand Down Expand Up @@ -1452,8 +1478,20 @@
###############################################################################
# internal helpers

# cartan matrix in the format <a^v, b>
function positive_roots_and_reflections(cartan_matrix::ZZMatrix)
@doc raw"""
_positive_roots_and_reflections(cartan_matrix::ZZMatrix) -> Vector{Vector{ZZRingElem}}, Vector{Vector{ZZRingElem}}, Matrix{UInt64}

Compute the positive roots, the positive coroots, and a matrix `refl` of size $m \times n$,
where $m$ is the rank of the root system and $n$ is the number of minimal roots.

The minimal roots and coroots are given as coefficient vectors w.r.t. the simple roots and simple coroots, respectively.
The minimal roots are indexed by `1:n`, with the first `m` of them corresponding
to the simple roots, and the other roots sorted by height.

If `beta = alpha_j * s_i` is a minimal root, then `refl_table[i, j]` stores the index of beta, and otherwise `0`.
Note that `refl_table[i, i] = 0` for every simple root `alpha_i`.
"""
function _positive_roots_and_reflections(cartan_matrix::ZZMatrix)
rank, _ = size(cartan_matrix)

roots = [[l == s ? one(ZZ) : zero(ZZ) for l in 1:rank] for s in 1:rank]
Expand Down Expand Up @@ -1508,5 +1546,5 @@
table[s, i] = iszero(refl[s, perm[i]]) ? 0 : invp[refl[s, perm[i]]]
end

roots[perm], coroots[perm], table
return roots[perm], coroots[perm], table
end
4 changes: 2 additions & 2 deletions src/LieTheory/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ See [`root_system(::ZZMatrix)`](@ref) for the constructor.
function RootSystem(mat::ZZMatrix; check::Bool=true, detect_type::Bool=true)
check && @req is_cartan_matrix(mat) "Requires a generalized Cartan matrix"

pos_roots, pos_coroots, refl = positive_roots_and_reflections(mat)
pos_roots, pos_coroots, refl = _positive_roots_and_reflections(mat)
finite = count(refl .== 0) == nrows(mat)

R = new(mat)
Expand Down Expand Up @@ -149,7 +149,7 @@ See [`weyl_group(::RootSystem)`](@ref) for the constructor.
"""
@attributes mutable struct WeylGroup <: AbstractAlgebra.Group
finite::Bool # finite indicates whether the Weyl group is finite
refl::Matrix{UInt} # see positive_roots_and_reflections
refl::Matrix{UInt} # see _positive_roots_and_reflections
root_system::RootSystem # root_system is the RootSystem from which the Weyl group was constructed

function WeylGroup(finite::Bool, refl::Matrix{UInt}, root_system::RootSystem)
Expand Down
26 changes: 26 additions & 0 deletions src/LieTheory/WeightLattice.jl
Original file line number Diff line number Diff line change
Expand Up @@ -462,3 +462,29 @@ function reflect!(w::WeightLatticeElem, s::Int)
w.vec = addmul!(w.vec, view(cartan_matrix_tr(root_system(w)), s:s, :), -w.vec[s]) # change to submul! once available
return w
end

@doc raw"""
reflect(w::WeightLatticeElem, beta::RootSpaceElem) -> RootSpaceElem

Return the reflection of `w` in the hyperplane orthogonal to root `beta`.

See also: [`reflect!(::WeightLatticeElem, ::RootSpaceElem)`](@ref).
"""
function reflect(w::WeightLatticeElem, beta::RootSpaceElem)
return reflect!(deepcopy(w), beta)
end

@doc raw"""
reflect!(w::WeightLatticeElem, beta::RootSpaceElem) -> RootSpaceElem

Reflect `w` in the hyperplane orthogonal to the root `beta`, and return it.

This is a mutating version of [`reflect(::WeightLatticeElem, ::RootSpaceElem)`](@ref).
"""
function reflect!(w::WeightLatticeElem, beta::RootSpaceElem)
janikapeters marked this conversation as resolved.
Show resolved Hide resolved
@req root_system(w) === root_system(beta) "Incompatible root systems"
for s in word(reflection(beta))
reflect!(w, Int(s))
end
return w
end
37 changes: 37 additions & 0 deletions src/LieTheory/WeylGroup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -516,6 +516,43 @@ function word(x::WeylGroupElem)
return x.word
end

@doc raw"""
reflection(beta::RootSpaceElem) -> WeylGroupElem

Return the Weyl group element corresponding to the reflection at the hyperplane orthogonal to the root `beta`.
"""
function reflection(beta::RootSpaceElem)
R = root_system(beta)
W = weyl_group(R)
rk = number_of_simple_roots(R)

b, index_of_beta = is_root_with_index(beta)
@req b "Not a root"
# for a negative root we want the index of the corresponding positive root
if index_of_beta > number_of_positive_roots(R)
index_of_beta -= number_of_positive_roots(R)
end

found_simple_root = index_of_beta <= rk
current_index = index_of_beta
list_of_indices = Int[]
while !found_simple_root
for j in 1:rk
next_index = W.refl[j, current_index]
if !iszero(next_index) &&
next_index < current_index
current_index = next_index
if current_index <= rk
found_simple_root = true
end
push!(list_of_indices, j)
break
end
end
end
return W([list_of_indices; current_index; reverse(list_of_indices)])
end

###############################################################################
# ReducedExpressionIterator

Expand Down
1 change: 1 addition & 0 deletions src/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1400,6 +1400,7 @@ export reduced_groebner_basis
export reduced_scheme
export reducible_fibers
export reflect, reflect!
export reflection
janikapeters marked this conversation as resolved.
Show resolved Hide resolved
export register_morphism!
export regular_120_cell
export regular_24_cell
Expand Down
Loading
Loading