PropertyT.jl/test/Chevalley.jl

310 lines
11 KiB
Julia
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

countmap(v) = countmap(identity, v)
function countmap(f, v)
counts = Dict{eltype(f(first(v))),Int}()
for x in v
fx = f(x)
counts[fx] = get!(counts, fx, 0) + 1
end
return counts
end
@testset "Chevalley" begin
@testset "classify_root_system" begin
α = PropertyT.Roots.Root([1, -1, 0])
β = PropertyT.Roots.Root([0, 1, -1])
γ = PropertyT.Roots.Root([2, 0, 0])
@test PropertyT.Roots.classify_root_system(α, β, (false, false)) == :A₂
@test PropertyT.Roots.classify_root_system(α, γ, (false, true)) == :C₂
@test PropertyT.Roots.classify_root_system(β, γ, (false, true)) ==
Symbol("A₁×C₁")
end
@testset "Exceptional root systems" begin
@testset "F4" begin
F4 =
let Σ = PermutationGroups.PermGroup(
perm"(1,2,3,4)",
perm"(1,2)",
)
long = let x = (1, 1, 0, 0) .// 1
PropertyT.Roots.Root.(
union(
(x^g for g in Σ),
((x .* (-1, 1, 1, 1))^g for g in Σ),
((-1 .* x)^g for g in Σ),
),
)
end
short = let x = (1, 0, 0, 0) .// 1
PropertyT.Roots.Root.(
union((x^g for g in Σ), ((-1 .* x)^g for g in Σ))
)
end
signs = collect(Iterators.product(fill([-1, +1], 4)...))
halfs = let x = (1, 1, 1, 1) .// 2
PropertyT.Roots.Root.(union(x .* sgn for sgn in signs))
end
union(long, short, halfs)
end
@test length(F4) == 48
a = F4[1]
@test isapprox(PropertyT.Roots.₂length(a), sqrt(2))
b = F4[6]
@test isapprox(PropertyT.Roots.₂length(b), sqrt(2))
c = a + b
@test isapprox(PropertyT.Roots.₂length(c), 2.0)
@test PropertyT.Roots.classify_root_system(b, c, (false, true)) ==
:C₂
long =
F4[findfirst(r -> PropertyT.Roots.₂length(r) == sqrt(2), F4)]
short = F4[findfirst(r -> PropertyT.Roots.₂length(r) == 1.0, F4)]
subtypes = Set([:C₂, :A₂, Symbol("A₁×C₁")])
let Ω = F4, α = long
counts = countmap([
PropertyT.Roots.classify_sub_root_system(Ω, α, γ) for
γ in Ω if !PropertyT.Roots.isproportional(α, γ)
])
@test Set(keys(counts)) == subtypes
d, r = divrem(counts[:C₂], 6)
@test r == 0 && d == 3
d, r = divrem(counts[:A₂], 4)
@test r == 0 && d == 4
end
let Ω = F4, α = short
counts = countmap([
PropertyT.Roots.classify_sub_root_system(Ω, α, γ) for
γ in Ω if !PropertyT.Roots.isproportional(α, γ)
])
@test Set(keys(counts)) == subtypes
d, r = divrem(counts[:C₂], 6)
@test r == 0 && d == 3
d, r = divrem(counts[:A₂], 4)
@test r == 0 && d == 4
end
end
@testset "E6-7-8 exceptional root systems" begin
E8 =
let Σ = PermutationGroups.PermGroup(
perm"(1,2,3,4,5,6,7,8)",
perm"(1,2)",
)
long = let x = (1, 1, 0, 0, 0, 0, 0, 0) .// 1
PropertyT.Roots.Root.(
union(
(x^g for g in Σ),
((x .* (-1, 1, 1, 1, 1, 1, 1, 1))^g for g in Σ),
((-1 .* x)^g for g in Σ),
),
)
end
signs = collect(
p for
p in Iterators.product(fill([-1, +1], 8)...) if
iseven(count(==(-1), p))
)
halfs = let x = (1, 1, 1, 1, 1, 1, 1, 1) .// 2
rts = unique(
PropertyT.Roots.Root(x .* sgn) for sgn in signs
)
end
union(long, halfs)
end
subtypes = Set([:A₂, Symbol("A₁×A₁")])
@testset "E8" begin
@test length(E8) == 240
@test all(r -> PropertyT.Roots.₂length(r) sqrt(2), E8)
let Ω = E8, α = first(Ω)
counts = countmap([
PropertyT.Roots.classify_sub_root_system(Ω, α, γ)
for γ in Ω if !PropertyT.Roots.isproportional(α, γ)
])
@test Set(keys(counts)) == subtypes
d, r = divrem(counts[:A₂], 4)
@test r == 0 && d == 28
end
end
@testset "E7" begin
E7 = filter(r -> iszero(sum(r.coord)), E8)
@test length(E7) == 126
let Ω = E7, α = first(Ω)
counts = countmap([
PropertyT.Roots.classify_sub_root_system(Ω, α, γ)
for γ in Ω if !PropertyT.Roots.isproportional(α, γ)
])
@test Set(keys(counts)) == subtypes
d, r = divrem(counts[:A₂], 4)
@test r == 0 && d == 16
end
end
@testset "E6" begin
E6 = filter(
r -> r.coord[end] == r.coord[end-1] == r.coord[end-2],
E8,
)
@test length(E6) == 72
let Ω = E6, α = first(Ω)
counts = countmap([
PropertyT.Roots.classify_sub_root_system(Ω, α, γ)
for γ in Ω if !PropertyT.Roots.isproportional(α, γ)
])
@test Set(keys(counts)) == subtypes
d, r = divrem(counts[:A₂], 4)
@info d, r
@test r == 0 && d == 10
end
end
end
end
@testset "Levels in Sp2n" begin
function level(rootsystem, level::Integer)
1 level 4 || throw("level is implemented only for i ∈{1,2,3,4}")
level == 1 && return PropertyT.Adj(rootsystem, :C₁) # always positive
level == 2 && return PropertyT.Adj(rootsystem, :A₁) +
PropertyT.Adj(rootsystem, Symbol("C₁×C₁")) +
PropertyT.Adj(rootsystem, :C₂) # C₂ is not positive
level == 3 && return PropertyT.Adj(rootsystem, :A₂) +
PropertyT.Adj(rootsystem, Symbol("A₁×C₁"))
level == 4 && return PropertyT.Adj(rootsystem, Symbol("A₁×A₁")) # positive
end
n = 5
G = MatrixGroups.SymplecticGroup{2n}(Int8)
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 1)
Weyl = let N = n
P = PermGroup(perm"(1,2)", Perm(circshift(1:N, -1)))
Groups.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P)
end
act = PropertyT.action_by_conjugation(G, Weyl)
function ^ᵃ(x, w::Groups.Constructions.WreathProductElement)
return SymbolicWedderburn.action(act, w, x)
end
Sₙ = S
Δsₙ = PropertyT.laplacians(
RG,
Sₙ,
x -> (gx = PropertyT.grading(x); Set([gx, -gx])),
)
function natural_embedding(i, Sp2m, Sp2n)
_dim(::MatrixGroups.ElementarySymplectic{N}) where {N} = N
n = _dim(first(alphabet(Sp2n))) ÷ 2
m = _dim(first(alphabet(Sp2m))) ÷ 2
l = alphabet(Sp2m)[i]
i, j = if l.symbol === :A
l.i, l.j
elseif l.symbol === :B
ifelse(l.i m, (l.i, l.j - m + n), (l.i - m + n, l.j))
else
throw("unknown type: $(l.symbol)")
end
image_of_l =
MatrixGroups.ElementarySymplectic{2n}(l.symbol, i, j, l.val)
return Groups.word_type(Sp2n)([alphabet(Sp2n)[image_of_l]])
end
@testset "Sp4 ↪ Sp12" begin
m = 2
Sₘ = let m = m, Sp2n = G
Sp2m = MatrixGroups.SymplecticGroup{2m}(Int8)
h = Groups.Homomorphism(
natural_embedding,
Sp2m,
Sp2n;
check = false,
)
S = h.(gens(Sp2m))
S = union!(S, inv.(S))
end
Δsₘ = PropertyT.laplacians(
RG,
Sₘ,
x -> (gx = PropertyT.grading(x); Set([gx, -gx])),
)
function k(n, m, i)
return 2^n * factorial(m) * factorial(n - i) ÷ factorial(m - i)
end
@testset "Level $i" for i in 1:4
Levᵢᵐ = level(Δsₘ, i)
Levᵢⁿ = level(Δsₙ, i)
if 1 i 2
@test !iszero(Levᵢᵐ)
@time Σ_W_Levᵢᵐ = sum(Levᵢᵐ^ᵃw for w in Weyl)
@test isinteger(Σ_W_Levᵢᵐ[one(G)] / Levᵢⁿ[one(G)])
@test Σ_W_Levᵢᵐ[one(G)] / Levᵢⁿ[one(G)] == k(n, m, i)
@test Σ_W_Levᵢᵐ == k(n, m, i) * Levᵢⁿ
else
@test iszero(Levᵢᵐ)
@test !iszero(Levᵢⁿ)
end
end
end
@testset "Sp8 ↪ Sp12" begin
m = 4
Sₘ = let m = m, Sp2n = G
Sp2m = MatrixGroups.SymplecticGroup{2m}(Int8)
h = Groups.Homomorphism(
natural_embedding,
Sp2m,
Sp2n;
check = false,
)
S = h.(gens(Sp2m))
S = union!(S, inv.(S))
end
Δsₘ = PropertyT.laplacians(
RG,
Sₘ,
x -> (gx = PropertyT.grading(x); Set([gx, -gx])),
)
function k(n, m, i)
return 2^n * factorial(m) * factorial(n - i) ÷ factorial(m - i)
end
@testset "Level $i" for i in 1:4
Levᵢᵐ = level(Δsₘ, i)
Levᵢⁿ = level(Δsₙ, i)
@test !iszero(Levᵢᵐ)
@time Σ_W_Levᵢᵐ = sum(Levᵢᵐ^ᵃw for w in Weyl)
@test isinteger(Σ_W_Levᵢᵐ[one(G)] / Levᵢⁿ[one(G)])
@test Σ_W_Levᵢᵐ[one(G)] / Levᵢⁿ[one(G)] == k(n, m, i)
@test Σ_W_Levᵢᵐ == k(n, m, i) * Levᵢⁿ
end
end
end
end