From de054b2295533681ac252e90a4b7fde665c7a253 Mon Sep 17 00:00:00 2001 From: Marek Kaluba Date: Thu, 9 May 2024 12:18:02 +0200 Subject: [PATCH] make augmented stuff a self-contained file --- src/StarAlgebras.jl | 8 ++-- src/algebra_elts.jl | 2 - src/bases_dirac.jl | 59 -------------------------- src/coefficients.jl | 6 --- src/diracs_augmented.jl | 91 +++++++++++++++++++++++++++++++++++++++- src/mstructures.jl | 14 ------- src/star.jl | 4 -- test/group_algebra.jl | 16 +++---- test/perm_grp_algebra.jl | 8 ++-- test/sum_of_squares.jl | 2 +- 10 files changed, 108 insertions(+), 102 deletions(-) diff --git a/src/StarAlgebras.jl b/src/StarAlgebras.jl index e907744..10bd653 100644 --- a/src/StarAlgebras.jl +++ b/src/StarAlgebras.jl @@ -6,13 +6,12 @@ import LinearAlgebra import MutableArithmetics as MA export StarAlgebra, AlgebraElement -export aug, basis, coeffs, star, supp +export basis, coeffs, star, supp # AbstractCoefficients ## abstract definitions include("coefficients.jl") -## concrete implementations -include("diracs_augmented.jl") +## concrete implementation include("sparse_coeffs.jl") # MultiplicativeStructures @@ -34,4 +33,7 @@ include("star.jl") include("arithmetic.jl") include("show.jl") +# augmented basis implementation +include("diracs_augmented.jl") + end diff --git a/src/algebra_elts.jl b/src/algebra_elts.jl index a02a3b2..8644903 100644 --- a/src/algebra_elts.jl +++ b/src/algebra_elts.jl @@ -25,8 +25,6 @@ function supp(a::AlgebraElement) return [b[i] for (i, _) in nonzero_pairs(coeffs(a))] end -aug(a::AlgebraElement) = aug(coeffs(a)) - function LinearAlgebra.norm(a::AlgebraElement, p::Real) return LinearAlgebra.norm(coeffs(a), p) end diff --git a/src/bases_dirac.jl b/src/bases_dirac.jl index c11acc6..d04b2c5 100644 --- a/src/bases_dirac.jl +++ b/src/bases_dirac.jl @@ -27,62 +27,3 @@ function Base.getindex(db::DiracBasis{T}, x::T) where {T} @assert x in object(db) return x end - -mutable struct AugmentedBasis{T,I,A<:Augmented{T},B<:AbstractBasis{T,I}} <: - ImplicitBasis{A,I} - basis::B -end - -function AugmentedBasis(basis::DiracBasis{T,I}) where {T,I} - return AugmentedBasis{T,I,Augmented{T},typeof(basis)}(basis) -end - -object(ab::AugmentedBasis) = object(ab.basis) - -Base.IteratorSize(::Type{<:AugmentedBasis{T,A,I,B}}) where {T,A,I,B} = Base.IteratorSize(B) -Base.haslength(ab::AugmentedBasis) = Base.haslength(ab.basis) - -function Base.length(ab::AugmentedBasis) - @assert Base.haslength(ab.basis) - return length(ab.basis) - 1 -end - -function Base.iterate(ab::AugmentedBasis) - return ((v, st) = iterate(object(ab)); (Augmented(v), st)) -end -function Base.iterate(ab::AugmentedBasis, st) - return ((v, st) = iterate(object(ab), st); (Augmented(v), st)) -end - -Base.in(g, ab::AugmentedBasis) = false -Base.in(ad::Augmented, ab::AugmentedBasis) = ad.elt in ab.basis - -function Base.getindex(ab::AugmentedBasis{T,I,A}, x::A) where {T,I,A} - @assert x.elt in object(ab) - return x -end - -mstructure(db::AugmentedBasis) = AugmentedMStructure(mstructure(db.basis)) - -function coeffs!( - res::AbstractCoefficients, - cfs::AbstractCoefficients, - source::DiracBasis, - target::AugmentedBasis, -) - s = aug(cfs) - if !iszero(s) - throw("Conversion to $target not possible due to non-zero augmentation: $s") - end - for (k, v) in nonzero_pairs(cfs) - isone(k) && continue - x = source[k] - MA.operate!( - UnsafeAddMul(*), - res, - v, - SparseCoefficients((target[Augmented(x)],), (1,)), - ) - end - return MA.operate!!(canonical, res) -end diff --git a/src/coefficients.jl b/src/coefficients.jl index c28edf7..d807eff 100644 --- a/src/coefficients.jl +++ b/src/coefficients.jl @@ -78,12 +78,6 @@ end return zip(SparseArrays.nonzeroinds(v), SparseArrays.nonzeros(v)) end -aug(cfs::Any) = sum(values(cfs)) -function aug(ac::AbstractCoefficients) - isempty(keys(ac)) && return zero(valtype(ac)) - return sum(c * aug(x) for (x, c) in nonzero_pairs(ac)) -end - function LinearAlgebra.norm(sc::AbstractCoefficients, p::Real) isempty(keys(sc)) && return (0^p)^1 / p return sum(v^p for v in values(sc))^1 / p diff --git a/src/diracs_augmented.jl b/src/diracs_augmented.jl index 1424e98..09b887a 100644 --- a/src/diracs_augmented.jl +++ b/src/diracs_augmented.jl @@ -1,3 +1,11 @@ +aug(cfs::Any) = sum(values(cfs)) +aug(a::AlgebraElement) = aug(coeffs(a)) + +function aug(ac::AbstractCoefficients) + isempty(keys(ac)) && return zero(valtype(ac)) + return sum(c * aug(x) for (x, c) in nonzero_pairs(ac)) +end + struct Augmented{K} <: AbstractCoefficients{K,Int} elt::K end # corresponds to (elt - 1) @@ -18,6 +26,10 @@ function Base.values(aδ::Augmented) return (aδ[e], aδ[x]) end +function star(basis::AbstractBasis, ad::Augmented) + return Augmented(star(basis, ad.elt)) +end + function Base.show(io::IO, aδ::Augmented) ioc = IOContext(io, :limit => true) if iszero(aδ) @@ -31,5 +43,82 @@ end Base.isless(ad1::Augmented, ad2::Augmented) = isless(ad1.elt, ad2.elt) -# optimization aug(::Augmented) = 0 + +struct AugmentedBasis{T,I,A<:Augmented{T},B<:AbstractBasis{T,I}} <: + ImplicitBasis{A,I} + basis::B +end + +function AugmentedBasis(basis::DiracBasis{T,I}) where {T,I} + return AugmentedBasis{T,I,Augmented{T},typeof(basis)}(basis) +end + +object(ab::AugmentedBasis) = object(ab.basis) + +function Base.IteratorSize(::Type{<:AugmentedBasis{T,A,I,B}}) where {T,A,I,B} + return Base.IteratorSize(B) +end +Base.haslength(ab::AugmentedBasis) = Base.haslength(ab.basis) + +function Base.length(ab::AugmentedBasis) + @assert Base.haslength(ab.basis) + return length(ab.basis) - 1 +end + +function Base.iterate(ab::AugmentedBasis) + return ((v, st) = iterate(object(ab)); (Augmented(v), st)) +end +function Base.iterate(ab::AugmentedBasis, st) + return ((v, st) = iterate(object(ab), st); (Augmented(v), st)) +end + +Base.in(g, ab::AugmentedBasis) = false +Base.in(ad::Augmented, ab::AugmentedBasis) = ad.elt in ab.basis + +function Base.getindex(ab::AugmentedBasis{T,I,A}, x::A) where {T,I,A} + @assert x.elt in object(ab) + return x +end + +mstructure(db::AugmentedBasis) = AugmentedMStructure(mstructure(db.basis)) + +struct AugmentedMStructure{M<:DiracMStructure} <: MultiplicativeStructure + op::M +end + +function (mstr::AugmentedMStructure)(aδx::Augmented, aδy::Augmented) + δxy = first(keys(mstr.op(aδx.elt, aδy.elt))) + if isone(δxy) + return SparseCoefficients((aδx, aδy), (-1, -1)) + else + aδxy = Augmented(δxy) + #(x-1)*(y-1) = 1 - x - y + xy = -1·(x-1) - 1·(y-1) + 1·(xy-1) + return SparseCoefficients((aδx, aδy, aδxy), (-1, -1, 1)) + end +end + +function coeffs!( + res::AbstractCoefficients, + cfs::AbstractCoefficients, + source::DiracBasis, + target::AugmentedBasis, +) + s = aug(cfs) + if !iszero(s) + throw( + "Conversion to $target not possible due to non-zero augmentation: $s", + ) + end + for (k, v) in nonzero_pairs(cfs) + isone(k) && continue + x = source[k] + MA.operate!( + UnsafeAddMul(*), + res, + v, + SparseCoefficients((target[Augmented(x)],), (1,)), + ) + end + return MA.operate!!(canonical, res) +end diff --git a/src/mstructures.jl b/src/mstructures.jl index f7a4f89..686cca7 100644 --- a/src/mstructures.jl +++ b/src/mstructures.jl @@ -87,17 +87,3 @@ function (mstr::DiracMStructure)(x::T, y::T) where {T} return SparseCoefficients((xy,), (1,)) end -struct AugmentedMStructure{M<:DiracMStructure} <: MultiplicativeStructure - op::M -end - -function (mstr::AugmentedMStructure)(aδx::Augmented, aδy::Augmented) - δxy = first(keys(mstr.op(aδx.elt, aδy.elt))) - if isone(δxy) - return SparseCoefficients((aδx, aδy), (-1, -1)) - else - aδxy = Augmented(δxy) - #(x-1)*(y-1) = 1 - x - y + xy = -1·(x-1) - 1·(y-1) + 1·(xy-1) - return SparseCoefficients((aδx, aδy, aδxy), (-1, -1, 1)) - end -end diff --git a/src/star.jl b/src/star.jl index 07b48da..6735dd9 100644 --- a/src/star.jl +++ b/src/star.jl @@ -9,10 +9,6 @@ end star(::AbstractBasis, x) = star(x) star(basis::ImplicitBasis, i::Integer) = basis[-i] -function star(basis::AbstractBasis, ad::Augmented) - return Augmented(star(basis, ad.elt)) -end - function star(basis::AbstractBasis, d::SparseCoefficients) k = star.(Ref(basis), keys(d)) v = star.(values(d)) diff --git a/test/group_algebra.jl b/test/group_algebra.jl index 4a892a3..7559a65 100644 --- a/test/group_algebra.jl +++ b/test/group_algebra.jl @@ -86,7 +86,7 @@ @test star(RG(g)) == RG(inv(g)) @test (one(RG) - RG(g)) * star(one(RG) - RG(g)) == 2 * one(RG) - RG(g) - RG(inv(g)) - @test aug(one(RG) - RG(g)) == 0 + @test SA.aug(one(RG) - RG(g)) == 0 end g, h = PermutationGroups.gens(G) @@ -99,16 +99,16 @@ @test a * b == MA.operate_to!(similar(a), *, a, b) - @test aug(a) == 3 - @test aug(b) == -1 - @test aug(a) * aug(b) == aug(a * b) == aug(b * a) + @test SA.aug(a) == 3 + @test SA.aug(b) == -1 + @test SA.aug(a) * SA.aug(b) == SA.aug(a * b) == SA.aug(b * a) z = sum((one(RG) - RG(g)) * star(one(RG) - RG(g)) for g in G) - @test aug(z) == 0 + @test SA.aug(z) == 0 - @test supp(z) == sort(collect(basis(parent(z)))) - @test supp(RG(1) + RG(g)) == [one(G), g] - @test supp(a) == [one(G), h, g] + @test SA.supp(z) == sort(collect(basis(parent(z)))) + @test SA.supp(RG(1) + RG(g)) == [one(G), g] + @test SA.supp(a) == [one(G), h, g] @testset "Projections in star algebras" begin b = basis(RG) diff --git a/test/perm_grp_algebra.jl b/test/perm_grp_algebra.jl index a7566f2..9de784b 100644 --- a/test/perm_grp_algebra.jl +++ b/test/perm_grp_algebra.jl @@ -56,7 +56,7 @@ scfs = SA.SparseCoefficients(rand(G, 10), rand(-2:2, 10)) s = SA.AlgebraElement(scfs, RG) - @test aug(r * s) == aug(r) * aug(s) + @test SA.aug(r * s) == SA.aug(r) * SA.aug(s) end @testset "Fixed Basis" begin m = PermutationGroups.order(UInt16, G) @@ -76,9 +76,9 @@ fr = SA.AlgebraElement(coeffs(r, basis(fRG)), fRG) fs = SA.AlgebraElement(coeffs(s, basis(fRG)), fRG) - @test aug(fr) == aug(r) - @test aug(fs) == aug(s) - @test aug(fr * fs) == aug(fr) * aug(fs) + @test SA.aug(fr) == SA.aug(r) + @test SA.aug(fs) == SA.aug(s) + @test SA.aug(fr * fs) == SA.aug(fr) * SA.aug(fs) @test coeffs(r * s, basis(fRG)) isa AbstractVector @test fr * fs == SA.AlgebraElement(coeffs(r * s, basis(fRG)), fRG) diff --git a/test/sum_of_squares.jl b/test/sum_of_squares.jl index 59cf4fc..ed4df7b 100644 --- a/test/sum_of_squares.jl +++ b/test/sum_of_squares.jl @@ -7,7 +7,7 @@ E_R, sizes = Groups.wlmetric_ball(S, ID; radius = 2 * RADIUS) @test sizes == [9, 65, 457, 3201, 22409, 156865] - b = StarAlgebras.DiracBasis{UInt32}(F) + b = SA.DiracBasis{UInt32}(F) RG = StarAlgebra(F, b)