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

fix: group algebras of additive groups with sparse rep #1685

Merged
merged 9 commits into from
Nov 19, 2024
57 changes: 42 additions & 15 deletions src/AlgAss/AlgGrp.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

base_ring_type(::Type{GroupAlgebra{T, S, R}}) where {T, S, R} = parent_type(T)

Generic.dim(A::GroupAlgebra) = size(multiplication_table(A, copy = false), 1)
Generic.dim(A::GroupAlgebra) = order(Int, group(A))

elem_type(::Type{GroupAlgebra{T, S, R}}) where {T, S, R} = GroupAlgebraElem{T, GroupAlgebra{T, S, R}}

Expand Down Expand Up @@ -55,11 +55,15 @@
# get the underyling group operation, I wish this was part of the group interface

_op(G::AbstractAlgebra.AdditiveGroup) = +

_op(G::Group) = *

_op(A::GroupAlgebra) = _op(group(A))

_is_identity_elem(x::AbstractAlgebra.AdditiveGroupElem) = iszero(x)
_is_identity_elem(x::GroupElem) = isone(x)

_identity_elem(G::AbstractAlgebra.AdditiveGroup) = zero(G)
_identity_elem(G::Group) = one(G)

################################################################################
#
# Construction
Expand All @@ -81,12 +85,12 @@
over rational field
```
"""
group_algebra(K::Ring, G; cached = true) = _group_algebra(K, G; op = *, cached)
group_algebra(K::Ring, G; cached = true) = _group_algebra(K, G; cached)

# one additional level of indirection to hide the non-user facing options
# `op` and `sparse`.
function _group_algebra(K::Ring, G; op = *, sparse = _use_sparse_group_algebra(G), cached::Bool = true)
A = GroupAlgebra(K, G; op = _op(G) , sparse = sparse, cached = cached)
function _group_algebra(K::Ring, G; op = _op(G), sparse = _use_sparse_group_algebra(G), cached::Bool = true)
A = GroupAlgebra(K, G; op = op , sparse = sparse, cached = cached)
if !(K isa Field)
return A
end
Expand Down Expand Up @@ -128,16 +132,26 @@
if is_commutative_known(A)
return A.is_commutative == 1
end
for i in 1:dim(A)
for j in 1:dim(A)
if multiplication_table(A, copy = false)[i, j] != multiplication_table(A, copy = false)[j, i]
A.is_commutative = 2
return false
if _is_sparse(A)
if is_abelian(group(A))
A.is_commutative = 1
return true
else
A.is_commutative = 2
return false

Check warning on line 141 in src/AlgAss/AlgGrp.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAss/AlgGrp.jl#L140-L141

Added lines #L140 - L141 were not covered by tests
end
else
for i in 1:dim(A)
for j in 1:dim(A)
if multiplication_table(A, copy = false)[i, j] != multiplication_table(A, copy = false)[j, i]
A.is_commutative = 2
return false
end
end
end
A.is_commutative = 1
return true
end
A.is_commutative = 1
return true
end

################################################################################
Expand All @@ -157,9 +171,21 @@

function show(io::IO, A::GroupAlgebra)
if is_terse(io)
print(io, "Group algebra of dimension ", dim(A), " over ", base_ring(A))
print(io, "Group algebra of ")
if is_finite(group(A))
print(io, "dimension ", order(group(A)))

Check warning on line 176 in src/AlgAss/AlgGrp.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAss/AlgGrp.jl#L174-L176

Added lines #L174 - L176 were not covered by tests
else
print(io, "infinite dimension ")

Check warning on line 178 in src/AlgAss/AlgGrp.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAss/AlgGrp.jl#L178

Added line #L178 was not covered by tests
end
print(io, " over ", base_ring(A))

Check warning on line 180 in src/AlgAss/AlgGrp.jl

View check run for this annotation

Codecov / codecov/patch

src/AlgAss/AlgGrp.jl#L180

Added line #L180 was not covered by tests
else
print(io, "Group algebra of group of order ", order(group(A)), " over ")
print(io, "Group algebra of group ")
if is_finite(group(A))
print(io, "of order ", order(group(A)))
else
print(io, "of infinite order ")
end
print(io, "over ")
print(terse(io), base_ring(A))
end
end
Expand Down Expand Up @@ -236,6 +262,7 @@
################################################################################

function StructureConstantAlgebra(A::GroupAlgebra{T, S, R}) where {T, S, R}
@req _is_dense(A) "StructureConstantAlgebra only works for dense group algebras"
K = base_ring(A)
mult = Array{T, 3}(undef, dim(A), dim(A), dim(A))
B = basis(A)
Expand Down
8 changes: 6 additions & 2 deletions src/AlgAss/Elem.jl
Original file line number Diff line number Diff line change
Expand Up @@ -147,8 +147,12 @@ end
################################################################################

function -(a::AbstractAssociativeAlgebraElem{T}) where {T}
v = T[ -coefficients(a, copy = false)[i] for i = 1:dim(parent(a)) ]
return parent(a)(v)
if _is_sparse(a)
return parent(a)(-a.coeffs_sparse)
else
v = T[ -coefficients(a, copy = false)[i] for i = 1:dim(parent(a)) ]
return parent(a)(v)
end
end

################################################################################
Expand Down
8 changes: 2 additions & 6 deletions src/AlgAss/Types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -186,11 +186,7 @@ end
end

if A.sparse
if G isa FinGenAbGroup
el = zero(G)
else
el = one(G)
end
el = _identity_elem(G)
A.group_to_base[el] = 1
A.base_to_group[1] = el
A.sparse_one = sparse_row(K, [1], [one(K)])
Expand All @@ -199,7 +195,7 @@ end
A.mult_table = zeros(Int, d, d)
i = 2
for g in collect(G)
if isone(g)
if _is_identity_elem(g)
A.group_to_base[deepcopy(g)] = 1
A.base_to_group[1] = deepcopy(g)
continue
Expand Down
39 changes: 38 additions & 1 deletion test/AlgAss/AlgGrp.jl
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
@testset "Group algebras" begin
G = small_group(8, 4)
A = GroupAlgebra(QQ, G)

@test sprint(show, MIME"text/plain"(), A) isa String
@test sprint(show, A) isa String
@testset "Regular matrix algebra" begin
B, BtoA = Hecke.regular_matrix_algebra(A)

Expand Down Expand Up @@ -90,6 +91,10 @@
let
G = SymmetricGroup(10)
QG = Hecke._group_algebra(QQ, G; sparse = true, cached = false)
@test dim(QG) == factorial(10)
#@test !is_commutative(QG) # needs https://github.com/Nemocas/AbstractAlgebra.jl/pull/1907
@test sprint(show, MIME"text/plain"(), QG) isa String
@test sprint(show, QG) isa String
for i in 1:10
a = rand(G)
b = rand(G)
Expand All @@ -102,6 +107,38 @@
@test aa * bb == cc
@test bb * aa == dd
@test (aa + bb)^2 == QG(a)^2 + cc + dd + QG(b)^2
@test aa - bb == aa + (-bb)
end
end

let
G = abelian_group([2, 3, 5000])
QG = Hecke._group_algebra(QQ, G; sparse = true, cached = false)
@test dim(QG) == 2 * 3 * 5000
@test is_commutative(QG)
@test sprint(show, MIME"text/plain"(), QG) isa String
@test sprint(show, QG) isa String
for i in 1:10
a = rand(G)
b = rand(G)
c = a + b
d = b + a
aa = QG(a)
bb = QG(b)
cc = QG(c)
dd = QG(d)
@test aa * bb == cc
@test bb * aa == dd
@test (aa + bb)^2 == QG(a)^2 + cc + dd + QG(b)^2
@test aa - bb == aa + (-bb)
end
end

let
G = abelian_group([2, 3, 0])
QG = Hecke._group_algebra(QQ, G; sparse = true, cached = false)
@test is_commutative(QG)
@test sprint(show, MIME"text/plain"(), QG) isa String
@test sprint(show, QG) isa String
end
end
Loading