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

Enhance inference in LieAlgebras, GSets, and MatrixGroups #4208

Merged
merged 11 commits into from
Oct 18, 2024
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 @@
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)

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

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/AbstractLieAlgebra.jl#L221-L222

Added lines #L221 - L222 were not covered by tests
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 @@
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 @@
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})

Check warning on line 107 in experimental/LieAlgebras/src/LieAlgebraIdeal.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/LieAlgebraIdeal.jl#L107

Added line #L107 was not covered by tests
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}

Check warning on line 116 in experimental/LieAlgebras/src/LieAlgebraIdeal.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/LieAlgebraIdeal.jl#L116

Added line #L116 was 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.

At first I was concerned that this change might lead to funky behaviour if v does not use 1-based indexing. But then I noticed the call matrix(coefficient_ring(I), 1, length(v), v) below, so I think that will throw a suitable error in that case. Fine by me then.

Copy link
Member Author

Choose a reason for hiding this comment

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

@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 @@
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 @@
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})

Check warning on line 105 in experimental/LieAlgebras/src/LieSubalgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/LieSubalgebra.jl#L105

Added line #L105 was not covered by tests
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 @@
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 @@
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)

Check warning on line 206 in experimental/LieAlgebras/src/LinearLieAlgebra.jl

View check run for this annotation

Codecov / codecov/patch

experimental/LieAlgebras/src/LinearLieAlgebra.jl#L205-L206

Added lines #L205 - L206 were not covered by tests
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
Loading