use GroupOrNCRing[Elem]

in AbstractAlgebra Rings are not groups
This commit is contained in:
kalmarek 2019-07-01 01:05:48 +02:00
parent fbd7b940e9
commit af1ca3e6e7
No known key found for this signature in database
GPG Key ID: 8BF1A3855328FC15
2 changed files with 75 additions and 58 deletions

View File

@ -1,7 +1,7 @@
module GroupRings module GroupRings
using AbstractAlgebra using AbstractAlgebra
import AbstractAlgebra: Group, GroupElem, Ring, RingElem, parent, elem_type, parent_type, addeq!, mul! import AbstractAlgebra: Group, NCRing, NCRingElem, parent, elem_type, parent_type, addeq!, mul!
using SparseArrays using SparseArrays
using LinearAlgebra using LinearAlgebra
@ -9,13 +9,16 @@ using Markdown
import Base: convert, show, hash, ==, +, -, *, ^, //, /, length, getindex, setindex!, eltype, one, zero import Base: convert, show, hash, ==, +, -, *, ^, //, /, length, getindex, setindex!, eltype, one, zero
GroupOrNCRing = Union{AbstractAlgebra.Group, AbstractAlgebra.NCRing}
GroupOrNCRingElem = Union{AbstractAlgebra.GroupElem, AbstractAlgebra.NCRingElem}
############################################################################### ###############################################################################
# #
# GroupRings / GroupRingsElem # GroupRings / GroupRingsElem
# #
############################################################################### ###############################################################################
mutable struct GroupRing{Gr<:Group, T<:GroupElem} <: Ring mutable struct GroupRing{Gr<:GroupOrNCRing, T<:GroupOrNCRingElem} <: NCRing
group::Gr group::Gr
basis::Vector{T} basis::Vector{T}
basis_dict::Dict{T, Int} basis_dict::Dict{T, Int}
@ -39,7 +42,7 @@ mutable struct GroupRing{Gr<:Group, T<:GroupElem} <: Ring
end end
end end
mutable struct GroupRingElem{T, A<:AbstractVector, GR<:GroupRing} <: RingElem mutable struct GroupRingElem{T, A<:AbstractVector, GR<:GroupRing} <: NCRingElem
coeffs::A coeffs::A
parent::GR parent::GR
@ -131,13 +134,13 @@ function (RG::GroupRing{<:AbstractAlgebra.NCRing})(i::Int, T::Type=Int)
return elt return elt
end end
function (RG::GroupRing)(g::GroupElem, T::Type=Int) function (RG::GroupRing)(g::GroupOrNCRingElem, T::Type=Int)
result = RG(T) result = RG(T)
result[RG.group(g)] = one(T) result[RG.group(g)] = one(T)
return result return result
end end
function (RG::GroupRing{Gr,T})(V::Vector{T}, S::Type=Int) where {Gr<:Group, T<:GroupElem} function (RG::GroupRing{Gr,T})(V::Vector{T}, S::Type=Int) where {Gr, T}
res = RG(S) res = RG(S)
for g in V for g in V
res[g] += one(S) res[g] += one(S)
@ -181,7 +184,7 @@ function getindex(X::GroupRingElem, n::Int)
return X.coeffs[n] return X.coeffs[n]
end end
function getindex(X::GroupRingElem, g::GroupElem) function getindex(X::GroupRingElem, g::GroupOrNCRingElem)
return X.coeffs[parent(X).basis_dict[g]] return X.coeffs[parent(X).basis_dict[g]]
end end
@ -189,7 +192,7 @@ function setindex!(X::GroupRingElem, value, n::Int)
X.coeffs[n] = value X.coeffs[n] = value
end end
function setindex!(X::GroupRingElem, value, g::GroupElem) function setindex!(X::GroupRingElem, value, g::GroupOrNCRingElem)
RG = parent(X) RG = parent(X)
if !(g in keys(RG.basis_dict)) if !(g in keys(RG.basis_dict))
g = (RG.group)(g) g = (RG.group)(g)
@ -525,8 +528,8 @@ end
reverse_dict(iter) = reverse_dict(Int, iter) reverse_dict(iter) = reverse_dict(Int, iter)
function create_pm(basis::Vector{T}, basis_dict::Dict{T, Int}, function create_pm(basis::AbstractVector{T}, basis_dict::Dict{T, Int},
limit::Int=length(basis); twisted::Bool=false, check=true) where {T<:GroupElem} limit::Int=length(basis); twisted::Bool=false, check=true) where T
product_matrix = zeros(Int, (limit,limit)) product_matrix = zeros(Int, (limit,limit))
Threads.@threads for i in 1:limit Threads.@threads for i in 1:limit
x = basis[i] x = basis[i]
@ -543,7 +546,7 @@ function create_pm(basis::Vector{T}, basis_dict::Dict{T, Int},
return product_matrix return product_matrix
end end
create_pm(b::Vector{T}) where {T<:GroupElem} = create_pm(b, reverse_dict(b)) create_pm(b::AbstractVector{<:GroupOrNCRingElem}) = create_pm(b, reverse_dict(b))
function check_pm(product_matrix, basis, twisted=false) function check_pm(product_matrix, basis, twisted=false)
idx = findfirst(product_matrix' .== 0) idx = findfirst(product_matrix' .== 0)

View File

@ -9,7 +9,7 @@ using SparseArrays
@testset "Constructors: PermutationGroup" begin @testset "Constructors: PermutationGroup" begin
G = PermutationGroup(3) G = PermutationGroup(3)
@test isa(GroupRing(G), AbstractAlgebra.Ring) @test isa(GroupRing(G), AbstractAlgebra.NCRing)
@test isa(GroupRing(G), GroupRing) @test isa(GroupRing(G), GroupRing)
RG = GroupRing(G) RG = GroupRing(G)
@ -115,6 +115,20 @@ using SparseArrays
@test string(-a) == " - 2() - 1(1,2,3)" @test string(-a) == " - 2() - 1(1,2,3)"
@test length(a) == 2 @test length(a) == 2
@testset "RSL(3,Z)" begin
N = 3
halfradius = 2
M = MatrixAlgebra(zz, N)
E(M, i,j) = (e_ij = one(M); e_ij[i,j] = 1; e_ij)
S = [E(M, i,j) for i in 1:N for j in 1:N if i≠j]
S = unique([S; inv.(S)])
E_R, sizes = Groups.generate_balls(S, radius=2*halfradius)
E_rdict = GroupRings.reverse_dict(E_R)
pm = GroupRings.create_pm(E_R, E_rdict, sizes[halfradius]; twisted=true);
@test GroupRing(M, E_R, E_rdict, pm) isa GroupRing
end
end end
@testset "Arithmetic" begin @testset "Arithmetic" begin
@ -153,7 +167,7 @@ using SparseArrays
@test isa(b//4, GroupRingElem) @test isa(b//4, GroupRingElem)
@test eltype(b//4) == Rational{Int} @test eltype(b//4) == Rational{Int}
@test isa(b//big(4), RingElem) @test isa(b//big(4), NCRingElem)
@test eltype(b//(big(4)//1)) == Rational{BigInt} @test eltype(b//(big(4)//1)) == Rational{BigInt}
@test isa(a//1, GroupRingElem) @test isa(a//1, GroupRingElem)
@ -208,18 +222,18 @@ using SparseArrays
@test supp(z) == parent(z).basis @test supp(z) == parent(z).basis
@test supp(RG(1) + RG(perm"(2,3)")) == [G(), perm"(2,3)"] @test supp(RG(1) + RG(perm"(2,3)")) == [G(), perm"(2,3)"]
@test supp(a) == [perm"(3)", perm"(2,3)", perm"(1,2,3)"] @test supp(a) == [perm"(3)", perm"(2,3)", perm"(1,2,3)"]
end end
@testset "HPC multiplicative operations" begin @testset "HPC multiplicative operations" begin
G = PermutationGroup(5) G = PermutationGroup(5)
RG = GroupRing(G, cachedmul=true) RG = GroupRing(G, cachedmul=true)
RG2 = GroupRing(G, cachedmul=false) RG2 = GroupRing(G, cachedmul=false)
Z = RG() Z = RG()
W = RG() W = RG()
for g in [rand(G) for _ in 1:30] for g in [rand(G) for _ in 1:30]
X = RG(g) X = RG(g)
Y = -RG(inv(g)) Y = -RG(inv(g))
@ -227,26 +241,26 @@ using SparseArrays
X[rand(G)] += rand(1:3) X[rand(G)] += rand(1:3)
Y[rand(G)] -= rand(1:3) Y[rand(G)] -= rand(1:3)
end end
@test X*Y == @test X*Y ==
RG2(X)*RG2(Y) == RG2(X)*RG2(Y) ==
GroupRings.mul!(Z, X, Y) GroupRings.mul!(Z, X, Y)
@test Z.coeffs == GroupRings.GRmul!(W.coeffs, X.coeffs, Y.coeffs, RG.pm) == W.coeffs @test Z.coeffs == GroupRings.GRmul!(W.coeffs, X.coeffs, Y.coeffs, RG.pm) == W.coeffs
@test (2*X*Y).coeffs == @test (2*X*Y).coeffs ==
GroupRings.fmac!(W.coeffs, X.coeffs, Y.coeffs, RG.pm) == GroupRings.fmac!(W.coeffs, X.coeffs, Y.coeffs, RG.pm) ==
GroupRings.mul!(2, X*Y).coeffs GroupRings.mul!(2, X*Y).coeffs
end end
end end
end end
@testset "SumOfSquares in group rings" begin @testset "SumOfSquares in group rings" begin
= star = star
G = FreeGroup(["g", "h", "k", "l"]) G = FreeGroup(["g", "h", "k", "l"])
S = G.(G.gens) S = G.(G.gens)
S = [S; inv.(S)] S = [S; inv.(S)]
ID = G() ID = G()
RADIUS=3 RADIUS=3
@time E_R, sizes = Groups.generate_balls(S, ID, radius=2*RADIUS); @time E_R, sizes = Groups.generate_balls(S, ID, radius=2*RADIUS);
@ -254,14 +268,14 @@ using SparseArrays
E_rdict = GroupRings.reverse_dict(E_R) E_rdict = GroupRings.reverse_dict(E_R)
pm = GroupRings.create_pm(E_R, E_rdict, sizes[RADIUS]; twisted=true); pm = GroupRings.create_pm(E_R, E_rdict, sizes[RADIUS]; twisted=true);
RG = GroupRing(G, E_R, E_rdict, pm) RG = GroupRing(G, E_R, E_rdict, pm)
g = RG.basis[2] g = RG.basis[2]
h = RG.basis[3] h = RG.basis[3]
k = RG.basis[4] k = RG.basis[4]
l = RG.basis[5] l = RG.basis[5]
G = (1-RG(g)) G = (1-RG(g))
@test G^2 == 2 - RG(g) - (RG(g)) @test G^2 == 2 - RG(g) - (RG(g))
G = (1-RG(g)) G = (1-RG(g))
H = (1-RG(h)) H = (1-RG(h))
K = (1-RG(k)) K = (1-RG(k))
@ -271,59 +285,59 @@ using SparseArrays
X = (2 - (RG(g)) - RG(h)) X = (2 - (RG(g)) - RG(h))
Y = (2 - (RG(g*h)) - RG(k)) Y = (2 - (RG(g*h)) - RG(k))
@test -(2 - RG(g*h) - (RG(g*h))) + 2G^2 + 2H^2 == X^2 @test -(2 - RG(g*h) - (RG(g*h))) + 2G^2 + 2H^2 == X^2
@test (2 - RG(g*h) - (RG(g*h))) == GH^2 @test (2 - RG(g*h) - (RG(g*h))) == GH^2
@test -(2 - RG(g*h*k) - (RG(g*h*k))) + 2GH^2 + 2K^2 == Y^2 @test -(2 - RG(g*h*k) - (RG(g*h*k))) + 2GH^2 + 2K^2 == Y^2
@test -(2 - RG(g*h*k) - (RG(g*h*k))) + @test -(2 - RG(g*h*k) - (RG(g*h*k))) +
2(GH^2 - 2G^2 - 2H^2) + 2(GH^2 - 2G^2 - 2H^2) +
4G^2 + 4H^2 + 2K^2 == 4G^2 + 4H^2 + 2K^2 ==
Y^2 Y^2
@test GH^2 - 2G^2 - 2H^2 == - X^2 @test GH^2 - 2G^2 - 2H^2 == - X^2
@test -(2 - RG(g*h*k) - (RG(g*h*k))) + 4G^2 + 4H^2 + 2K^2 == 2X^2 + Y^2 @test -(2 - RG(g*h*k) - (RG(g*h*k))) + 4G^2 + 4H^2 + 2K^2 == 2X^2 + Y^2
@test GH^2 == 2G^2 + 2H^2 - (2 - (RG(g)) - RG(h))^2 @test GH^2 == 2G^2 + 2H^2 - (2 - (RG(g)) - RG(h))^2
@test KL^2 == 2K^2 + 2L^2 - (2 - (RG(k)) - RG(l))^2 @test KL^2 == 2K^2 + 2L^2 - (2 - (RG(k)) - RG(l))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + 2*GH^2 + 2*KL^2 == @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + 2*GH^2 + 2*KL^2 ==
(2 - (RG(g*h)) - RG(k*l))^2 (2 - (RG(g*h)) - RG(k*l))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
2(2G^2 + 2H^2 - (2 - (RG(g)) - RG(h))^2) + 2(2G^2 + 2H^2 - (2 - (RG(g)) - RG(h))^2) +
2(2K^2 + 2L^2 - (2 - (RG(k)) - RG(l))^2) == 2(2K^2 + 2L^2 - (2 - (RG(k)) - RG(l))^2) ==
(2 - (RG(g*h)) - RG(k*l))^2 (2 - (RG(g*h)) - RG(k*l))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
2(2G^2 + 2H^2) + 2(2G^2 + 2H^2) +
2(2K^2 + 2L^2) == 2(2K^2 + 2L^2) ==
(2 - (RG(g*h)) - RG(k*l))^2 + (2 - (RG(g*h)) - RG(k*l))^2 +
2(2 - (RG(g)) - RG(h))^2 + 2(2 - (RG(g)) - RG(h))^2 +
2(2 - (RG(k)) - RG(l))^2 2(2 - (RG(k)) - RG(l))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
2(2 - (RG(g*h*k)) - RG(g*h*k)) + 2L^2 == 2(2 - (RG(g*h*k)) - RG(g*h*k)) + 2L^2 ==
(2 - (RG(g*h*k)) - RG(l))^2 (2 - (RG(g*h*k)) - RG(l))^2
@test 2 - (RG(g*h*k)) - RG(g*h*k) == @test 2 - (RG(g*h*k)) - RG(g*h*k) ==
2GH^2 + 2K^2 - (2 - (RG(g*h)) - RG(k))^2 2GH^2 + 2K^2 - (2 - (RG(g*h)) - RG(k))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
2(2GH^2 + 2K^2 - (2 - (RG(g*h)) - RG(k))^2) + 2L^2 == 2(2GH^2 + 2K^2 - (2 - (RG(g*h)) - RG(k))^2) + 2L^2 ==
(2 - (RG(g*h*k)) - RG(l))^2 (2 - (RG(g*h*k)) - RG(l))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
2(2GH^2 + 2K^2) + 2L^2 == 2(2GH^2 + 2K^2) + 2L^2 ==
(2 - (RG(g*h*k)) - RG(l))^2 + (2 - (RG(g*h*k)) - RG(l))^2 +
2(2 - (RG(g*h)) - RG(k))^2 2(2 - (RG(g*h)) - RG(k))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
8G^2 + 8H^2 + 4K^2 + 2L^2 == 8G^2 + 8H^2 + 4K^2 + 2L^2 ==
(2 - (RG(g*h*k)) - RG(l))^2 + 2(2 - (RG(g*h)) - RG(k))^2 + 4(2 - (RG(g)) - RG(h))^2 (2 - (RG(g*h*k)) - RG(l))^2 + 2(2 - (RG(g*h)) - RG(k))^2 + 4(2 - (RG(g)) - RG(h))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) +
2GH^2 + 2KL^2 == (2 - (RG(g*h)) - RG(k*l))^2 2GH^2 + 2KL^2 == (2 - (RG(g*h)) - RG(k*l))^2
@test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + 2(2G^2 + 2H^2) + 2(2K^2 + 2L^2) == @test -(2 - (RG(g*h*k*l)) - RG(g*h*k*l)) + 2(2G^2 + 2H^2) + 2(2K^2 + 2L^2) ==
(2 - (RG(g*h)) - RG(k*l))^2 + 2(2 - (RG(k)) - RG(l))^2 + 2(2 - (RG(g)) - RG(h))^2 (2 - (RG(g*h)) - RG(k*l))^2 + 2(2 - (RG(k)) - RG(l))^2 + 2(2 - (RG(g)) - RG(h))^2
end end