Skip to content

Commit

Permalink
Enhance inference in LieAlgebras, GSets, and MatrixGroups (#4208)
Browse files Browse the repository at this point in the history
Co-authored-by: Thomas Breuer <[email protected]>
  • Loading branch information
lgoettgens and ThomasBreuer authored Oct 18, 2024
1 parent 97785ad commit f55951b
Show file tree
Hide file tree
Showing 14 changed files with 120 additions and 104 deletions.
2 changes: 1 addition & 1 deletion Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4"
cohomCalg_jll = "5558cf25-a90e-53b0-b813-cadaa3ae7ade"

[compat]
AbstractAlgebra = "0.43.1"
AbstractAlgebra = "0.43.7"
AlgebraicSolving = "0.8.0"
Distributed = "1.6"
GAP = "0.12.0"
Expand Down
2 changes: 1 addition & 1 deletion docs/src/Groups/action.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ action_function(Omega::GSetByElements)
action_homomorphism(Omega::GSetByElements{T}) where T<:GAPGroup
is_conjugate(Omega::GSet, omega1, omega2)
is_conjugate_with_data(Omega::GSet, omega1, omega2)
orbit(Omega::GSetByElements{<:GAPGroup}, omega::T) where T
orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S
orbit(G::PermGroup, omega)
orbits(Omega::T) where T <: GSetByElements{TG} where TG <: GAPGroup
```
Expand Down
20 changes: 14 additions & 6 deletions experimental/LieAlgebras/src/AbstractLieAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -218,9 +218,15 @@ end
function lie_algebra(
basis::Vector{AbstractLieAlgebraElem{C}}; check::Bool=true
) where {C<:FieldElem}
parent_L = parent(basis[1])
@req all(parent(x) === parent_L for x in basis) "Elements not compatible."
R = coefficient_ring(parent_L)
@req !isempty(basis) "Basis must not be empty, or provide the Lie algebra as first argument"
return lie_algebra(parent(basis[1]), basis; check)
end

function lie_algebra(
L::AbstractLieAlgebra{C}, basis::Vector{AbstractLieAlgebraElem{C}}; check::Bool=true
) where {C<:FieldElem}
@req all(parent(x) === L for x in basis) "Elements not compatible."
R = coefficient_ring(L)
basis_matrix = if length(basis) == 0
matrix(R, 0, dim(L), C[])
else
Expand Down Expand Up @@ -370,9 +376,11 @@ function _N_matrix(rs::RootSystem, extraspecial_pair_signs::Vector{Bool})
i < j || continue
alpha_i_plus_beta_j = add!(alpha_i_plus_beta_j, alpha_i, beta_j)
is_positive_root(alpha_i_plus_beta_j) || continue
l = findfirst(
l -> is_positive_root(alpha_i_plus_beta_j - simple_root(rs, l)), 1:nsimp
)::Int
l = let alpha_i_plus_beta_j = alpha_i_plus_beta_j # avoid closure capture
findfirst(
l -> is_positive_root(alpha_i_plus_beta_j - simple_root(rs, l)), 1:nsimp
)::Int
end
l == i && continue # already extraspecial
fl, l_comp = is_positive_root_with_index(alpha_i_plus_beta_j - simple_root(rs, l))
@assert fl
Expand Down
19 changes: 9 additions & 10 deletions experimental/LieAlgebras/src/LieAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -158,21 +158,21 @@ function (L::LieAlgebra)()
end

@doc raw"""
(L::LieAlgebra{C})(v::Vector{Int}) -> LieAlgebraElem{C}
(L::LieAlgebra{C})(v::AbstractVector{Int}) -> LieAlgebraElem{C}
Return the element of `L` with coefficient vector `v`.
Fail, if `Int` cannot be coerced into the base ring of `L`.
"""
function (L::LieAlgebra)(v::Vector{Int})
function (L::LieAlgebra)(v::AbstractVector{Int})
return L(coefficient_ring(L).(v))
end

@doc raw"""
(L::LieAlgebra{C})(v::Vector{C}) -> LieAlgebraElem{C}
(L::LieAlgebra{C})(v::AbstractVector{C}) -> LieAlgebraElem{C}
Return the element of `L` with coefficient vector `v`.
"""
function (L::LieAlgebra{C})(v::Vector{C}) where {C<:FieldElem}
function (L::LieAlgebra{C})(v::AbstractVector{C}) where {C<:FieldElem}
@req length(v) == dim(L) "Length of vector does not match dimension."
mat = matrix(coefficient_ring(L), 1, length(v), v)
return elem_type(L)(L, mat)
Expand Down Expand Up @@ -291,7 +291,7 @@ end
Return the center of `L`, i.e. $\{x \in L \mid [x, L] = 0\}$
"""
function center(L::LieAlgebra)
dim(L) == 0 && return ideal(L, [])
dim(L) == 0 && return ideal(L, elem_type(L)[])

mat = zero_matrix(coefficient_ring(L), dim(L), dim(L)^2)
for (i, bi) in enumerate(basis(L))
Expand All @@ -300,9 +300,8 @@ function center(L::LieAlgebra)
end
end

c_basis = kernel(mat; side=:left)
c_dim = nrows(c_basis)
return ideal(L, [L(c_basis[i, :]) for i in 1:c_dim]; is_basis=true)
ker = kernel(mat; side=:left)
return ideal(L, L.(eachrow(ker)); is_basis=true)
end

@doc raw"""
Expand Down Expand Up @@ -548,7 +547,7 @@ function engel_subalgebra(x::LieAlgebraElem{C}) where {C<:FieldElem}
n = dim(L)
A = adjoint_matrix(x)^n
ker = kernel(A; side=:left)
basis = [L(ker[i, :]) for i in 1:nrows(ker)]
basis = L.(eachrow(ker))
L0adx = sub(L, basis; is_basis=true)
return L0adx
end
Expand Down Expand Up @@ -610,7 +609,7 @@ function _root_system_and_chevalley_basis(
for (f, k) in facs
@assert k == 1 # TODO: is this always the case?
ker = kernel((f^k)(A); side=:left)
basis = [B_j(ker[i, :]) for i in 1:nrows(ker)]
basis = B_j.(eachrow(ker))
push!(B_new, sub(L, basis; is_basis=true))
end
end
Expand Down
10 changes: 5 additions & 5 deletions experimental/LieAlgebras/src/LieAlgebraIdeal.jl
Original file line number Diff line number Diff line change
Expand Up @@ -99,21 +99,21 @@ function (I::LieAlgebraIdeal)()
end

@doc raw"""
(I::LieAlgebraIdeal{C})(v::Vector{Int}) -> LieAlgebraElem{C}
(I::LieAlgebraIdeal{C})(v::AbstractVector{Int}) -> LieAlgebraElem{C}
Return the element of `I` with coefficient vector `v`.
Fail, if `Int` cannot be coerced into the base ring of `I`.
"""
function (I::LieAlgebraIdeal)(v::Vector{Int})
function (I::LieAlgebraIdeal)(v::AbstractVector{Int})
return I(coefficient_ring(I).(v))
end

@doc raw"""
(I::LieAlgebraIdeal{C})(v::Vector{C}) -> LieAlgebraElem{C}
(I::LieAlgebraIdeal{C})(v::AbstractVector{C}) -> LieAlgebraElem{C}
Return the element of `I` with coefficient vector `v`.
"""
function (I::LieAlgebraIdeal{C})(v::Vector{C}) where {C<:FieldElem}
function (I::LieAlgebraIdeal{C})(v::AbstractVector{C}) where {C<:FieldElem}
@req length(v) == dim(I) "Length of vector does not match dimension."
mat = matrix(coefficient_ring(I), 1, length(v), v)
L = base_lie_algebra(I)
Expand Down Expand Up @@ -268,8 +268,8 @@ Return `I` as a Lie algebra `LI`, together with an embedding `LI -> L`,
where `L` is the Lie algebra where `I` lives in.
"""
function lie_algebra(I::LieAlgebraIdeal)
LI = lie_algebra(basis(I))
L = base_lie_algebra(I)
LI = lie_algebra(L, basis(I))
emb = hom(LI, L, basis(I); check=false)
return LI, emb
end
Expand Down
8 changes: 4 additions & 4 deletions experimental/LieAlgebras/src/LieAlgebraModule.jl
Original file line number Diff line number Diff line change
Expand Up @@ -252,21 +252,21 @@ function (V::LieAlgebraModule)()
end

@doc raw"""
(V::LieAlgebraModule{C})(v::Vector{Int}) -> LieAlgebraModuleElem{C}
(V::LieAlgebraModule{C})(v::AbstractVector{Int}) -> LieAlgebraModuleElem{C}
Return the element of `V` with coefficient vector `v`.
Fails, if `Int` cannot be coerced into the base ring of `L`.
"""
function (V::LieAlgebraModule)(v::Vector{Int})
function (V::LieAlgebraModule)(v::AbstractVector{Int})
return V(coefficient_ring(V).(v))
end

@doc raw"""
(V::LieAlgebraModule{C})(v::Vector{C}) -> LieAlgebraModuleElem{C}
(V::LieAlgebraModule{C})(v::AbstractVector{C}) -> LieAlgebraModuleElem{C}
Return the element of `V` with coefficient vector `v`.
"""
function (V::LieAlgebraModule{C})(v::Vector{C}) where {C<:FieldElem}
function (V::LieAlgebraModule{C})(v::AbstractVector{C}) where {C<:FieldElem}
@req length(v) == dim(V) "Length of vector does not match dimension."
mat = matrix(coefficient_ring(V), 1, length(v), v)
return elem_type(V)(V, mat)
Expand Down
10 changes: 5 additions & 5 deletions experimental/LieAlgebras/src/LieSubalgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -97,21 +97,21 @@ function (S::LieSubalgebra)()
end

@doc raw"""
(S::LieSubalgebra{C})(v::Vector{Int}) -> LieAlgebraElem{C}
(S::LieSubalgebra{C})(v::AbstractVector{Int}) -> LieAlgebraElem{C}
Return the element of `S` with coefficient vector `v`.
Fail, if `Int` cannot be coerced into the base ring of `S`.
"""
function (S::LieSubalgebra)(v::Vector{Int})
function (S::LieSubalgebra)(v::AbstractVector{Int})
return S(coefficient_ring(S).(v))
end

@doc raw"""
(S::LieSubalgebra{C})(v::Vector{C}) -> LieAlgebraElem{C}
(S::LieSubalgebra{C})(v::AbstractVector{C}) -> LieAlgebraElem{C}
Return the element of `S` with coefficient vector `v`.
"""
function (S::LieSubalgebra{C})(v::Vector{C}) where {C<:FieldElem}
function (S::LieSubalgebra{C})(v::AbstractVector{C}) where {C<:FieldElem}
@req length(v) == dim(S) "Length of vector does not match dimension."
mat = matrix(coefficient_ring(S), 1, length(v), v)
L = base_lie_algebra(S)
Expand Down Expand Up @@ -299,8 +299,8 @@ Return `S` as a Lie algebra `LS`, together with an embedding `LS -> L`,
where `L` is the Lie algebra where `S` lives in.
"""
function lie_algebra(S::LieSubalgebra)
LS = lie_algebra(basis(S))
L = base_lie_algebra(S)
LS = lie_algebra(L, basis(S))
emb = hom(LS, L, basis(S); check=false)
return LS, emb
end
Expand Down
15 changes: 10 additions & 5 deletions experimental/LieAlgebras/src/LinearLieAlgebra.jl
Original file line number Diff line number Diff line change
Expand Up @@ -202,12 +202,17 @@ end
function lie_algebra(
basis::Vector{LinearLieAlgebraElem{C}}; check::Bool=true
) where {C<:FieldElem}
parent_L = parent(basis[1])
@req all(parent(x) === parent_L for x in basis) "Elements not compatible."
R = coefficient_ring(parent_L)
n = parent_L.n
@req !isempty(basis) "Basis must not be empty, or provide the Lie algebra as first argument"
return lie_algebra(parent(basis[1]), basis; check)
end

function lie_algebra(
L::LinearLieAlgebra{C}, basis::Vector{LinearLieAlgebraElem{C}}; check::Bool=true
) where {C<:FieldElem}
@req all(parent(x) === L for x in basis) "Elements not compatible."
R = coefficient_ring(L)
s = map(AbstractAlgebra.obj_to_string_wrt_times, basis)
return lie_algebra(R, n, matrix_repr.(basis), s; check)
return lie_algebra(R, L.n, matrix_repr.(basis), s; check)
end

@doc raw"""
Expand Down
4 changes: 2 additions & 2 deletions experimental/LieAlgebras/src/RootSystem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1238,8 +1238,8 @@ function dominant_weights(T::Type, R::RootSystem, hw::Vector{<:IntegerUnion})
end

function dominant_weights(
T::Type{<:Vector{<:IntegerUnion}}, R::RootSystem, hw::WeightLatticeElem
)
::Type{T}, R::RootSystem, hw::WeightLatticeElem
) where {T<:Vector{<:IntegerUnion}}
weights = dominant_weights(WeightLatticeElem, R, hw)
return [T(_vec(coefficients(w))) for w in weights]
end
Expand Down
14 changes: 7 additions & 7 deletions experimental/LieAlgebras/src/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -295,7 +295,7 @@ end
L::LieAlgebra{C}, gens::Vector{LieT}; is_basis::Bool=false
) where {C<:FieldElem,LieT<:LieAlgebraElem{C}}
@req all(g -> parent(g) === L, gens) "Parent mismatch."
L::parent_type(LieT)
@req L isa parent_type(LieT) "Parent type mismatch."
if is_basis
basis_elems = gens
basis_matrix = if length(gens) == 0
Expand All @@ -311,14 +311,14 @@ end
while !isempty(left)
g = pop!(left)
can_solve(basis_matrix, _matrix(g); side=:left) && continue
for i in 1:nrows(basis_matrix)
push!(left, g * L(basis_matrix[i, :]))
for row in eachrow(basis_matrix)
push!(left, g * L(row))
end
basis_matrix = vcat(basis_matrix, _matrix(g))
rank = rref!(basis_matrix)
basis_matrix = basis_matrix[1:rank, :]
@assert rank == nrows(basis_matrix) # otherwise the continue above would've triggered
end
basis_elems = [L(basis_matrix[i, :]) for i in 1:nrows(basis_matrix)]
basis_elems = L.(eachrow(basis_matrix))
return new{C,LieT}(L, gens, basis_elems, basis_matrix)
end
end
Expand Down Expand Up @@ -364,9 +364,9 @@ end
end
basis_matrix = vcat(basis_matrix, _matrix(g))
rank = rref!(basis_matrix)
basis_matrix = basis_matrix[1:rank, :]
@assert rank == nrows(basis_matrix) # otherwise the continue above would've triggered
end
basis_elems = [L(basis_matrix[i, :]) for i in 1:nrows(basis_matrix)]
basis_elems = L.(eachrow(basis_matrix))
return new{C,LieT}(L, gens, basis_elems, basis_matrix)
end
end
Expand Down
2 changes: 1 addition & 1 deletion src/GAP/iso_oscar_gap.jl
Original file line number Diff line number Diff line change
Expand Up @@ -591,7 +591,7 @@ function AbstractAlgebra.map_entries(f::Map{T, GapObj}, a::MatrixElem{S}) where
@assert base_ring(a) === domain(f)
rows = Vector{GapObj}(undef, nrows(a))
for i in 1:nrows(a)
rows[i] = GapObj([f(a[i, j]) for j in 1:ncols(a)])
rows[i] = GapObj([f(a[i, j])::GAP.Obj for j in 1:ncols(a)])
end
return GAPWrap.ImmutableMatrix(codomain(f), GapObj(rows), true)
end
Expand Down
2 changes: 2 additions & 0 deletions src/GAP/wrappers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -107,6 +107,8 @@ GAP.@wrap GeneratorsOfGroup(x::GapObj)::GapObj
GAP.@wrap GetFusionMap(x::GapObj, y::GapObj)::GapObj
GAP.@wrap GF(x::Any)::GapObj
GAP.@wrap GF(x::Any, y::Any)::GapObj
GAP.@wrap Group(x::GapObj)::GapObj
GAP.@wrap Group(x::GapObj, y::GapObj)::GapObj
GAP.@wrap GroupHomomorphismByFunction(x1, x2, x3)::GapObj
GAP.@wrap GroupHomomorphismByFunction(x1, x2, x3, x4)::GapObj
GAP.@wrap GroupHomomorphismByFunction(x1, x2, x3, x4, x5)::GapObj
Expand Down
7 changes: 4 additions & 3 deletions src/Groups/gsets.jl
Original file line number Diff line number Diff line change
Expand Up @@ -345,15 +345,15 @@ julia> length(orbit(Omega, 1))
4
```
"""
function orbit(Omega::GSetByElements{<:GAPGroup}, omega::T) where T
function orbit(Omega::GSetByElements{<:GAPGroup, S}, omega::S) where S
G = acting_group(Omega)
acts = GapObj(gens(G))
gfun = GapObj(action_function(Omega))

# The following works only because GAP does not check
# whether the given (dummy) group 'GapObj(G)' fits to the given generators,
# or whether the elements of 'acts' are group elements.
orb = Vector{T}(GAP.Globals.Orbit(GapObj(G), omega, acts, acts, gfun)::GapObj)
orb = Vector{S}(GAP.Globals.Orbit(GapObj(G), omega, acts, acts, gfun)::GapObj)

res = as_gset(acting_group(Omega), action_function(Omega), orb)
# We know that this G-set is transitive.
Expand Down Expand Up @@ -413,7 +413,8 @@ julia> map(collect, orbs)
"""
@attr Vector{GSetByElements{T,S}} function orbits(Omega::GSetByElements{T,S}) where {T <: Union{GAPGroup, FinGenAbGroup},S}
orbs = GSetByElements{T,S}[]
for p in Omega.seeds
for p_ in Omega.seeds
p = p_::S
if all(o -> !(p in o), orbs)
push!(orbs, orbit(Omega, p))
end
Expand Down
Loading

0 comments on commit f55951b

Please sign in to comment.