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

Add Coxeter Groups and Root Systems #2689

Merged
merged 14 commits into from
Oct 28, 2023
1 change: 1 addition & 0 deletions experimental/GModule/Cohomology.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module GrpCoh
using Oscar
import Oscar: action
import Oscar: induce
import Oscar: word
import Oscar: GAPWrap, pc_group, fp_group, direct_product, direct_sum
import AbstractAlgebra: Group, Module
import Base: parent
Expand Down
2 changes: 1 addition & 1 deletion experimental/JuLie/src/JuLie.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module JuLie

using ..Oscar
import Oscar: IntegerUnion
import Oscar: IntegerUnion, weight

include("partitions.jl")
include("schur_polynomials.jl")
Expand Down
120 changes: 111 additions & 9 deletions experimental/LieAlgebras/src/AbstractLieAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
struct_consts::Matrix{SRow{C}}
s::Vector{Symbol}

# only set if known
root_system::RootSystem

function AbstractLieAlgebra{C}(
R::Field,
struct_consts::Matrix{SRow{C}},
Expand Down Expand Up @@ -69,6 +72,52 @@

dim(L::AbstractLieAlgebra) = L.dim

###############################################################################
#
# Root system getters
#
###############################################################################

has_root_system(L::LieAlgebra) = isdefined(L, :root_system)

function root_system(L::LieAlgebra)
@req has_root_system(L) "No root system known."
return L.root_system

Check warning on line 85 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L83-L85

Added lines #L83 - L85 were not covered by tests
end

has_root_system_type(L::AbstractLieAlgebra) =
has_root_system(L) && has_root_system_type(L.root_system)

function root_system_type(L::AbstractLieAlgebra)
@req has_root_system_type(L) "No root system type known."
return root_system_type(root_system(L))

Check warning on line 93 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L91-L93

Added lines #L91 - L93 were not covered by tests
end

function root_system_type_string(L::AbstractLieAlgebra)
@req has_root_system_type(L) "No root system type known."
return root_system_type_string(root_system(L))

Check warning on line 98 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L96-L98

Added lines #L96 - L98 were not covered by tests
end

@doc raw"""
chevalley_basis(L::AbstractLieAlgebra{C}) -> NTuple{3,Vector{AbstractLieAlgebraElem{C}}}

Return the Chevalley basis of the Lie algebra `L` in three vectors, stating first the positive root vectors,
Copy link
Member

Choose a reason for hiding this comment

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

You say "the" Chevalley basis, "the" Cartan subalgebra. These are not in general unique things, so what is meant? IMHO this should either be changed to "a" in both cases, or somewhere should be an explanation in how far something "unique" is returned that warrants the use "the"

then the negative root vectors, and finally the basis of the Cartan subalgebra. The order of root vectors corresponds
to the order of the roots in the root system.
"""
function chevalley_basis(L::AbstractLieAlgebra)
@req has_root_system(L) "No root system known."

Check warning on line 109 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L108-L109

Added lines #L108 - L109 were not covered by tests
Copy link
Member

Choose a reason for hiding this comment

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

Wouldn't root_system(L) below already throw a similar error? Removing this check here then would have the advantage that this method would start working once someone implements runtime computation of root systems...


npos = num_positive_roots(root_system(L))
b = basis(L)

Check warning on line 112 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L111-L112

Added lines #L111 - L112 were not covered by tests
# root vectors
r_plus = b[1:npos]
r_minus = b[(npos + 1):(2 * npos)]

Check warning on line 115 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L114-L115

Added lines #L114 - L115 were not covered by tests
# basis for cartan algebra
h = b[(2 * npos + 1):dim(L)]
return (r_plus, r_minus, h)

Check warning on line 118 in experimental/LieAlgebras/src/AbstractLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L117-L118

Added lines #L117 - L118 were not covered by tests
end

###############################################################################
#
# String I/O
Expand All @@ -79,6 +128,8 @@
io = pretty(io)
println(io, "Abstract Lie algebra")
println(io, Indent(), "of dimension $(dim(L))", Dedent())
has_root_system_type(L) &&
println(io, Indent(), "of type $(root_system_type_string(L))", Dedent())
print(io, "over ")
print(io, Lowercase(), coefficient_ring(L))
end
Expand Down Expand Up @@ -267,23 +318,74 @@
lie_algebra(R::Field, dynkin::Tuple{Char,Int}; cached::Bool) -> AbstractLieAlgebra{elem_type(R)}

Construct the simple Lie algebra over the ring `R` with Dynkin type given by `dynkin`.
Comment on lines 318 to 320
Copy link
Member

Choose a reason for hiding this comment

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

Docstring doesn't match changed signature

Suggested change
lie_algebra(R::Field, dynkin::Tuple{Char,Int}; cached::Bool) -> AbstractLieAlgebra{elem_type(R)}
Construct the simple Lie algebra over the ring `R` with Dynkin type given by `dynkin`.
lie_algebra(R::Field, S::Symbol, n::Int; cached::Bool) -> AbstractLieAlgebra{elem_type(R)}
Construct the simple Lie algebra over the ring `R` with Dynkin type given by `S` and `n`.

The actual construction is done in GAP.
The internally used basis of this Lie algebra is the Chevalley basis.

If `cached` is `true`, the constructed Lie algebra is cached.
"""
function lie_algebra(R::Field, dynkin::Tuple{Char,Int}; cached::Bool=true)
@req dynkin[1] in 'A':'G' "Unknown Dynkin type"
function lie_algebra(R::Field, S::Symbol, n::Int; cached::Bool=true)
rs = root_system(S, n)
cm = cartan_matrix(rs)
@req is_cartan_matrix(cm; generalized=false) "The type does not correspond to a classical root system"

npos = num_positive_roots(rs)
nsimp = num_simple_roots(rs)
n = 2 * npos + nsimp

#=
struct_consts = Matrix{SRow{elem_type(R)}}(undef, n, n)
for i in 1:npos, j in 1:npos
# [x_i, x_j]
fl, k = is_positive_root_with_index(positive_root(rs, i) + positive_root(rs, j))
struct_consts[i, j] = fl ? sparse_row(R, [k], [1]) : sparse_row(R)
# [x_i, y_j] = δ_ij h_i
struct_consts[i, npos + j] = i == j ? sparse_row(R, [2 * npos + i], [1]) : sparse_row(R)
# [y_j, x_i] = -[x_i, y_j]
struct_consts[npos + j, i] = -struct_consts[i, npos + j]
# [y_i, y_j]
fl, k = is_negative_root_with_index(negative_root(rs, i) + negative_root(rs, j))
struct_consts[npos + i, npos + j] = fl ? sparse_row(R, [npos + k], [1]) : sparse_row(R)
end
for i in 1:nsimp, j in 1:npos
# [h_i, x_j] = <α_j, α_i> x_j
struct_consts[2 * npos + i, j] = sparse_row(R, [j], [cm[j, i]])
# [h_i, y_j] = - <α_j, α_i> y_j
struct_consts[2 * npos + i, npos + j] = sparse_row(R, [npos + j], [-cm[j, i]])
# [x_j, h_i] = -[h_i, x_j]
struct_consts[j, 2 * npos + i] = -struct_consts[2 * npos + i, j]
# [y_j, h_i] = -[h_i, y_j]
struct_consts[npos + j, 2 * npos + i] = -struct_consts[2 * npos + i, npos + j]
end
for i in 1:nsimp, j in 1:nsimp
# [h_i, h_j] = 0
struct_consts[2 * npos + i, 2 * npos + j] = sparse_row(R)
end

s = [
[Symbol("x_$i") for i in 1:npos]
[Symbol("y_$i") for i in 1:npos]
[Symbol("h_$i") for i in 1:nsimp]
]

L = lie_algebra(R, struct_consts, s; cached, check=true) # TODO: remove check
=#

# start temporary workaround # TODO: reenable code above
type = only(root_system_type(rs))
coeffs_iso = inv(Oscar.iso_oscar_gap(R))
LG = GAP.Globals.SimpleLieAlgebra(
GAP.Obj(string(dynkin[1])), dynkin[2], domain(coeffs_iso)
)
s = [Symbol("x_$i") for i in 1:GAPWrap.Dimension(LG)]
LO = codomain(
LG = GAP.Globals.SimpleLieAlgebra(GAP.Obj(string(type[1])), type[2], domain(coeffs_iso))
@req GAPWrap.Dimension(LG) == n "Dimension mismatch. Something went wrong."
s = [
[Symbol("x_$i") for i in 1:npos]
[Symbol("y_$i") for i in 1:npos]
[Symbol("h_$i") for i in 1:nsimp]
]
L = codomain(
_iso_gap_oscar_abstract_lie_algebra(LG, s; coeffs_iso, cached)
)::AbstractLieAlgebra{elem_type(R)}
# end temporary workaround

return LO
set_attribute!(L, :is_simple, true)
return L
end

function abelian_lie_algebra(::Type{T}, R::Field, n::Int) where {T<:AbstractLieAlgebra}
Expand Down
144 changes: 144 additions & 0 deletions experimental/LieAlgebras/src/CartanMatrix.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,144 @@
###############################################################################
#
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
#

# Cartan Matrix Helpers
#
###############################################################################

@doc raw"""
cartan_matrix(fam::Symbol, rk::Int) -> ZZMatrix
"""
function cartan_matrix(fam::Symbol, rk::Int)
if fam == :A
@req rk >= 1 "type An requires rank rk of at least 1"

mat = diagonal_matrix(ZZ(2), rk)
for i in 1:(rk - 1)
mat[i + 1, i], mat[i, i + 1] = -1, -1
end
elseif fam == :B
@req rk >= 2 "type Bn requires rank rk of at least 2"

mat = diagonal_matrix(ZZ(2), rk)
for i in 1:(rk - 1)
mat[i + 1, i], mat[i, i + 1] = -1, -1
end
mat[rk, rk - 1] = -2
elseif fam == :C
@req rk >= 2 "type Cn requires rank rk of at least 2"

Check warning on line 27 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L27

Added line #L27 was not covered by tests

mat = diagonal_matrix(ZZ(2), rk)
for i in 1:(rk - 1)
mat[i + 1, i], mat[i, i + 1] = -1, -1
end
mat[rk - 1, rk] = -2

Check warning on line 33 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L29-L33

Added lines #L29 - L33 were not covered by tests
elseif fam == :D
@req rk >= 3 "type Dn requires rank rk of at least 3"

Check warning on line 35 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L35

Added line #L35 was not covered by tests

mat = diagonal_matrix(ZZ(2), rk)
for i in 1:(rk - 1)
mat[i + 1, i], mat[i, i + 1] = -1, -1
end
mat[rk - 1, rk] = -2

Check warning on line 41 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L37-L41

Added lines #L37 - L41 were not covered by tests
elseif fam == :E
@req rk in 6:8 "type En requires rank to be one of 6, 7, 8"
Copy link
Member

Choose a reason for hiding this comment

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

Just as a side remark (not a change request): Actually there is also $E_9$, $E_{10}$ - the resulting Weyl/Coxeter groups, Lie algebras just are not finite dimensional anymore. I have particular interest in these, so ultimately I'd want this to work more generally.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If you have a reference to common generalized Cartan matrices, I will implement them. For now I have implemented the classical case, but when offering generalized Cartan matrices, there should be some rules on what is offered by the helper.

Copy link
Contributor

Choose a reason for hiding this comment

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

The standard reference for Cartan matrices (generalized) should be Kac's book Infinite Dimensional Lie Algebras I would say.

mat = matrix(

Check warning on line 44 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L43-L44

Added lines #L43 - L44 were not covered by tests
ZZ,
[
2 0 -1 0 0 0 0 0
0 2 0 -1 0 0 0 0
-1 0 2 -1 0 0 0 0
0 -1 -1 2 -1 0 0 0
0 0 0 -1 2 -1 0 0
0 0 0 0 -1 2 -1 0
0 0 0 0 0 -1 2 -1
0 0 0 0 0 0 -1 2
],
)

if rk == 6
mat = mat[1:6, 1:6]
elseif rk == 7
mat = mat[1:7, 1:7]

Check warning on line 61 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L58-L61

Added lines #L58 - L61 were not covered by tests
end
elseif fam == :F
@req rk == 4 "type Fn requires rank rk to be 4"
mat = matrix(ZZ, [2 -1 0 0; -1 2 -1 0; 0 -2 2 -1; 0 0 -1 2])
elseif fam == :G
@req rk == 2 "type Gn requires rank rk to be 2"
mat = matrix(ZZ, [2 -3; -1 2])
else
error("unknown family $fam")

Check warning on line 70 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L70

Added line #L70 was not covered by tests
end

return mat
end

function cartan_matrix(types::Tuple{Symbol,Int}...)
blocks = ZZMatrix[cartan_matrix(type...) for type in types]

Check warning on line 77 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L76-L77

Added lines #L76 - L77 were not covered by tests

return block_diagonal_matrix(blocks)

Check warning on line 79 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L79

Added line #L79 was not covered by tests
end

function cartan_to_coxeter_matrix(mat; check=true)
Copy link
Member

Choose a reason for hiding this comment

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

No tests cover this function :-(

@req !check || !is_cartan_matrix(mat) "$mat is not a (generalized) Cartan matrix"

Check warning on line 83 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L82-L83

Added lines #L82 - L83 were not covered by tests

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

Check warning on line 89 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L85-L89

Added lines #L85 - L89 were not covered by tests
end

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

Check warning on line 99 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L92-L99

Added lines #L92 - L99 were not covered by tests
end
end

Check warning on line 101 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L101

Added line #L101 was not covered by tests

return cm

Check warning on line 103 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L103

Added line #L103 was not covered by tests
end

@doc raw"""
is_cartan_matrix(mat::ZZMatrix) -> Bool
felix-roehrich marked this conversation as resolved.
Show resolved Hide resolved

Test if `mat` is a (`generalized`) Cartan matrix.
felix-roehrich marked this conversation as resolved.
Show resolved Hide resolved
"""
function is_cartan_matrix(mat::ZZMatrix; generalized::Bool=true)
n, m = size(mat)
if n != m
return false

Check warning on line 114 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L114

Added line #L114 was not covered by tests
end

if !all(mat[i, i] == 2 for i in 1:n)
return false

Check warning on line 118 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L118

Added line #L118 was not covered by tests
end

for i in 1:n
for j in (i + 1):n
if is_zero_entry(mat, i, j) && is_zero_entry(mat, j, i)
continue
end

# mat[i,j] != 0 or mat[j,i] != 0, so both entries must be < 0
if mat[i, j] >= 0 || mat[j, i] >= 0
return false

Check warning on line 129 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L129

Added line #L129 was not covered by tests
end

# if we only want a generalized Cartan matrix, we are done with this pair of entries
if generalized
continue

Check warning on line 134 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L134

Added line #L134 was not covered by tests
end

if !(mat[i, j] * mat[j, i] in 1:3)
return false

Check warning on line 138 in experimental/LieAlgebras/src/CartanMatrix.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/CartanMatrix.jl#L138

Added line #L138 was not covered by tests
end
end
end

return true
end
3 changes: 3 additions & 0 deletions experimental/LieAlgebras/src/CoxeterGroup.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
abstract type CoxeterGroup end # <: Group
felix-roehrich marked this conversation as resolved.
Show resolved Hide resolved

#function is_coxeter_matrix(M::ZZMatrix) end
Copy link
Member

Choose a reason for hiding this comment

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

Meta-remark: maybe at some point in the future rename the LieAlgebras directory to LieTheory or AlgebraicLieTheory (of course only after all big PRs have been merged, i.e., this is far from urgent)

Loading
Loading