diff --git a/src/mtables.jl b/src/mtables.jl index fcf0f23..6b9fac0 100644 --- a/src/mtables.jl +++ b/src/mtables.jl @@ -92,6 +92,23 @@ function complete!(mt::MTable) return mt end +function MA.operate!( + ms::UnsafeAddMul{<:MTable}, + res::AbstractCoefficients, + v::AbstractCoefficients, + w::AbstractCoefficients, +) + for (kv, a) in nonzero_pairs(v) + for (kw, b) in nonzero_pairs(w) + c = ms.structure(kv, kw) + for (k, v) in nonzero_pairs(c) + res[ms.structure[k]] += v * a * b + end + end + end + return res +end + function MA.operate!( ms::UnsafeAddMul{<:MTable}, res::AbstractSparseVector, diff --git a/test/abstract_coeffs.jl b/test/abstract_coeffs.jl index c5b6536..efc6826 100644 --- a/test/abstract_coeffs.jl +++ b/test/abstract_coeffs.jl @@ -1,51 +1,3 @@ -struct ACoeffs{T} <: SA.AbstractCoefficients{UInt32,T} - vals::Vector{T} -end - -# convienience: -ACoeffs(v::AbstractVector) = ACoeffs{valtype(v)}(v) - -# AbstractCoefficients API - -## Basic API -Base.keys(ac::ACoeffs) = (k for (k, v) in pairs(ac.vals) if !iszero(v)) -Base.values(ac::ACoeffs) = (v for v in ac.vals if !iszero(v)) -SA.canonical(ac::ACoeffs) = ac -function SA.star(b::SA.AbstractBasis, ac::ACoeffs) - return ACoeffs([ac.vals[star(b, k)] for k in keys(ac)]) -end - -# for preallocation in arithmetic -function Base.similar(ac::ACoeffs, ::Type{T}) where {T} - # it is needed to zero as uninitialized values may not be cleared by - # MA.operate!(zero, ac) - return ACoeffs(zeros(T, size(ac.vals))) -end - -# the default arithmetic implementation uses this access -Base.getindex(ac::ACoeffs, idx) = ac.vals[idx] -Base.setindex!(ac::ACoeffs, val, idx) = ac.vals[idx] = val - -# a very basic * using ms.structure; -# TODO: this is so generic that it should be included in SA -# but then it hijacks the more refined version -function MA.operate!( - ms::SA.UnsafeAddMul, - res::ACoeffs, - v::SA.AbstractCoefficients, - w::SA.AbstractCoefficients, -) - for (kv, a) in SA.nonzero_pairs(v) - for (kw, b) in SA.nonzero_pairs(w) - c = ms.structure(kv, kw) - for (k, v) in SA.nonzero_pairs(c) - res[ms.structure[k]] += v * a * b - end - end - end - return res -end - @testset "Abstract coefficients" begin G = PermGroup(perm"(1,2,3)", perm"(1,2)") RG = StarAlgebra(G, SA.DiracBasis{UInt8}(G)) diff --git a/test/runtests.jl b/test/runtests.jl index 8e9866c..3d87d80 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -22,6 +22,9 @@ end # implementations of the free monoid over an alphabet include("test_example_words.jl") +# example implementation of abstract coefficients +include("test_example_acoeffs.jl") + @testset "StarAlgebras" begin # proof of concept using PermutationGroups diff --git a/test/test_example_acoeffs.jl b/test/test_example_acoeffs.jl new file mode 100644 index 0000000..3a21966 --- /dev/null +++ b/test/test_example_acoeffs.jl @@ -0,0 +1,27 @@ +struct ACoeffs{T} <: SA.AbstractCoefficients{UInt32,T} + vals::Vector{T} +end + +# convienience: +ACoeffs(v::AbstractVector) = ACoeffs{valtype(v)}(v) + +# AbstractCoefficients API + +## Basic API +Base.keys(ac::ACoeffs) = (k for (k, v) in pairs(ac.vals) if !iszero(v)) +Base.values(ac::ACoeffs) = (v for v in ac.vals if !iszero(v)) +SA.canonical(ac::ACoeffs) = ac +function SA.star(b::SA.AbstractBasis, ac::ACoeffs) + return ACoeffs([ac.vals[star(b, k)] for k in keys(ac)]) +end + +# for preallocation in arithmetic +function Base.similar(ac::ACoeffs, ::Type{T}) where {T} + vals = similar(ac.vals, T) + MA.operate!(zero, vals) + return ACoeffs(vals) +end + +# the default arithmetic implementation uses this access +Base.getindex(ac::ACoeffs, idx) = ac.vals[idx] +Base.setindex!(ac::ACoeffs, val, idx) = ac.vals[idx] = val