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

Lie algebras: more progress #4053

Merged
merged 18 commits into from
Sep 16, 2024
Merged
Show file tree
Hide file tree
Changes from 15 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
12 changes: 12 additions & 0 deletions docs/oscar_references.bib
Original file line number Diff line number Diff line change
Expand Up @@ -1766,6 +1766,18 @@ @Misc{MNP24
url = {https://gap-packages.github.io/tomlib/}
}

@Article{MP82,
author = {Moody, R. V. and Patera, J.},
title = {Fast recursion formula for weight multiplicities},
journal = {Bull. Amer. Math. Soc. (N.S.)},
fjournal = {American Mathematical Society. Bulletin. New Series},
volume = {7},
number = {1},
pages = {237--242},
year = {1982},
doi = {10.1090/S0273-0979-1982-15021-2}
}

@Article{MR20,
author = {Markwig, Thomas and Ren, Yue},
title = {Computing tropical varieties over fields with valuation},
Expand Down
38 changes: 22 additions & 16 deletions experimental/LieAlgebras/src/CoxeterGroup.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,32 @@
then this will be expressed by $m_{ij} = 0$ (instead of the usual convention $m_{ij} = \infty$).
The keyword argument `check` can be set to `false` to skip verification whether `gcm` is indeed a generalized Cartan matrix.
"""
function coxeter_from_cartan_matrix(gcm; check::Bool=true)
function coxeter_from_cartan_matrix(gcm::ZZMatrix; check::Bool=true)

Check warning on line 10 in experimental/LieAlgebras/src/CoxeterGroup.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CoxeterGroup.jl#L10

Added line #L10 was not covered by tests
@req !check || is_cartan_matrix(gcm) "requires a generalized Cartan matrix"

cm = identity_matrix(gcm)
rk, _ = size(gcm)
for i in 1:rk, j in 1:rk
if i == j
continue
end
cm = matrix(

Check warning on line 14 in experimental/LieAlgebras/src/CoxeterGroup.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CoxeterGroup.jl#L14

Added line #L14 was not covered by tests
ZZ, [coxeter_matrix_entry_from_cartan_matrix(gcm, i, j) for i in 1:rk, j in 1:rk]
)

if gcm[i, j] == 0
cm[i, j] = 2
elseif gcm[i, j] == -1
cm[i, j] = 3
elseif gcm[i, j] == -2
cm[i, j] = 4
elseif gcm[i, j] == -3
cm[i, j] = 6
end
return cm

Check warning on line 18 in experimental/LieAlgebras/src/CoxeterGroup.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CoxeterGroup.jl#L18

Added line #L18 was not covered by tests
end

function coxeter_matrix_entry_from_cartan_matrix(gcm::ZZMatrix, i::Int, j::Int)
if i == j
return 1
end

return cm
d = gcm[i, j] * gcm[j, i]
if d == 0
return 2
elseif d == 1
return 3
elseif d == 2
return 4
elseif d == 3
return 6
else
return 0
end
end
145 changes: 114 additions & 31 deletions experimental/LieAlgebras/src/LieAlgebraModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1398,10 +1398,10 @@ function simple_module(L::LieAlgebra, hw::Vector{Int})
end

@doc raw"""
dim_of_simple_module([T = Int], L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> T
dim_of_simple_module([T = Int,] L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> T
lgoettgens marked this conversation as resolved.
Show resolved Hide resolved

Compute the dimension of the simple module of the Lie algebra `L` with highest weight `hw`
using Weyl's dimension formula.
using Weyl's dimension formula.
The return value is of type `T`.

# Example
Expand Down Expand Up @@ -1431,11 +1431,65 @@ function dim_of_simple_module(L::LieAlgebra, hw::Vector{<:IntegerUnion})
end

@doc raw"""
dominant_character(L::LieAlgebra{C}, hw::Vector{Int}) -> Dict{Vector{Int}, Int}
dominant_weights([T,] L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> Vector{T}
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
dominant_weights([T,] L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> Vector{T}
dominant_weights([T = Vector{Int}], L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> Vector{T}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not want to specify this at this point, as I want to straight out all of the return types in the near future. That's also the reason for the many `The return type will change in the future" in docstrings.


Computes the dominant weights occurring in the simple module of the Lie algebra `L` with highest weight `hw`,
sorted ascendingly by the total height of roots needed to reach them from `hw`.

When supplying `T = Vector{Int}`, the weights are returned as vectors of integers.

See [MP82](@cite) for details and the implemented algorithm.

# Example
```jldoctest
julia> L = lie_algebra(QQ, :B, 3);

julia> dominant_weights(L, [1, 0, 3])
7-element Vector{Vector{Int64}}:
[1, 0, 3]
[1, 1, 1]
[2, 0, 1]
[0, 0, 3]
[0, 1, 1]
[1, 0, 1]
[0, 0, 1]
```
"""
function dominant_weights(T::Type, L::LieAlgebra, hw::Vector{<:IntegerUnion})
if has_root_system(L)
R = root_system(L)
return dominant_weights(T, R, hw)
else # TODO: remove branch once root system detection is implemented
@req is_dominant_weight(hw) "Not a dominant weight."
return first.(
sort!(
collect(
T(w) => d for (w, d) in
zip(
GAP.Globals.DominantWeights(
GAP.Globals.RootSystem(codomain(Oscar.iso_oscar_gap(L))),
GAP.Obj(hw; recursive=true),
)...,
)
); by=last)
)
end
fingolfin marked this conversation as resolved.
Show resolved Hide resolved
end

function dominant_weights(L::LieAlgebra, hw::Vector{<:IntegerUnion})
return dominant_weights(Vector{Int}, L, hw)
end

@doc raw"""
dominant_character(L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> Dict{Vector{Int}, Int}

Computes the dominant weights occurring in the simple module of the Lie algebra `L` with highest weight `hw`,
together with their multiplicities.

The return type may change in the future.

This function uses an optimized version of the Freudenthal formula, see [MP82](@cite) for details.

# Example
```jldoctest
julia> L = lie_algebra(QQ, :A, 3);
Expand All @@ -1448,19 +1502,31 @@ Dict{Vector{Int64}, Int64} with 4 entries:
[0, 2, 0] => 1
```
"""
function dominant_character(L::LieAlgebra, hw::Vector{Int})
@req is_dominant_weight(hw) "Not a dominant weight."
return Dict{Vector{Int},Int}(
Vector{Int}(w) => d for (w, d) in
zip(GAPWrap.DominantCharacter(codomain(Oscar.iso_oscar_gap(L)), GAP.Obj(hw))...)
)
function dominant_character(L::LieAlgebra, hw::Vector{<:IntegerUnion})
if has_root_system(L)
R = root_system(L)
return dominant_character(R, hw)
else # TODO: remove branch once root system detection is implemented
@req is_dominant_weight(hw) "Not a dominant weight."
return Dict{Vector{Int},Int}(
Vector{Int}(w) => d for (w, d) in
zip(
GAPWrap.DominantCharacter(
codomain(Oscar.iso_oscar_gap(L)), GAP.Obj(hw; recursive=true)
)...,
)
)
end
end

@doc raw"""
character(L::LieAlgebra{C}, hw::Vector{Int}) -> Dict{Vector{Int}, Int}
character(L::LieAlgebra{C}, hw::Vector{<:IntegerUnion}) -> Dict{Vector{Int}, Int}

Computes all weights occurring in the simple module of the Lie algebra `L` with highest weight `hw`,
together with their multiplicities.
This is achieved by acting with the Weyl group on the [`dominant_character`](@ref dominant_character(::LieAlgebra, ::Vector{<:IntegerUnion})).

The return type may change in the future.

# Example
```jldoctest
Expand All @@ -1476,29 +1542,37 @@ Dict{Vector{Int64}, Int64} with 10 entries:
[1, -1, 1] => 1
[-1, 0, 1] => 1
[1, 0, -1] => 1
[0, -1, 0] => 1
[2, 0, 0] => 1
[0, -1, 0] => 1
```
"""
function character(L::LieAlgebra, hw::Vector{Int})
@req is_dominant_weight(hw) "Not a dominant weight."
dc = dominant_character(L, hw)
c = Dict{Vector{Int},Int}()
W = GAPWrap.WeylGroup(GAPWrap.RootSystem(codomain(Oscar.iso_oscar_gap(L))))
for (w, d) in dc
it = GAPWrap.WeylOrbitIterator(W, GAP.Obj(w))
while !GAPWrap.IsDoneIterator(it)
push!(c, Vector{Int}(GAPWrap.NextIterator(it)) => d)
function character(L::LieAlgebra, hw::Vector{<:IntegerUnion})
if has_root_system(L)
R = root_system(L)
return character(R, hw)
else # TODO: remove branch once root system detection is implemented
@req is_dominant_weight(hw) "Not a dominant weight."
dc = dominant_character(L, hw)
c = Dict{Vector{Int},Int}()
W = GAPWrap.WeylGroup(GAPWrap.RootSystem(codomain(Oscar.iso_oscar_gap(L))))
for (w, d) in dc
it = GAPWrap.WeylOrbitIterator(W, GAP.Obj(w))
while !GAPWrap.IsDoneIterator(it)
push!(c, Vector{Int}(GAPWrap.NextIterator(it)) => d)
end
end
return c
end
return c
end

@doc raw"""
tensor_product_decomposition(L::LieAlgebra, hw1::Vector{Int}, hw2::Vector{Int}) -> MSet{Vector{Int}}
tensor_product_decomposition(L::LieAlgebra, hw1::Vector{<:IntegerUnion}, hw2::Vector{<:IntegerUnion}) -> MSet{Vector{Int}}

Computes the decomposition of the tensor product of the simple modules of the Lie algebra `L` with highest weights `hw1` and `hw2`
into simple modules with their multiplicities.
This function uses Klimyk's formula (see [Hum72; Exercise 24.9](@cite)).

The return type may change in the future.

# Example
```jldoctest
Expand All @@ -1518,13 +1592,22 @@ MSet{Vector{Int64}} with 6 elements:
[0, 3]
```
"""
function tensor_product_decomposition(L::LieAlgebra, hw1::Vector{Int}, hw2::Vector{Int})
@req is_dominant_weight(hw1) && is_dominant_weight(hw2) "Both weights must be dominant."
return multiset(
Tuple{Vector{Vector{Int}},Vector{Int}}(
GAPWrap.DecomposeTensorProduct(
codomain(Oscar.iso_oscar_gap(L)), GAP.Obj(hw1), GAP.Obj(hw2)
),
)...,
)
function tensor_product_decomposition(
L::LieAlgebra, hw1::Vector{<:IntegerUnion}, hw2::Vector{<:IntegerUnion}
)
if has_root_system(L)
R = root_system(L)
return tensor_product_decomposition(R, hw1, hw2)
else # TODO: remove branch once root system detection is implemented
@req is_dominant_weight(hw1) && is_dominant_weight(hw2) "Both weights must be dominant."
return multiset(
Tuple{Vector{Vector{Int}},Vector{Int}}(
GAPWrap.DecomposeTensorProduct(
codomain(Oscar.iso_oscar_gap(L)),
GAP.Obj(hw1; recursive=true),
GAP.Obj(hw2; recursive=true),
),
)...,
)
end
end
5 changes: 5 additions & 0 deletions experimental/LieAlgebras/src/LieAlgebras.jl
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ import ..Oscar:
_iso_oscar_gap,
_vec,
action,
add!,
basis_matrix,
basis,
canonical_injection,
Expand All @@ -43,6 +44,7 @@ import ..Oscar:
elem_type,
expressify,
exterior_power,
fp_group,
gen,
gens,
height,
Expand All @@ -62,9 +64,11 @@ import ..Oscar:
is_simple,
is_solvable,
is_welldefined,
isomorphism,
kernel,
lower_central_series,
matrix,
neg!,
normalizer,
number_of_generators,
ngens,
Expand All @@ -74,6 +78,7 @@ import ..Oscar:
root,
roots,
sub,
sub!,
symbols,
symmetric_power,
tensor_product,
Expand Down
Loading
Loading