mirror of
https://github.com/kalmarek/GroupRings.jl.git
synced 2024-12-28 18:50:29 +01:00
StarAlgebras (+their elements) based on Basis and MStructures
This commit is contained in:
parent
781e26299f
commit
1151ac7bd3
@ -565,12 +565,18 @@ end
|
||||
|
||||
|
||||
module New
|
||||
using SparseArrays
|
||||
import LinearAlgebra
|
||||
|
||||
include("bases.jl")
|
||||
|
||||
include("mstructures.jl")
|
||||
include("mtables.jl")
|
||||
|
||||
include("types.jl")
|
||||
include("algebra_elts.jl")
|
||||
include("show.jl")
|
||||
|
||||
end
|
||||
|
||||
end # of module GroupRings
|
||||
|
44
src/algebra_elts.jl
Normal file
44
src/algebra_elts.jl
Normal file
@ -0,0 +1,44 @@
|
||||
function Base.hash(a::AlgebraElement, h::UInt)
|
||||
return hash(coeffs(a), hash(parent(a), hash(typeof(a), h)))
|
||||
end
|
||||
function Base.:(==)(X::AlgebraElement, Y::AlgebraElement)
|
||||
parent(X) === parent(Y) || return false
|
||||
return coeffs(X) == coeffs(Y)
|
||||
end
|
||||
|
||||
Base.getindex(a::AlgebraElement, i::Integer) = coeffs(a)[i]
|
||||
Base.getindex(a::AlgebraElement{<:StarAlgebra{O,T}}, x::T) where {O,T} =
|
||||
(b = basis(parent(a)); a[b[x]])
|
||||
|
||||
# call overload:
|
||||
(a::AlgebraElement)(x) = a[x]
|
||||
|
||||
Base.setindex!(a::AlgebraElement, v, i::Integer) = a.coeffs[i] = v
|
||||
|
||||
function Base.setindex!(a::AlgebraElement{<:StarAlgebra{O,T}}, v, t::T) where {O,T}
|
||||
b = basis(parent(a))
|
||||
return a[b[t]] = v
|
||||
end
|
||||
|
||||
|
||||
# AlgebraElement specific functions
|
||||
|
||||
supp_ind(a::AlgebraElement) = findall(!iszero, coeffs(a))
|
||||
supp_ind(a::AlgebraElement{A,T,<:SparseVector}) where {A,T} = coeffs(a).nzind
|
||||
supp(a::AlgebraElement) = (b = basis(parent(a)); [b[i] for i in supp_ind(a)])
|
||||
|
||||
function star(X::AlgebraElement)
|
||||
A = parent(X)
|
||||
b = basis(A)
|
||||
supp_X = supp_ind(X)
|
||||
idcs = similar(supp_X)
|
||||
vals = similar(idcs, eltype(X))
|
||||
for (i, idx) in enumerate(supp_X)
|
||||
idcs[i] = b[star(b[idx])]
|
||||
vals[i] = X[idx]
|
||||
end
|
||||
return AlgebraElement(sparsevec(idcs, vals, length(b)), A)
|
||||
end
|
||||
|
||||
LinearAlgebra.norm(a::AlgebraElement, p) = LinearAlgebra.norm(coeffs(a), p)
|
||||
aug(a::AlgebraElement) = sum(coeffs(a))
|
35
src/show.jl
Normal file
35
src/show.jl
Normal file
@ -0,0 +1,35 @@
|
||||
Base.show(io::IO, A::AbstractStarAlgebra) = print(io, "*-Algebra of $(object(A))")
|
||||
|
||||
__prints_with_minus(x) = false
|
||||
__prints_with_minus(x::Real) = x < 0
|
||||
|
||||
function Base.show(io::IO, a::AlgebraElement)
|
||||
A = parent(a)
|
||||
if iszero(a)
|
||||
T = eltype(a)
|
||||
print(io, "$(zero(T))*$(one(object(A)))")
|
||||
elseif hasbasis(A)
|
||||
elts = String[]
|
||||
nzeros = findall(!iszero, coeffs(a))
|
||||
for (counter, idx) in enumerate(nzeros)
|
||||
c, elt = coeffs(a)[idx], basis(A)[idx]
|
||||
if counter == 1
|
||||
print(io, c, '·', elt)
|
||||
length(nzeros) > 1 && print(io, ' ')
|
||||
else
|
||||
__prints_with_minus(c) || print(io, '+')
|
||||
print(io, c, '·', elt)
|
||||
counter == length(nzeros) || print(io, ' ')
|
||||
end
|
||||
end
|
||||
else
|
||||
println(io, "Algebra element without defined basis")
|
||||
show(io, MIME("text/plain"), a.coeffs)
|
||||
end
|
||||
end
|
||||
|
||||
function Base.show(io::IO, ::MIME"text/plain", mstr::TrivialMStructure)
|
||||
Tw = _istwisted(mstr)
|
||||
l = length(basis(mstr))
|
||||
print(io, "TrivialMStructure{$Tw} over basis with $l elements")
|
||||
end
|
116
src/types.jl
Normal file
116
src/types.jl
Normal file
@ -0,0 +1,116 @@
|
||||
abstract type AbstractStarAlgebra end
|
||||
|
||||
struct StarAlgebra{O,T,M<:MultiplicativeStructure,B<:AbstractBasis{T}} <:
|
||||
AbstractStarAlgebra
|
||||
object::O
|
||||
mstructure::M
|
||||
basis::B
|
||||
|
||||
function StarAlgebra(obj, basis::AbstractBasis, mstr::MultiplicativeStructure)
|
||||
O = typeof(obj)
|
||||
T = eltype(basis)
|
||||
M = typeof(mstr)
|
||||
B = typeof(basis)
|
||||
|
||||
return new{O,T,M,B}(obj, mstr, basis)
|
||||
end
|
||||
|
||||
function StarAlgebra(obj, mstr::MultiplicativeStructure)
|
||||
O = typeof(obj)
|
||||
T = Symbol
|
||||
M = typeof(mstr)
|
||||
B = Basis{T,Int}
|
||||
|
||||
return new{O,T,M,B}(obj, mstr)
|
||||
end
|
||||
end
|
||||
|
||||
# TrivialMStructure:
|
||||
StarAlgebra(obj, basis::AbstractBasis) = StarAlgebra{false}(obj, basis)
|
||||
|
||||
function StarAlgebra{Tw}(obj, basis::AbstractBasis) where {Tw}
|
||||
mstr = TrivialMStructure{Tw}(basis)
|
||||
return StarAlgebra(obj, basis, mstr)
|
||||
end
|
||||
|
||||
# CachedMStructure:
|
||||
StarAlgebra(obj, basis::AbstractBasis, cache_size::Tuple{<:Integer,Integer}) =
|
||||
StarAlgebra{false}(obj, basis, cache_size)
|
||||
|
||||
function StarAlgebra{Tw}(
|
||||
obj,
|
||||
basis::AbstractBasis,
|
||||
cache_size::Tuple{<:Integer,Integer},
|
||||
) where {Tw}
|
||||
mstr = CachedMTable{Tw}(basis, table_size = cache_size)
|
||||
return StarAlgebra(obj, basis, mstr)
|
||||
end
|
||||
|
||||
hasbasis(A::StarAlgebra) = isdefined(A, :basis)
|
||||
|
||||
basis(A::StarAlgebra) = A.basis
|
||||
object(A::StarAlgebra) = A.object
|
||||
# Base.eltype(A::StarAlgebra{O,B}) where {O,B} = eltype(B)
|
||||
|
||||
|
||||
struct AlgebraElement{A,T,V<:AbstractVector{T}}
|
||||
coeffs::V
|
||||
parent::A
|
||||
|
||||
function AlgebraElement(coeffs::AbstractVector, A::AbstractStarAlgebra)
|
||||
if hasbasis(A)
|
||||
@assert length(coeffs) == length(basis(A))
|
||||
end
|
||||
return new{typeof(A),eltype(coeffs),typeof(coeffs)}(coeffs, A)
|
||||
end
|
||||
end
|
||||
|
||||
coeffs(a::AlgebraElement) = a.coeffs
|
||||
Base.parent(a::AlgebraElement) = a.parent
|
||||
Base.eltype(a::AlgebraElement) = eltype(coeffs(a))
|
||||
|
||||
|
||||
### constructing elements
|
||||
|
||||
function Base.zero(A::AbstractStarAlgebra, T = Int)
|
||||
if hasbasis(A)
|
||||
return AlgebraElement(spzeros(T, length(basis(A))), A)
|
||||
else
|
||||
return AlgebraElement(spzeros(T, maximum(A.mstructure)))
|
||||
end
|
||||
end
|
||||
|
||||
Base.one(A::AbstractStarAlgebra, T = Int) = A(one(object(A)), T)
|
||||
|
||||
Base.zero(a::AlgebraElement) = zero(parent(a))
|
||||
Base.one(a::AlgebraElement) = one(parent(a))
|
||||
|
||||
Base.iszero(a::AlgebraElement) = iszero(coeffs(a))
|
||||
|
||||
function Base.isone(a::AlgebraElement, T = Int)
|
||||
b = basis(parent(a))
|
||||
k = findfirst(!iszero, coeffs(a))
|
||||
k === nothing && return false
|
||||
isone(a[k]) || return false
|
||||
return isone(b[k])
|
||||
end
|
||||
|
||||
function (A::AbstractStarAlgebra)(elt, T = Int)
|
||||
if hasbasis(A)
|
||||
b = basis(A)
|
||||
i = b[elt]
|
||||
return AlgebraElement(sparsevec([i], [one(T)], length(b)), A)
|
||||
else
|
||||
throw("Cannot coerce $elt to an algebra without defined basis")
|
||||
end
|
||||
end
|
||||
|
||||
function (A::AbstractStarAlgebra)(x::Number)
|
||||
g = one(object(A))
|
||||
res = A(g, typeof(x))
|
||||
res = mul!(res, res, x)
|
||||
return res
|
||||
end
|
||||
|
||||
Base.similar(X::AlgebraElement, ::Type{T} = eltype(X)) where {T} =
|
||||
AlgebraElement(similar(coeffs(X), T), parent(X))
|
@ -30,3 +30,33 @@
|
||||
@test tmstr[3, 2] == b[inv(b[3])*b[2]]
|
||||
end
|
||||
|
||||
@testset "Group Algebra caching" begin
|
||||
G = SymmetricGroup(3)
|
||||
b = New.Basis{UInt8}(collect(G))
|
||||
l = length(b)
|
||||
|
||||
RG = New.StarAlgebra(G, b, (l, l))
|
||||
@test RG isa New.StarAlgebra
|
||||
|
||||
D = ((l + 1) * one(RG) - sum(RG(g) for g in b)) // 6
|
||||
@test D isa New.AlgebraElement
|
||||
g = RG(b[1])
|
||||
@test isone(g)
|
||||
@test one(RG) == g
|
||||
@test iszero(zero(RG))
|
||||
@test 0 * g == zero(RG)
|
||||
@test iszero(0 * g)
|
||||
|
||||
h = RG(b[3])
|
||||
|
||||
@test D * one(RG) == D
|
||||
|
||||
@test all(New.supp(D) .== b)
|
||||
|
||||
@test one(RG) * D == D
|
||||
@test any(iszero, RG.mstructure.table)
|
||||
|
||||
@test D * D isa New.AlgebraElement
|
||||
|
||||
@test all(!iszero, RG.mstructure.table)
|
||||
end
|
||||
|
47
test/constructors.jl
Normal file
47
test/constructors.jl
Normal file
@ -0,0 +1,47 @@
|
||||
@testset "Algebra and Elements Constructors" begin
|
||||
G = SymmetricGroup(3)
|
||||
b = New.Basis{UInt8}(collect(G))
|
||||
l = length(b)
|
||||
|
||||
RG = New.StarAlgebra(G, b, (l, l))
|
||||
|
||||
a = rand(6)
|
||||
|
||||
@test New.AlgebraElement(a, RG) isa New.AlgebraElement
|
||||
@test all(RG(g) isa New.AlgebraElement{typeof(RG)} for g in G)
|
||||
|
||||
@test_throws AssertionError New.AlgebraElement([1,2,3], RG)
|
||||
@test New.AlgebraElement([1,2,3,0,0,0], RG) isa New.AlgebraElement
|
||||
|
||||
p = G([2,3,1])
|
||||
a = RG(p)
|
||||
@test New.coeffs(a) isa SparseVector
|
||||
@test New.coeffs(a)[5] == 1
|
||||
@test all(New.coeffs(a)[i] == 0 for i in 1:6 if i ≠ 5)
|
||||
@test a(p) == 1
|
||||
@test all(a(g) == 0 for g in G if g != p)
|
||||
|
||||
@test sprint(show, a) == "1·(1,2,3)"
|
||||
@test sprint(show, -a) == "-1·(1,2,3)"
|
||||
|
||||
@test New.AlgebraElement([0,0,0,0,1,0], RG) == a
|
||||
|
||||
@test New.supp(a) == [p]
|
||||
@test New.supp_ind(a) == [5]
|
||||
|
||||
s = one(G)
|
||||
@test a(s) == 0
|
||||
|
||||
a[s] = 2
|
||||
|
||||
@test New.coeffs(a)[1] == 2
|
||||
@test a[1] == 2
|
||||
@test a(s) == 2
|
||||
|
||||
@test New.supp(a) == [s, p]
|
||||
@test New.supp_ind(a) == [1, 5]
|
||||
|
||||
@test sprint(show, a) == "2·() +1·(1,2,3)"
|
||||
@test sprint(show, -a) == "-2·() -1·(1,2,3)"
|
||||
@test sprint(show, New.AlgebraElement([2,0,0,0,-1,0], RG)) == "2·() -1·(1,2,3)"
|
||||
end
|
@ -10,6 +10,7 @@ using GroupRings.New
|
||||
|
||||
New.star(p::Generic.Perm) = inv(p)
|
||||
|
||||
include("constructors.jl")
|
||||
include("cachedmtables.jl")
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user