diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index aece144..b6e28c4 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -1,15 +1,15 @@ name: CI on: - pull_request + - push jobs: test: - name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} - ${{ github.event_name }} + name: Julia ${{ matrix.version }} - ${{ matrix.os }} - ${{ matrix.arch }} runs-on: ${{ matrix.os }} strategy: - fail-fast: false matrix: version: - - '1.0' + - '1.6' - '1' - 'nightly' os: @@ -18,13 +18,16 @@ jobs: - windows-latest arch: - x64 + allow_failures: + - julia: nightly + fail-fast: false steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - uses: julia-actions/setup-julia@v1 with: version: ${{ matrix.version }} arch: ${{ matrix.arch }} - - uses: actions/cache@v1 + - uses: actions/cache@v3 env: cache-name: cache-artifacts with: @@ -34,12 +37,15 @@ jobs: ${{ runner.os }}-test-${{ env.cache-name }}- ${{ runner.os }}-test- ${{ runner.os }}- - - uses: julia-actions/julia-buildpkg@v1 - - uses: julia-actions/julia-runtest@v1 + - uses: julia-actions/julia-buildpkg@latest + - uses: julia-actions/julia-runtest@latest - uses: julia-actions/julia-processcoverage@v1 - - uses: codecov/codecov-action@v1 + - uses: codecov/codecov-action@v2 with: - file: lcov.info + file: ./lcov.info + flags: unittests + name: codecov-umbrella + fail_ci_if_error: false docs: name: Documentation runs-on: ubuntu-latest diff --git a/.github/workflows/TagBot.yml b/.github/workflows/TagBot.yml index f49313b..f389611 100644 --- a/.github/workflows/TagBot.yml +++ b/.github/workflows/TagBot.yml @@ -4,6 +4,11 @@ on: types: - created workflow_dispatch: + inputs: + lookback: + default: 3 +permissions: + contents: write jobs: TagBot: if: github.event_name == 'workflow_dispatch' || github.actor == 'JuliaTagBot' diff --git a/Project.toml b/Project.toml index 007b6a2..dd5f943 100644 --- a/Project.toml +++ b/Project.toml @@ -1,21 +1,22 @@ name = "StarAlgebras" uuid = "0c0c59c1-dc5f-42e9-9a8b-b5dc384a6cd1" authors = ["Marek Kaluba "] -version = "0.1.7" +version = "0.1.8" [deps] LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" [compat] -GroupsCore = "0.4" -julia = "1" +julia = "1.6" [extras] -Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" +Groups = "5d8bd718-bd84-11e8-3b40-ad14f4a32557" GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120" +PermutationGroups = "8bc5a954-2dfc-11e9-10e6-cd969bffa420" +Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" [targets] -test = ["Pkg", "GroupsCore", "Random", "Test"] +test = ["Pkg", "Groups", "GroupsCore", "PermutationGroups", "Random", "Test"] diff --git a/src/algebra_elts.jl b/src/algebra_elts.jl index b1c0cbb..248e31a 100644 --- a/src/algebra_elts.jl +++ b/src/algebra_elts.jl @@ -50,3 +50,9 @@ aug(a::AlgebraElement) = sum(coeffs(a)) LinearAlgebra.dot(a::AlgebraElement, v::AbstractVector) = LinearAlgebra.dot(StarAlgebras.coeffs(a), v) LinearAlgebra.dot(v::AbstractVector, a::AlgebraElement) = LinearAlgebra.dot(a, v) + +Base.copy(a::AlgebraElement) = AlgebraElement(copy(coeffs(a)), parent(a)) +function Base.deepcopy_internal(a::AlgebraElement, stackdict::IdDict) + haskey(stackdict, a) && return stackdict[a] + return AlgebraElement(deepcopy(coeffs(a)), parent(a)) +end diff --git a/src/arithmetic.jl b/src/arithmetic.jl index 419208a..376638a 100644 --- a/src/arithmetic.jl +++ b/src/arithmetic.jl @@ -6,6 +6,7 @@ Base.:(/)(X::AlgebraElement, a::Number) = inv(a) * X # TODO: handle this through mul!? Base.:(//)(X::AlgebraElement, a::Number) = AlgebraElement(coeffs(X) .// a, parent(X)) +Base.:div(X::AlgebraElement, a::Number) = AlgebraElement(div.(coeffs(X), a), parent(X)) # ring structure: Base.:-(X::AlgebraElement) = neg!(similar(X), X) @@ -33,28 +34,48 @@ end function neg!(res::AlgebraElement, X::AlgebraElement) @assert parent(res) === parent(X) - res.coeffs .= -coeffs(X) + res.coeffs .= .-coeffs(X) return res end function add!(res::AlgebraElement, X::AlgebraElement, Y::AlgebraElement) - @assert parent(res) === parent(X) === parent(Y) - # res = (res === X || res === Y) ? similar(res) : res - res.coeffs .= coeffs(X) .+ coeffs(Y) + @assert parent(res) === parent(X) + @assert parent(X) === parent(Y) + if res === X + for (idx, y) in _nzpairs(coeffs(Y)) + res[idx] += y + end + elseif res === Y + for (idx, x) in _nzpairs(coeffs(X)) + res[idx] += x + end + else + zero!(res) + for (idx, x) in _nzpairs(coeffs(X)) + res[idx] += x + end + for (idx, y) in _nzpairs(coeffs(Y)) + res[idx] += y + end + end return res end function sub!(res::AlgebraElement, X::AlgebraElement, Y::AlgebraElement) @assert parent(res) === parent(X) === parent(Y) - # res = (res === X || res === Y) ? similar(res) : res - res.coeffs .= coeffs(X) .- coeffs(Y) + neg!(res, Y) + add!(res, res, X) return res end function mul!(res::AlgebraElement, X::AlgebraElement, a::Number) @assert parent(res) === parent(X) - # res = (res === X) ? similar(res) : res - res.coeffs .= a .* coeffs(X) + if res !== X + zero!(res) + end + for (idx, x) in _nzpairs(coeffs(X)) + res.coeffs[idx] = a * x + end return res end @@ -69,12 +90,12 @@ function mul!( end function mul!(res::AlgebraElement, X::AlgebraElement, Y::AlgebraElement) - @assert parent(res) === parent(X) === parent(Y) res = (res === X || res === Y) ? zero(res) : zero!(res) return fmac!(res, X, Y) end function fmac!(res::AlgebraElement, X::AlgebraElement, Y::AlgebraElement) + @assert parent(res) === parent(X) === parent(Y) fmac!(coeffs(res), coeffs(X), coeffs(Y), parent(res).mstructure) return res end @@ -91,9 +112,33 @@ function fmac!( ) @assert res !== X @assert res !== Y - for (j, y) in _nzpairs(Y) - for (i, x) in _nzpairs(X) - res[mstr[i, j]] += x * y + lx, ly = size(mstr) + @assert all(iszero, @view(X[lx+1:end])) + @assert all(iszero, @view(Y[ly+1:end])) + for iy in 1:ly + y = Y[iy] + iszero(y) && continue + for ix in 1:lx + x = X[ix] + iszero(x) && continue + res[mstr[ix, iy]] += X[ix] * y + end + end + return res +end + +function fmac!( + res::AbstractVector, + X::AbstractSparseVector, + Y::AbstractSparseVector, + mstr::MultiplicativeStructure, +) + @assert res !== X + @assert res !== Y + for iy in SparseArrays.nonzeroinds(Y) + y = Y[iy] + for ix in SparseArrays.nonzeroinds(X) + res[mstr[ix, iy]] += X[ix] * y end end return res diff --git a/src/mtables.jl b/src/mtables.jl index 41b7128..a29b7f0 100644 --- a/src/mtables.jl +++ b/src/mtables.jl @@ -31,7 +31,7 @@ end MTable{Tw}(mt::AbstractMatrix{<:Integer}) where {Tw} = MTable{eltype(mt),Tw,typeof(mt)}(mt) -MTable(b::AbstractBasis; table_size) = MTable{false}(b; table_size = table_size) +MTable(b::AbstractBasis; table_size) = MTable{false}(b; table_size=table_size) function MTable{Tw}(basis::AbstractBasis; table_size) where {Tw} @assert length(table_size) == 2 @@ -78,7 +78,7 @@ struct CachedMTable{T,I,B<:Basis{T,I},M,Twisted} <: AbstractMTable{I,Twisted} end CachedMTable(basis::AbstractBasis; table_size) = - CachedMTable{false}(basis; table_size = table_size) + CachedMTable{false}(basis; table_size=table_size) function CachedMTable{Tw}(basis::AbstractBasis{T,I}; table_size) where {Tw,T,I} return CachedMTable{Tw}(basis, zeros(I, table_size)) diff --git a/src/show.jl b/src/show.jl index 5a15086..f22be43 100644 --- a/src/show.jl +++ b/src/show.jl @@ -10,9 +10,9 @@ __needs_parens(a::AlgebraElement) = true function _coeff_elt_print(io, c, elt) print(io, c, "·") - __needs_parens(elt) && print(io, "(") + __needs_parens(elt) && print(io, '(') print(io, elt) - __needs_parens(elt) && print(io, ")") + __needs_parens(elt) && print(io, ')') return end @@ -33,10 +33,12 @@ function Base.show(io::IO, a::AlgebraElement) if counter == 1 _coeff_elt_print(io, c, elt) else - print(io, ' ') - __prints_with_minus(c) || print(io, '+') + if __prints_with_minus(c) + print(io, ' ') + else + print(io, ' ', '+') + end _coeff_elt_print(io, c, elt) - counter == length(nzeros) || print(io, ' ') end end else diff --git a/src/types.jl b/src/types.jl index e890f24..6daff1d 100644 --- a/src/types.jl +++ b/src/types.jl @@ -43,7 +43,7 @@ function StarAlgebra{Tw}( cache_size::Tuple{<:Integer,Integer}; precompute=false ) where {Tw} - mstr = CachedMTable{Tw}(basis, table_size = cache_size) + mstr = CachedMTable{Tw}(basis, table_size=cache_size) precompute && complete!(mstr) return StarAlgebra(obj, basis, mstr) end @@ -73,7 +73,7 @@ Base.eltype(a::AlgebraElement) = eltype(coeffs(a)) ### constructing elements -function Base.zero(A::AbstractStarAlgebra, T = Int) +function Base.zero(A::AbstractStarAlgebra, T=Int) if hasbasis(A) I = SparseArrays.indtype(basis(A)) return AlgebraElement(sparsevec(I[], T[], length(basis(A))), A) @@ -83,7 +83,7 @@ function Base.zero(A::AbstractStarAlgebra, T = Int) ) end -function Base.one(A::AbstractStarAlgebra, T = Int) +function Base.one(A::AbstractStarAlgebra, T=Int) hasbasis(A) && return A(one(object(A)), T) throw( "Algebra without basis; to construct one use the `AlgebraElement` constructor directly.", @@ -101,31 +101,29 @@ function Base.isone(a::AlgebraElement) isone(a[k]) || return false return isone(b[k]) end -let SA = @static VERSION < v"1.3.0" ? :StarAlgebra : :AbstractStarAlgebra - @eval begin - function (A::$SA{O,T})(elt::T, S = Int) where {O,T} - if hasbasis(A) - b = basis(A) - i = b[elt] - return AlgebraElement(sparsevec([i], [one(S)], length(b)), A) - else - throw("Algebra without basis: cannot coerce $elt.") - end +@eval begin + function (A::AbstractStarAlgebra{O,T})(elt::T, S=Int) where {O,T} + if hasbasis(A) + b = basis(A) + i = b[elt] + return AlgebraElement(sparsevec([i], [one(S)], length(b)), A) + else + throw("Algebra without basis: cannot coerce $elt.") end + end - function (A::$SA)(x::Number) - g = one(object(A)) - res = A(g, typeof(x)) - res[g] *= x - return res - end + function (A::AbstractStarAlgebra)(x::Number) + g = one(object(A)) + res = A(g, typeof(x)) + res[g] *= x + return res end end -Base.similar(X::AlgebraElement, ::Type{T} = eltype(X)) where {T} = +Base.similar(X::AlgebraElement, ::Type{T}=eltype(X)) where {T} = AlgebraElement(similar(coeffs(X), T), parent(X)) -function AlgebraElement{T}(X::AlgebraElement) where T +function AlgebraElement{T}(X::AlgebraElement) where {T} v = coeffs(X) w = similar(v, T) w .= v diff --git a/test/arithmetic.jl b/test/arithmetic.jl index a2c1996..7a9157f 100644 --- a/test/arithmetic.jl +++ b/test/arithmetic.jl @@ -1,16 +1,21 @@ using GroupsCore +using PermutationGroups import Random -include(joinpath(pathof(GroupsCore), "..", "..", "test", "cyclic.jl")) -StarAlgebras.star(g::GroupElement) = inv(g) +StarAlgebras.star(g::PermutationGroups.GroupElement) = inv(g) + +using SparseArrays +if VERSION < v"1.9" + Base.sum(v::SparseVector) = sum(nonzeros(v)) +end @testset "Arithmetic" begin - G = CyclicGroup(6) + G = PermGroup(perm"(1,2,3)", perm"(1,2)") b = StarAlgebras.Basis{UInt8}(collect(G)) l = length(b) RG = StarAlgebra(G, b, (l, l)) - @test sprint(show, RG) == "*-algebra of Group of residues modulo 6" + @test contains(sprint(show, RG), "*-algebra of Permutation group") @testset "Module structure" begin a = AlgebraElement(ones(Int, order(G)), RG) @@ -22,6 +27,11 @@ StarAlgebras.star(g::GroupElement) = inv(g) @test eltype(2 * a) == typeof(2) @test coeffs(2 * a) == 2coeffs(a) + @test eltype(2a) == Int + y = div(2a, 2) + @test y == a + @test eltype(y) == Int + @test 2.0 * a isa AlgebraElement @test eltype(2.0 * a) == typeof(2.0) @test coeffs(2.0 * a) == 2.0 * coeffs(a) @@ -44,17 +54,16 @@ StarAlgebras.star(g::GroupElement) = inv(g) @testset "Additive structure" begin a = AlgebraElement(ones(Int, order(G)), RG) - b = sum((-1)^isodd(g.residual) * RG(g) for g in G) + b = sum(sign(g) * RG(g) for g in G) @test a == AlgebraElement(ones(Int, order(G)), RG) == sum(RG(g) for g in G) - @test 1 / 2 * (a + b).coeffs == [1.0, 0.0, 1.0, 0.0, 1.0, 0.0] + @test 1 / 2 * (coeffs(a + b)) == [1.0, 0.0, 1.0, 0.0, 1.0, 0.0] - g = CyclicGroupElement(2, G) - h = CyclicGroupElement(3, G) - k = CyclicGroupElement(5, G) + g, h = gens(G) + k = g * h a = RG(1) + RG(g) + RG(h) b = RG(1) - RG(k) - RG(h) @@ -83,9 +92,8 @@ StarAlgebras.star(g::GroupElement) = inv(g) @test aug(one(RG) - RG(g)) == 0 end - g = CyclicGroupElement(2, G) - h = CyclicGroupElement(3, G) - k = CyclicGroupElement(5, G) + g, h = PermutationGroups.gens(G) + k = g * h a = RG(1) + RG(g) + RG(h) b = RG(1) - RG(k) - RG(h) @@ -95,9 +103,6 @@ StarAlgebras.star(g::GroupElement) = inv(g) norm(a)^2 ≈ LinearAlgebra.dot(coeffs(a), a) - # a = RG(1) + RG(perm"(2,3)") + RG(perm"(1,2,3)") - # b = RG(1) - RG(perm"(1,2)(3)") - RG(perm"(1,2,3)") - @test a * b == StarAlgebras.mul!(a, a, b) @test aug(a) == 3 @@ -107,47 +112,40 @@ StarAlgebras.star(g::GroupElement) = inv(g) z = sum((one(RG) - RG(g)) * star(one(RG) - RG(g)) for g in G) @test aug(z) == 0 - @test supp(z) == basis(parent(z)) + @test supp(z) == StarAlgebras.basis(parent(z)) @test supp(RG(1) + RG(g)) == [one(G), g] - @test supp(a) == [one(G), g, h] + @test supp(a) == [one(G), h, g] - if false - @testset "Projections in Symm(3)" begin - G = SymmetricGroup(3) - b = StarAlgebras.Basis{UInt8}(collect(G)) - l = length(b) + @testset "Projections in star algebras" begin + b = StarAlgebras.basis(RG) + l = length(b) + P = sum(RG(g) for g in b) // l + @test P * P == P - RG = StarAlgebra(G, b) - @test RG isa StarAlgebra + P3 = 2 * sum(RG(g) for g in b if sign(g) > 0) // l + @test P3 * P3 == P3 - P = sum(RG(g) for g in b) // l - @test P * P == P + PAlt = sum(sign(g) * RG(g) for g in b) // l + @test PAlt * PAlt == PAlt - P3 = 2 * sum(RG(g) for g in b if sign(g) > 0) // l - @test P3 * P3 == P3 + @test P3 * PAlt == PAlt * P3 - PAlt = sum(sign(g) * RG(g) for g in b) // l - @test PAlt * PAlt == PAlt + P2 = (RG(1) + RG(b[2])) // 2 + @test P2 * P2 == P2 - @test P3 * PAlt == PAlt * P3 + @test P2 * P3 == P3 * P2 == P - P2 = (RG(1) + RG(b[2])) // 2 - @test P2 * P2 == P2 + P2m = (RG(1) - RG(b[2])) // 2 + @test P2m * P2m == P2m - @test P2 * P3 == P3 * P2 == P - - P2m = (RG(1) - RG(b[2])) // 2 - @test P2m * P2m == P2m - - @test P2m * P3 == P3 * P2m == PAlt - @test iszero(P2m * P2) - end + @test P2m * P3 == P3 * P2m == PAlt + @test iszero(P2m * P2) end end @testset "Mutable API and trivial mstructure" begin A = [:a, :b, :c] - b = StarAlgebras.Basis{UInt16}(words(A, radius = 8)) + b = StarAlgebras.Basis{UInt16}(words(A, radius=8)) l = findfirst(w -> length(w) > 4, b) - 1 RG = StarAlgebra(one(first(b)), b) @@ -203,11 +201,83 @@ StarAlgebras.star(g::GroupElement) = inv(g) @test coeffs(2 * X * Y) == coeffs(StarAlgebras.mul!(W, W, 2)) end end + + @testset "mutable arithmetic" begin + A = [:a, :b, :c] + bas = StarAlgebras.Basis{UInt16}(words(A, radius=4)) + l = findfirst(w -> length(w) > 2, bas) - 1 + RG = StarAlgebra(one(first(bas)), bas, (l, l)) + + a = let c = rand(-3:3, l) + resize!(c, length(bas)) + c[l:end] .= 0 + AlgebraElement(c, RG) + end + b = let c = rand(-3:3, l) + resize!(c, length(bas)) + c[l:end] .= 0 + AlgebraElement(c, RG) + end + + let d = deepcopy(a) + StarAlgebras.zero!(d) + StarAlgebras.neg!(d, a) + + d = deepcopy(a) + @test !iszero(d) + @test @allocated(StarAlgebras.zero!(d)) == 0 + @test iszero(d) + + @test @allocated(StarAlgebras.neg!(d, a)) == 0 + @test d == -a + end + + let d = deepcopy(a) + StarAlgebras.add!(d, d, b) + StarAlgebras.add!(d, b, d) + StarAlgebras.add!(d, a, b) + + d = deepcopy(a) + @test @allocated(StarAlgebras.add!(d, d, b)) == 0 + @test d == a + b + + d = deepcopy(a) + @test @allocated(StarAlgebras.add!(d, b, d)) == 0 + @test d == a + b + + @test @allocated(StarAlgebras.add!(d, a, b)) == 0 + @test d == a + b + end + + let d = deepcopy(a) + StarAlgebras.mul!(d, d, 2) + StarAlgebras.mul!(d, a, 2) + StarAlgebras.mul!(d, a, b) + d = deepcopy(a) + StarAlgebras.mul!(d, d, b) + + d = deepcopy(a) + @test @allocated(StarAlgebras.mul!(d, d, 2)) == 0 + @test d == 2a + + @test @allocated(StarAlgebras.mul!(d, a, 2)) == 0 + @test d == 2a + + @test @allocated(StarAlgebras.mul!(d, a, b)) == 32 + @test d == a * b + + d = deepcopy(a) + @test @allocated(StarAlgebras.mul!(d, d, b)) != 0 + z = StarAlgebras.mul!(d, d, b) + @test z == a * b + @test z !== d + end + end end @testset "Group Algebra caching" begin A = [:a, :b, :c] - b = StarAlgebras.Basis{UInt8}(words(A, radius = 4)) + b = StarAlgebras.Basis{UInt8}(words(A, radius=4)) k = findfirst(w -> length(w) == 3, b) - 1 RG = StarAlgebra(Word(A, Int[]), b, (k, k)) @@ -240,6 +310,6 @@ end @test all(!iszero, RG.mstructure.table) - RG = StarAlgebra(Word(A, Int[]), b, (k, k), precompute = true) + RG = StarAlgebra(Word(A, Int[]), b, (k, k), precompute=true) @test all(!iszero, RG.mstructure.table) end diff --git a/test/constructors.jl b/test/constructors.jl index 4104d1f..edc9a50 100644 --- a/test/constructors.jl +++ b/test/constructors.jl @@ -1,6 +1,6 @@ @testset "Algebra and Elements" begin A = [:a, :b, :c] - b = StarAlgebras.Basis{UInt8}(words(A, radius = 2)) + b = StarAlgebras.Basis{UInt8}(words(A, radius=2)) l = length(b) RG = StarAlgebra(one(first(b)), b, (4, 4)) @@ -72,6 +72,17 @@ z[b[s]] = 2 @test AlgebraElement(z, RG) == a @test sprint(show, AlgebraElement(z, RG)) == "2.0·(id) +1.0·b·c" + @test sprint(show, 2one(RG) - RG(p)) == "2·(id) -1·b·c" @test LinearAlgebra.norm(a, 1) == 3 + + @test copy(a) == a + @test copy(a) !== a + @test coeffs(copy(a)) !== coeffs(a) + @test parent(copy(a)) === parent(a) + + @test deepcopy(a) == a + @test deepcopy(a) !== a + @test coeffs(deepcopy(a)) !== coeffs(a) + @test parent(deepcopy(a)) === parent(a) end diff --git a/test/mtables.jl b/test/mtables.jl index 43bfad9..21378ca 100644 --- a/test/mtables.jl +++ b/test/mtables.jl @@ -1,5 +1,5 @@ @testset "TrivialMStructure" begin - b = StarAlgebras.Basis{UInt8}(words([:a, :b, :c], radius = 4)) + b = StarAlgebras.Basis{UInt8}(words([:a, :b, :c], radius=4)) k = findfirst(w -> length(w) == 3, b) - 1 mstr = StarAlgebras.TrivialMStructure{false}(b) @@ -35,10 +35,10 @@ end @testset "MTable" begin - b = StarAlgebras.Basis{UInt16}(words([:a, :b, :c, :d], radius = 4)) + b = StarAlgebras.Basis{UInt16}(words([:a, :b, :c, :d], radius=4)) k = findfirst(w -> length(w) == 3, b) - 1 - mstr = StarAlgebras.MTable(b, table_size = (k, k)) + mstr = StarAlgebras.MTable(b, table_size=(k, k)) @test mstr isa StarAlgebras.MTable{UInt16,false} @@ -46,7 +46,7 @@ end @test all(mstr[1, i] == i for i in 1:size(mstr, 2)) @test all(mstr[i, 1] == i for i in 1:size(mstr, 1)) - tmstr = StarAlgebras.MTable{true}(b, table_size = (k, k)) + tmstr = StarAlgebras.MTable{true}(b, table_size=(k, k)) @test tmstr isa StarAlgebras.MTable{UInt16,true} @test all(tmstr[i, i] != 1 for i in 2:size(tmstr, 1)) @@ -55,13 +55,13 @@ end end @testset "CachedMTable" begin - b = StarAlgebras.Basis{UInt8}(words([:a, :b, :c], radius = 4)) + b = StarAlgebras.Basis{UInt8}(words([:a, :b, :c], radius=4)) k = findfirst(w -> length(w) == 3, b) - 1 - @test StarAlgebras.CachedMTable(b, table_size = (k, k)) isa + @test StarAlgebras.CachedMTable(b, table_size=(k, k)) isa StarAlgebras.CachedMTable{Word{Symbol},UInt8,typeof(b),Matrix{UInt8},false} - @test StarAlgebras.CachedMTable{true}(b, table_size = (k, k)) isa + @test StarAlgebras.CachedMTable{true}(b, table_size=(k, k)) isa StarAlgebras.CachedMTable{Word{Symbol},UInt8,typeof(b),Matrix{UInt8},true} @test StarAlgebras.CachedMTable(b, spzeros(UInt8, k, k)) isa StarAlgebras.CachedMTable{ @@ -82,7 +82,7 @@ end } for mstr in [ - StarAlgebras.CachedMTable{false}(b, table_size = (k, k)), + StarAlgebras.CachedMTable{false}(b, table_size=(k, k)), StarAlgebras.CachedMTable{true}(b, spzeros(UInt8, k, k)), ] @@ -106,7 +106,7 @@ end @test_throws StarAlgebras.ProductNotDefined mstr[k+1, k] end - tmstr = StarAlgebras.CachedMTable{true}(b, table_size = (k, k)) + tmstr = StarAlgebras.CachedMTable{true}(b, table_size=(k, k)) @test all(iszero, tmstr.table) @test tmstr[1, 2] == 2 diff --git a/test/runtests.jl b/test/runtests.jl index b07d26d..01cb81c 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -10,9 +10,5 @@ include("test_example_words.jl") include("constructors.jl") include("arithmetic.jl") - if VERSION >= v"1.3.0" - using Pkg - Pkg.add("Groups") - include("sum_of_squares.jl") - end + include("sum_of_squares.jl") end diff --git a/test/sum_of_squares.jl b/test/sum_of_squares.jl index 2c5e61f..3512a6d 100644 --- a/test/sum_of_squares.jl +++ b/test/sum_of_squares.jl @@ -7,12 +7,12 @@ using Groups ID = one(F) RADIUS = 3 - @time E_R, sizes = Groups.wlmetric_ball(S, ID, radius = 2 * RADIUS) + @time E_R, sizes = Groups.wlmetric_ball(S, ID, radius=2 * RADIUS) @test sizes == [9, 65, 457, 3201, 22409, 156865] b = StarAlgebras.Basis{UInt32}(E_R) - tmstr = StarAlgebras.MTable{true}(b, table_size = (sizes[RADIUS], sizes[RADIUS])) + tmstr = StarAlgebras.MTable{true}(b, table_size=(sizes[RADIUS], sizes[RADIUS])) RG = StarAlgebra(F, b, tmstr) @@ -25,8 +25,6 @@ using Groups @test star(G * G) == G * G @testset "Sums of hermitian squares" begin - ∗ = StarAlgebras.star - 𝕀 = one(RG) G = (𝕀 - RG(g)) @@ -36,71 +34,71 @@ using Groups GH = (𝕀 - RG(g * h)) KL = (𝕀 - RG(k * l)) - X = (2𝕀 - ∗(RG(g)) - RG(h)) - Y = (2𝕀 - ∗(RG(g * h)) - RG(k)) + X = (2𝕀 - star(RG(g)) - RG(h)) + Y = (2𝕀 - star(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))) == 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))) + + @test -(2𝕀 - RG(g * h) - star(RG(g * h))) + 2G^2 + 2H^2 == X^2 + @test (2𝕀 - RG(g * h) - star(RG(g * h))) == GH^2 + @test -(2𝕀 - RG(g * h * k) - star(RG(g * h * k))) + 2GH^2 + 2K^2 == Y^2 + @test -(2𝕀 - RG(g * h * k) - star(RG(g * h * k))) + 2(GH^2 - 2G^2 - 2H^2) + 4G^2 + 4H^2 + 2K^2 == Y^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) - star(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 KL^2 == 2K^2 + 2L^2 - (2𝕀 - ∗(RG(k)) - RG(l))^2 + @test GH^2 == 2G^2 + 2H^2 - (2𝕀 - star(RG(g)) - RG(h))^2 + @test KL^2 == 2K^2 + 2L^2 - (2𝕀 - star(RG(k)) - RG(l))^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 + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + 2 * GH^2 + 2 * KL^2 == + (2𝕀 - star(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𝕀 - ∗(RG(g)) - RG(h))^2) + - 2(2K^2 + 2L^2 - (2𝕀 - ∗(RG(k)) - RG(l))^2) == - (2𝕀 - ∗(RG(g * h)) - RG(k * l))^2 + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + + 2(2G^2 + 2H^2 - (2𝕀 - star(RG(g)) - RG(h))^2) + + 2(2K^2 + 2L^2 - (2𝕀 - star(RG(k)) - RG(l))^2) == + (2𝕀 - star(RG(g * h)) - RG(k * l))^2 - @test -(2𝕀 - ∗(RG(g * h * k * l)) - RG(g * h * k * l)) + + @test -(2𝕀 - star(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(g)) - RG(h))^2 + - 2(2𝕀 - ∗(RG(k)) - RG(l))^2 + (2𝕀 - star(RG(g * h)) - RG(k * l))^2 + + 2(2𝕀 - star(RG(g)) - RG(h))^2 + + 2(2𝕀 - star(RG(k)) - RG(l))^2 - @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𝕀 - ∗(RG(g * h * k)) - RG(l))^2 + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + + 2(2𝕀 - star(RG(g * h * k)) - RG(g * h * k)) + + 2L^2 == (2𝕀 - star(RG(g * h * k)) - RG(l))^2 - @test 2𝕀 - ∗(RG(g * h * k)) - RG(g * h * k) == - 2GH^2 + 2K^2 - (2𝕀 - ∗(RG(g * h)) - RG(k))^2 + @test 2𝕀 - star(RG(g * h * k)) - RG(g * h * k) == + 2GH^2 + 2K^2 - (2𝕀 - star(RG(g * h)) - RG(k))^2 - @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𝕀 - ∗(RG(g * h * k)) - RG(l))^2 + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + + 2(2GH^2 + 2K^2 - (2𝕀 - star(RG(g * h)) - RG(k))^2) + + 2L^2 == (2𝕀 - star(RG(g * h * k)) - RG(l))^2 - @test -(2𝕀 - ∗(RG(g * h * k * l)) - RG(g * h * k * l)) + 2(2GH^2 + 2K^2) + 2L^2 == - (2𝕀 - ∗(RG(g * h * k)) - RG(l))^2 + 2(2𝕀 - ∗(RG(g * h)) - RG(k))^2 + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + 2(2GH^2 + 2K^2) + 2L^2 == + (2𝕀 - star(RG(g * h * k)) - RG(l))^2 + 2(2𝕀 - star(RG(g * h)) - RG(k))^2 - @test -(2𝕀 - ∗(RG(g * h * k * l)) - RG(g * h * k * l)) + + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + 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𝕀 - star(RG(g * h * k)) - RG(l))^2 + + 2(2𝕀 - star(RG(g * h)) - RG(k))^2 + + 4(2𝕀 - star(RG(g)) - RG(h))^2 - @test -(2𝕀 - ∗(RG(g * h * k * l)) - RG(g * h * k * l)) + 2GH^2 + 2KL^2 == - (2𝕀 - ∗(RG(g * h)) - RG(k * l))^2 + @test -(2𝕀 - star(RG(g * h * k * l)) - RG(g * h * k * l)) + 2GH^2 + 2KL^2 == + (2𝕀 - star(RG(g * h)) - RG(k * l))^2 - @test -(2𝕀 - ∗(RG(g * h * k * l)) - RG(g * h * k * l)) + + @test -(2𝕀 - star(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𝕀 - star(RG(g * h)) - RG(k * l))^2 + + 2(2𝕀 - star(RG(k)) - RG(l))^2 + + 2(2𝕀 - star(RG(g)) - RG(h))^2 end end diff --git a/test/test_example_words.jl b/test/test_example_words.jl index 4697b9a..fc327ce 100644 --- a/test/test_example_words.jl +++ b/test/test_example_words.jl @@ -30,20 +30,15 @@ end function StarAlgebras.star(w::Word) newletters = similar(w.letters) - A = w.alphabet # star(:a) = :b # star(:b) = :a # star(:c) = :c + star_d = Dict(1 => 2, 2 => 1) + for (i, l) in enumerate(Iterators.reverse(w.letters)) - k = if A[l] === :a - 2 - elseif A[l] === :b - 1 - else - l - end + k = haskey(star_d, l) ? star_d[l] : l newletters[i] = k end return Word(w.alphabet, newletters)