Compare commits

...

10 Commits

Author SHA1 Message Date
Marek Kaluba d3873e1b3a
Merge pull request #13 from kalmarek/mk/update_PermutationGroups_etal
update permutation groups etal
2024-02-18 17:57:28 +01:00
Marek Kaluba cd90e072c4
back to IntervalArithmetic-0.20 to keep julia-1.6 2024-02-16 12:09:11 +01:00
Marek Kaluba 83fdd313c6
bump to PropertyT to 0.6 2024-02-15 22:48:14 +01:00
Marek Kaluba 92a19f8566
no longer use "FULL_TEST" ENV variable 2024-02-15 22:47:55 +01:00
Marek Kaluba 681d93ce58
the order of characters has changed 2024-02-15 22:46:52 +01:00
Marek Kaluba 3a954cdfbd
the order of roots has changed 2024-02-15 22:45:55 +01:00
Marek Kaluba d3975790f2
tweaking solvers parameters in tests 2024-02-15 22:45:21 +01:00
Marek Kaluba c9f68eee8f
update IntervalArithmetic to 0.21 2024-02-15 22:44:23 +01:00
Marek Kaluba 27ce603872
import packages as ... instead of using
This includes:
* PermutationGroups as PG
* SymbolicWedderburn as SW
* StarAlgebras as SA
2024-02-15 22:42:17 +01:00
Marek Kaluba b23975a627
update and fix versions for dependencies
i.e. PermutationGroups, GroupsCore, SymbolicWedderburn
2024-02-14 11:00:05 +01:00
21 changed files with 316 additions and 287 deletions

View File

@ -1,29 +1,35 @@
name = "PropertyT" name = "PropertyT"
uuid = "03b72c93-0167-51e2-8a1e-eb4ff1fb940d" uuid = "03b72c93-0167-51e2-8a1e-eb4ff1fb940d"
authors = ["Marek Kaluba <kalmar@amu.edu.pl>"] authors = ["Marek Kaluba <kalmar@amu.edu.pl>"]
version = "0.5.0" version = "0.6.0"
[deps] [deps]
Groups = "5d8bd718-bd84-11e8-3b40-ad14f4a32557" Groups = "5d8bd718-bd84-11e8-3b40-ad14f4a32557"
GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"
IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253" IntervalArithmetic = "d1acc4aa-44c8-5952-acd4-ba5d80a2a253"
IntervalMatrices = "5c1f47dc-42dd-5697-8aaa-4d102d140ba9" IntervalMatrices = "5c1f47dc-42dd-5697-8aaa-4d102d140ba9"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572" JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e" LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
PermutationGroups = "8bc5a954-2dfc-11e9-10e6-cd969bffa420"
ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca" ProgressMeter = "92933f4c-e287-5a05-a399-4b506db050ca"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf" SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
StarAlgebras = "0c0c59c1-dc5f-42e9-9a8b-b5dc384a6cd1"
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182" StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
SymbolicWedderburn = "858aa9a9-4c7c-4c62-b466-2421203962a2" SymbolicWedderburn = "858aa9a9-4c7c-4c62-b466-2421203962a2"
[compat] [compat]
COSMO = "0.8" COSMO = "0.8"
Groups = "0.7" Groups = "0.8"
GroupsCore = "0.5"
IntervalArithmetic = "0.20" IntervalArithmetic = "0.20"
IntervalMatrices = "0.8" IntervalMatrices = "0.10"
JuMP = "1.3" JuMP = ">=1.3"
PermutationGroups = "0.6.2"
ProgressMeter = "1.7" ProgressMeter = "1.7"
SCS = "1.1" SCS = "2"
StarAlgebras = "0.2.1"
StaticArrays = "1" StaticArrays = "1"
SymbolicWedderburn = "0.3.4" SymbolicWedderburn = "0.4"
julia = "1.6" julia = "1.6"
[extras] [extras]

View File

@ -6,10 +6,10 @@ using SparseArrays
using JuMP using JuMP
using Groups using Groups
import Groups.GroupsCore import GroupsCore
using SymbolicWedderburn import PermutationGroups as PG
import SymbolicWedderburn.StarAlgebras import SymbolicWedderburn as SW
import SymbolicWedderburn.PermutationGroups import StarAlgebras as SA
include("constraint_matrix.jl") include("constraint_matrix.jl")
include("sos_sdps.jl") include("sos_sdps.jl")
@ -31,9 +31,9 @@ function group_algebra(G::Groups.Group, S = gens(G); halfradius::Integer)
@time E, sizes = Groups.wlmetric_ball(S; radius = 2halfradius) @time E, sizes = Groups.wlmetric_ball(S; radius = 2halfradius)
@info "sizes = $(sizes)" @info "sizes = $(sizes)"
@info "computing the *-algebra structure for G" @info "computing the *-algebra structure for G"
@time RG = StarAlgebras.StarAlgebra( @time RG = SA.StarAlgebra(
G, G,
StarAlgebras.Basis{UInt32}(E), SA.Basis{UInt32}(E),
(sizes[halfradius], sizes[halfradius]); (sizes[halfradius], sizes[halfradius]);
precompute = false, precompute = false,
) )

View File

@ -1,29 +1,24 @@
import SymbolicWedderburn.action
include("alphabet_permutation.jl") include("alphabet_permutation.jl")
include("sln_conjugation.jl") include("sln_conjugation.jl")
include("spn_conjugation.jl") include("spn_conjugation.jl")
include("autfn_conjugation.jl") include("autfn_conjugation.jl")
function SymbolicWedderburn.action( function SW.action(
act::SymbolicWedderburn.ByPermutations, act::SW.ByPermutations,
g::Groups.GroupElement, g::Groups.GroupElement,
α::StarAlgebras.AlgebraElement, α::SA.AlgebraElement,
) )
res = StarAlgebras.zero!(similar(α)) res = SA.zero!(similar(α))
B = basis(parent(α)) B = SA.basis(parent(α))
for (idx, val) in StarAlgebras._nzpairs(StarAlgebras.coeffs(α)) for (idx, val) in SA._nzpairs(SA.coeffs(α))
a = B[idx] a = B[idx]
a_g = SymbolicWedderburn.action(act, g, a) a_g = SW.action(act, g, a)
res[a_g] += val res[a_g] += val
end end
return res return res
end end
function Base.:^( function Base.:^(w::W, p::PG.AbstractPermutation) where {W<:Groups.AbstractWord}
w::W,
p::PermutationGroups.AbstractPerm,
) where {W<:Groups.AbstractWord}
return W([l^p for l in w]) return W([l^p for l in w])
end end

View File

@ -2,43 +2,37 @@
import Groups: Constructions import Groups: Constructions
struct AlphabetPermutation{GEl,I} <: SymbolicWedderburn.ByPermutations struct AlphabetPermutation{GEl,I} <: SW.ByPermutations
perms::Dict{GEl,PermutationGroups.Perm{I}} perms::Dict{GEl,PG.Perm{I}}
end end
function AlphabetPermutation( function AlphabetPermutation(
A::Alphabet, A::Alphabet,
Γ::PermutationGroups.AbstractPermutationGroup, Γ::PG.AbstractPermutationGroup,
op, op,
) )
return AlphabetPermutation( return AlphabetPermutation(
Dict(γ => inv(PermutationGroups.Perm([A[op(l, γ)] for l in A])) for γ in Γ), Dict(γ => inv(PG.Perm([A[op(l, γ)] for l in A])) for γ in Γ),
) )
end end
function AlphabetPermutation(A::Alphabet, W::Constructions.WreathProduct, op) function AlphabetPermutation(A::Alphabet, W::Constructions.WreathProduct, op)
return AlphabetPermutation( return AlphabetPermutation(
Dict( Dict(
w => inv(PermutationGroups.Perm([A[op(op(l, w.p), w.n)] for l in A])) for w => inv(PG.Perm([A[op(op(l, w.p), w.n)] for l in A])) for
w in W w in W
), ),
) )
end end
function SymbolicWedderburn.action( function SW.action(
act::AlphabetPermutation, act::AlphabetPermutation,
γ::Groups.GroupElement, γ::Groups.GroupElement,
g::Groups.AbstractFPGroupElement, g::Groups.AbstractFPGroupElement,
) )
G = parent(g) G = parent(g)
w = SymbolicWedderburn.action(act, γ, word(g)) # w = SW.action(act, γ, word(g))
w = word(g)^(act.perms[γ])
return G(w) return G(w)
end end
function SymbolicWedderburn.action(
act::AlphabetPermutation,
γ::Groups.GroupElement,
w::Groups.AbstractWord,
)
return w^(act.perms[γ])
end

View File

@ -2,7 +2,7 @@
function _conj( function _conj(
t::Groups.Transvection, t::Groups.Transvection,
σ::PermutationGroups.AbstractPerm, σ::PG.AbstractPermutation,
) )
return Groups.Transvection(t.id, t.i^inv(σ), t.j^inv(σ), t.inv) return Groups.Transvection(t.id, t.i^inv(σ), t.j^inv(σ), t.inv)
end end
@ -22,5 +22,9 @@ function _conj(
return _flip(t, x.elts[i]) return _flip(t, x.elts[i])
end end
action_by_conjugation(sautfn::Groups.AutomorphismGroup{<:Groups.FreeGroup}, Σ::Groups.Group) = function action_by_conjugation(
AlphabetPermutation(alphabet(sautfn), Σ, _conj) sautfn::Groups.AutomorphismGroup{<:Groups.FreeGroup},
Σ::Groups.Group,
)
return AlphabetPermutation(alphabet(sautfn), Σ, _conj)
end

View File

@ -2,7 +2,7 @@
function _conj( function _conj(
t::MatrixGroups.ElementaryMatrix{N}, t::MatrixGroups.ElementaryMatrix{N},
σ::PermutationGroups.AbstractPerm, σ::PG.AbstractPermutation,
) where {N} ) where {N}
return MatrixGroups.ElementaryMatrix{N}(t.i^inv(σ), t.j^inv(σ), t.val) return MatrixGroups.ElementaryMatrix{N}(t.i^inv(σ), t.j^inv(σ), t.val)
end end
@ -16,5 +16,9 @@ function _conj(
return ifelse(just_one_flips, inv(t), t) return ifelse(just_one_flips, inv(t), t)
end end
action_by_conjugation(sln::Groups.MatrixGroups.SpecialLinearGroup, Σ::Groups.Group) = function action_by_conjugation(
AlphabetPermutation(alphabet(sln), Σ, _conj) sln::Groups.MatrixGroups.SpecialLinearGroup,
Σ::Groups.Group,
)
return AlphabetPermutation(alphabet(sln), Σ, _conj)
end

View File

@ -2,10 +2,10 @@
function _conj( function _conj(
s::MatrixGroups.ElementarySymplectic{N,T}, s::MatrixGroups.ElementarySymplectic{N,T},
σ::PermutationGroups.AbstractPerm, σ::PG.AbstractPermutation,
) where {N,T} ) where {N,T}
@assert iseven(N) @assert iseven(N)
@assert PermutationGroups.degree(σ) == N ÷ 2 "Got degree = $(PermutationGroups.degree(σ)); N = $N" @assert PG.degree(σ) N ÷ 2 "Got degree = $(PG.degree(σ)); N = $N"
n = N ÷ 2 n = N ÷ 2
@assert 1 s.i N @assert 1 s.i N
@assert 1 s.j N @assert 1 s.j N
@ -40,5 +40,9 @@ function _conj(
return ifelse(just_one_flips, inv(s), s) return ifelse(just_one_flips, inv(s), s)
end end
action_by_conjugation(sln::Groups.MatrixGroups.SymplecticGroup, Σ::Groups.Group) = function action_by_conjugation(
AlphabetPermutation(alphabet(sln), Σ, _conj) sln::Groups.MatrixGroups.SymplecticGroup,
Σ::Groups.Group,
)
return AlphabetPermutation(alphabet(sln), Σ, _conj)
end

View File

@ -9,16 +9,16 @@ function augment_columns!(Q::AbstractMatrix)
end end
function __sos_via_sqr!( function __sos_via_sqr!(
res::StarAlgebras.AlgebraElement, res::SA.AlgebraElement,
P::AbstractMatrix; P::AbstractMatrix;
augmented::Bool, augmented::Bool,
id = (b = basis(parent(res)); b[one(first(b))]), id = (b = SA.basis(parent(res)); b[one(first(b))]),
) )
A = parent(res) A = parent(res)
mstr = A.mstructure mstr = A.mstructure
@assert size(mstr) == size(P) @assert size(mstr) == size(P)
StarAlgebras.zero!(res) SA.zero!(res)
for j in axes(mstr, 2) for j in axes(mstr, 2)
for i in axes(mstr, 1) for i in axes(mstr, 1)
p = P[i, j] p = P[i, j]
@ -39,11 +39,11 @@ function __sos_via_sqr!(
end end
function __sos_via_cnstr!( function __sos_via_cnstr!(
res::StarAlgebras.AlgebraElement, res::SA.AlgebraElement,
::AbstractMatrix, ::AbstractMatrix,
cnstrs, cnstrs,
) )
StarAlgebras.zero!(res) SA.zero!(res)
for (g, A_g) in cnstrs for (g, A_g) in cnstrs
res[g] = dot(A_g, ) res[g] = dot(A_g, )
end end
@ -51,17 +51,17 @@ function __sos_via_cnstr!(
end end
function compute_sos( function compute_sos(
A::StarAlgebras.StarAlgebra, A::SA.StarAlgebra,
Q::AbstractMatrix; Q::AbstractMatrix;
augmented::Bool, augmented::Bool,
) )
= Q' * Q = Q' * Q
res = StarAlgebras.AlgebraElement(zeros(eltype(), length(basis(A))), A) res = SA.AlgebraElement(zeros(eltype(), length(SA.basis(A))), A)
res = __sos_via_sqr!(res, ; augmented = augmented) res = __sos_via_sqr!(res, ; augmented = augmented)
return res return res
end end
function sufficient_λ(residual::StarAlgebras.AlgebraElement, λ; halfradius) function sufficient_λ(residual::SA.AlgebraElement, λ; halfradius)
L1_norm = norm(residual, 1) L1_norm = norm(residual, 1)
suff_λ = λ - 2.0^(2ceil(log2(halfradius))) * L1_norm suff_λ = λ - 2.0^(2ceil(log2(halfradius))) * L1_norm
@ -77,8 +77,10 @@ function sufficient_λ(residual::StarAlgebras.AlgebraElement, λ; halfradius)
info_strs = [ info_strs = [
"Numerical metrics of the obtained SOS:", "Numerical metrics of the obtained SOS:",
"ɛ(elt - λu - ∑ξᵢ*ξᵢ) $eq_sign $(StarAlgebras.aug(residual))", "ɛ(elt - λu - ∑ξᵢ*ξᵢ) $eq_sign " *
"‖elt - λu - ∑ξᵢ*ξᵢ‖₁ $eq_sign $(L1_norm)", sprint(show, SA.aug(residual); context = :compact => true),
"‖elt - λu - ∑ξᵢ*ξᵢ‖₁ $eq_sign " *
sprint(show, L1_norm; context = :compact => true),
" λ $eq_sign $suff_λ", " λ $eq_sign $suff_λ",
] ]
@info join(info_strs, "\n") @info join(info_strs, "\n")
@ -87,10 +89,10 @@ function sufficient_λ(residual::StarAlgebras.AlgebraElement, λ; halfradius)
end end
function sufficient_λ( function sufficient_λ(
elt::StarAlgebras.AlgebraElement, elt::SA.AlgebraElement,
order_unit::StarAlgebras.AlgebraElement, order_unit::SA.AlgebraElement,
λ, λ,
sos::StarAlgebras.AlgebraElement; sos::SA.AlgebraElement;
halfradius, halfradius,
) )
@assert parent(elt) === parent(order_unit) == parent(sos) @assert parent(elt) === parent(order_unit) == parent(sos)
@ -100,16 +102,15 @@ function sufficient_λ(
end end
function certify_solution( function certify_solution(
elt::StarAlgebras.AlgebraElement, elt::SA.AlgebraElement,
orderunit::StarAlgebras.AlgebraElement, orderunit::SA.AlgebraElement,
λ, λ,
Q::AbstractMatrix{<:AbstractFloat}; Q::AbstractMatrix{<:AbstractFloat};
halfradius, halfradius,
augmented = iszero(StarAlgebras.aug(elt)) && augmented = iszero(SA.aug(elt)) && iszero(SA.aug(orderunit)),
iszero(StarAlgebras.aug(orderunit)),
) )
should_we_augment = should_we_augment =
!augmented && StarAlgebras.aug(elt) == StarAlgebras.aug(orderunit) == 0 !augmented && SA.aug(elt) == SA.aug(orderunit) == 0
Q = should_we_augment ? augment_columns!(Q) : Q Q = should_we_augment ? augment_columns!(Q) : Q
@time sos = compute_sos(parent(elt), Q; augmented = augmented) @time sos = compute_sos(parent(elt), Q; augmented = augmented)
@ -122,10 +123,8 @@ function certify_solution(
return false, λ_flpoint return false, λ_flpoint
end end
λ_int = IntervalArithmetic.@interval(λ) λ_int = IntervalArithmetic.interval(λ)
Q_int = IntervalMatrices.IntervalMatrix([ Q_int = IntervalMatrices.IntervalMatrix(IntervalArithmetic.interval.(Q))
IntervalArithmetic.@interval(q) for q in Q
])
check, sos_int = @time if should_we_augment check, sos_int = @time if should_we_augment
@info("Projecting columns of Q to the augmentation ideal...") @info("Projecting columns of Q to the augmentation ideal...")

View File

@ -147,13 +147,13 @@ function LinearAlgebra.dot(cm::ConstraintMatrix, m::AbstractMatrix{T}) where {T}
return convert(eltype(cm), cm.val) * (pos - neg) return convert(eltype(cm), cm.val) * (pos - neg)
end end
function constraints(A::StarAlgebras.StarAlgebra; augmented::Bool) function constraints(A::SA.StarAlgebra; augmented::Bool)
return constraints(basis(A), A.mstructure; augmented = augmented) return constraints(SA.basis(A), A.mstructure; augmented = augmented)
end end
function constraints( function constraints(
basis::StarAlgebras.AbstractBasis, basis::SA.AbstractBasis,
mstr::StarAlgebras.MultiplicativeStructure; mstr::SA.MultiplicativeStructure;
augmented = false, augmented = false,
) )
cnstrs = _constraints( cnstrs = _constraints(
@ -170,7 +170,7 @@ function constraints(
end end
function _constraints( function _constraints(
mstr::StarAlgebras.MultiplicativeStructure; mstr::SA.MultiplicativeStructure;
augmented::Bool = false, augmented::Bool = false,
num_constraints = maximum(mstr), num_constraints = maximum(mstr),
id, id,

View File

@ -37,7 +37,7 @@ function _groupby(keys::AbstractVector{K}, vals::AbstractVector{V}) where {K,V}
return d return d
end end
function laplacians(RG::StarAlgebras.StarAlgebra, S, grading) function laplacians(RG::SA.StarAlgebra, S, grading)
d = _groupby(grading, S) d = _groupby(grading, S)
Δs = Dict(α => RG(length(Sα)) - sum(RG(s) for s in Sα) for (α, Sα) in d) Δs = Dict(α => RG(length(Sα)) - sum(RG(s) for s in Sα) for (α, Sα) in d)
return Δs return Δs

View File

@ -1,16 +1,18 @@
__outer_dim(wd::WedderburnDecomposition) = size(first(direct_summands(wd)), 2) function __outer_dim(wd::SW.WedderburnDecomposition)
return size(first(SW.direct_summands(wd)), 2)
end
function __group_of(wd::WedderburnDecomposition) function __group_of(wd::SW.WedderburnDecomposition)
# this is veeeery hacky... ;) # this is veeeery hacky... ;)
return parent(first(keys(wd.hom.cache))) return parent(first(keys(wd.hom.cache)))
end end
function reconstruct( function reconstruct(
Ms::AbstractVector{<:AbstractMatrix}, Ms::AbstractVector{<:AbstractMatrix},
wbdec::WedderburnDecomposition, wbdec::SW.WedderburnDecomposition,
) )
n = __outer_dim(wbdec) n = __outer_dim(wbdec)
res = sum(zip(Ms, SymbolicWedderburn.direct_summands(wbdec))) do (M, ds) res = sum(zip(Ms, SW.direct_summands(wbdec))) do (M, ds)
res = similar(M, n, n) res = similar(M, n, n)
res = _reconstruct!(res, M, ds) res = _reconstruct!(res, M, ds)
return res return res
@ -22,12 +24,12 @@ end
function _reconstruct!( function _reconstruct!(
res::AbstractMatrix, res::AbstractMatrix,
M::AbstractMatrix, M::AbstractMatrix,
ds::SymbolicWedderburn.DirectSummand, ds::SW.DirectSummand,
) )
res .= zero(eltype(res)) res .= zero(eltype(res))
if !iszero(M) if !iszero(M)
U = SymbolicWedderburn.image_basis(ds) U = SW.image_basis(ds)
d = SymbolicWedderburn.degree(ds) d = SW.degree(ds)
res = (U' * M * U) .* d res = (U' * M * U) .* d
end end
return res return res
@ -47,15 +49,15 @@ function average!(
res::AbstractMatrix, res::AbstractMatrix,
M::AbstractMatrix, M::AbstractMatrix,
G::Groups.Group, G::Groups.Group,
hom::SymbolicWedderburn.InducedActionHomomorphism{ hom::SW.InducedActionHomomorphism{
<:SymbolicWedderburn.ByPermutations, <:SW.ByPermutations,
}, },
) )
res .= zero(eltype(res)) res .= zero(eltype(res))
@assert size(M) == size(res) @assert size(M) == size(res)
o = Groups.order(Int, G) o = Groups.order(Int, G)
for g in G for g in G
p = SymbolicWedderburn.induce(hom, g) p = SW.induce(hom, g)
Threads.@threads for c in axes(res, 2) Threads.@threads for c in axes(res, 2)
for r in axes(res, 1) for r in axes(res, 1)
if !iszero(M[r, c]) if !iszero(M[r, c])

View File

@ -5,8 +5,8 @@ Formulate the dual to the sum of squares decomposition problem for `X - λ·u`.
See also [sos_problem_primal](@ref). See also [sos_problem_primal](@ref).
""" """
function sos_problem_dual( function sos_problem_dual(
elt::StarAlgebras.AlgebraElement, elt::SA.AlgebraElement,
order_unit::StarAlgebras.AlgebraElement = zero(elt); order_unit::SA.AlgebraElement = zero(elt);
lower_bound = -Inf, lower_bound = -Inf,
) )
@assert parent(elt) == parent(order_unit) @assert parent(elt) == parent(order_unit)
@ -20,7 +20,7 @@ function sos_problem_dual(
# Symmetrized: # Symmetrized:
# 1 dual variable for every orbit of G acting on basis # 1 dual variable for every orbit of G acting on basis
model = Model() model = Model()
JuMP.@variable(model, y[1:length(basis(algebra))]) JuMP.@variable(model, y[1:length(SA.basis(algebra))])
JuMP.@constraint(model, λ_dual, dot(order_unit, y) == 1) JuMP.@constraint(model, λ_dual, dot(order_unit, y) == 1)
JuMP.@constraint(model, psd, y[moment_matrix] in PSDCone()) JuMP.@constraint(model, psd, y[moment_matrix] in PSDCone())
@ -54,11 +54,10 @@ be added to the model. This may improve the accuracy of the solution if
The default `u = zero(X)` formulates a simple feasibility problem. The default `u = zero(X)` formulates a simple feasibility problem.
""" """
function sos_problem_primal( function sos_problem_primal(
elt::StarAlgebras.AlgebraElement, elt::SA.AlgebraElement,
order_unit::StarAlgebras.AlgebraElement = zero(elt); order_unit::SA.AlgebraElement = zero(elt);
upper_bound = Inf, upper_bound = Inf,
augmented::Bool = iszero(StarAlgebras.aug(elt)) && augmented::Bool = iszero(SA.aug(elt)) && iszero(SA.aug(order_unit)),
iszero(StarAlgebras.aug(order_unit)),
) )
@assert parent(elt) === parent(order_unit) @assert parent(elt) === parent(order_unit)
@ -80,11 +79,11 @@ function sos_problem_primal(
end end
JuMP.@objective(model, Max, λ) JuMP.@objective(model, Max, λ)
for b in basis(parent(elt)) for b in SA.basis(parent(elt))
JuMP.@constraint(model, elt(b) - λ * order_unit(b) == dot(A[b], P)) JuMP.@constraint(model, elt(b) - λ * order_unit(b) == dot(A[b], P))
end end
else else
for b in basis(parent(elt)) for b in SA.basis(parent(elt))
JuMP.@constraint(model, elt(b) == dot(A[b], P)) JuMP.@constraint(model, elt(b) == dot(A[b], P))
end end
end end
@ -94,7 +93,7 @@ end
function invariant_constraint!( function invariant_constraint!(
result::AbstractMatrix, result::AbstractMatrix,
basis::StarAlgebras.AbstractBasis, basis::SA.AbstractBasis,
cnstrs::AbstractDict{K,<:ConstraintMatrix}, cnstrs::AbstractDict{K,<:ConstraintMatrix},
invariant_vec::SparseVector, invariant_vec::SparseVector,
) where {K} ) where {K}
@ -128,14 +127,14 @@ function invariant_constraint(basis, cnstrs, invariant_vec)
return sparse(I, J, V, size(_M)...) return sparse(I, J, V, size(_M)...)
end end
function isorth_projection(ds::SymbolicWedderburn.DirectSummand) function isorth_projection(ds::SW.DirectSummand)
U = SymbolicWedderburn.image_basis(ds) U = SW.image_basis(ds)
return isapprox(U * U', I) return isapprox(U * U', I)
end end
function sos_problem_primal( function sos_problem_primal(
elt::StarAlgebras.AlgebraElement, elt::SA.AlgebraElement,
wedderburn::WedderburnDecomposition; wedderburn::SW.WedderburnDecomposition;
kwargs..., kwargs...,
) )
return sos_problem_primal(elt, zero(elt), wedderburn; kwargs...) return sos_problem_primal(elt, zero(elt), wedderburn; kwargs...)
@ -176,31 +175,30 @@ import ProgressMeter
__show_itrs(n, total) = () -> [(Symbol("constraint"), "$n/$total")] __show_itrs(n, total) = () -> [(Symbol("constraint"), "$n/$total")]
function sos_problem_primal( function sos_problem_primal(
elt::StarAlgebras.AlgebraElement, elt::SA.AlgebraElement,
orderunit::StarAlgebras.AlgebraElement, orderunit::SA.AlgebraElement,
wedderburn::WedderburnDecomposition; wedderburn::SW.WedderburnDecomposition;
upper_bound = Inf, upper_bound = Inf,
augmented = iszero(StarAlgebras.aug(elt)) && augmented = iszero(SA.aug(elt)) && iszero(SA.aug(orderunit)),
iszero(StarAlgebras.aug(orderunit)),
check_orthogonality = true, check_orthogonality = true,
show_progress = false, show_progress = false,
) )
@assert parent(elt) === parent(orderunit) @assert parent(elt) === parent(orderunit)
if check_orthogonality if check_orthogonality
if any(!isorth_projection, direct_summands(wedderburn)) if any(!isorth_projection, SW.direct_summands(wedderburn))
error( error(
"Wedderburn decomposition contains a non-orthogonal projection", "Wedderburn decomposition contains a non-orthogonal projection",
) )
end end
end end
id_one = findfirst(invariant_vectors(wedderburn)) do v id_one = findfirst(SW.invariant_vectors(wedderburn)) do v
b = basis(parent(elt)) b = SA.basis(parent(elt))
return sparsevec([b[one(first(b))]], [1 // 1], length(v)) == v return sparsevec([b[one(first(b))]], [1 // 1], length(v)) == v
end end
prog = ProgressMeter.Progress( prog = ProgressMeter.Progress(
length(invariant_vectors(wedderburn)); length(SW.invariant_vectors(wedderburn));
dt = 1, dt = 1,
desc = "Adding constraints: ", desc = "Adding constraints: ",
enabled = show_progress, enabled = show_progress,
@ -225,7 +223,7 @@ function sos_problem_primal(
end end
# semidefinite constraints as described by wedderburn # semidefinite constraints as described by wedderburn
Ps = map(direct_summands(wedderburn)) do ds Ps = map(SW.direct_summands(wedderburn)) do ds
dim = size(ds, 1) dim = size(ds, 1)
P = JuMP.@variable(model, [1:dim, 1:dim], Symmetric) P = JuMP.@variable(model, [1:dim, 1:dim], Symmetric)
JuMP.@constraint(model, P in PSDCone()) JuMP.@constraint(model, P in PSDCone())
@ -238,14 +236,14 @@ function sos_problem_primal(
_eps = 10 * eps(T) * max(size(parent(elt).mstructure)...) _eps = 10 * eps(T) * max(size(parent(elt).mstructure)...)
end end
X = StarAlgebras.coeffs(elt) X = SA.coeffs(elt)
U = StarAlgebras.coeffs(orderunit) U = SA.coeffs(orderunit)
# defining constraints based on the multiplicative structure # defining constraints based on the multiplicative structure
cnstrs = constraints(parent(elt); augmented = augmented) cnstrs = constraints(parent(elt); augmented = augmented)
# adding linear constraints: one per orbit # adding linear constraints: one per orbit
for (i, iv) in enumerate(invariant_vectors(wedderburn)) for (i, iv) in enumerate(SW.invariant_vectors(wedderburn))
ProgressMeter.next!(prog; showvalues = __show_itrs(i, prog.n)) ProgressMeter.next!(prog; showvalues = __show_itrs(i, prog.n))
augmented && i == id_one && continue augmented && i == id_one && continue
# i == 500 && break # i == 500 && break
@ -253,9 +251,9 @@ function sos_problem_primal(
x = dot(X, iv) x = dot(X, iv)
u = dot(U, iv) u = dot(U, iv)
spM_orb = invariant_constraint(basis(parent(elt)), cnstrs, iv) spM_orb = invariant_constraint(SA.basis(parent(elt)), cnstrs, iv)
Ms = SymbolicWedderburn.diagonalize!( Ms = SW.diagonalize!(
Ms, Ms,
spM_orb, spM_orb,
wedderburn; wedderburn;

View File

@ -1,30 +1,40 @@
import SymbolicWedderburn.PermutationGroups.AbstractPerm
# move to Groups # move to Groups
Base.keys(a::Alphabet) = keys(1:length(a)) Base.keys(a::Alphabet) = keys(1:length(a))
## the old 1812.03456 definitions ## the old 1812.03456 definitions
isopposite(σ::AbstractPerm, τ::AbstractPerm, i=1, j=2) = function isopposite(
i^σ i^τ && i^σ j^τ && j^σ i^τ && j^σ j^τ σ::PG.AbstractPermutation,
τ::PG.AbstractPermutation,
i = 1,
j = 2,
)
return i^σ i^τ && i^σ j^τ && j^σ i^τ && j^σ j^τ
end
isadjacent(σ::AbstractPerm, τ::AbstractPerm, i=1, j=2) = function isadjacent(
(i^σ == i^τ && j^σ j^τ) || # first equal, second differ σ::PG.AbstractPermutation,
(j^σ == j^τ && i^σ i^τ) || # second equal, first differ τ::PG.AbstractPermutation,
(i^σ == j^τ && j^σ i^τ) || # first σ equal to second τ i = 1,
(j^σ == i^τ && i^σ j^τ) # second σ equal to first τ j = 2,
)
return (i^σ == i^τ && j^σ j^τ) || # first equal, second differ
(j^σ == j^τ && i^σ i^τ) || # second equal, first differ
(i^σ == j^τ && j^σ i^τ) || # first σ equal to second τ
(j^σ == i^τ && i^σ j^τ) # second σ equal to first τ
end
function _ncycle(start, length, n=start + length - 1) function _ncycle(start, length, n=start + length - 1)
p = PermutationGroups.Perm(Int8(n)) p = Vector{UInt8}(1:n)
@assert n start + length - 1 @assert n start + length - 1
for k in start:start+length-2 for k in start:start+length-2
p[k] = k + 1 p[k] = k + 1
end end
p[start+length-1] = start p[start+length-1] = start
return p return PG.Perm(p)
end end
alternating_group(n::Integer) = PermutationGroups.PermGroup([_ncycle(i, 3) for i in 1:n-2]) alternating_group(n::Integer) = PG.PermGroup([_ncycle(i, 3) for i in 1:n-2])
function small_gens(G::MatrixGroups.SpecialLinearGroup) function small_gens(G::MatrixGroups.SpecialLinearGroup)
A = alphabet(G) A = alphabet(G)
@ -46,31 +56,31 @@ function small_gens(G::Groups.AutomorphismGroup{<:FreeGroup})
return union!(S, inv.(S)) return union!(S, inv.(S))
end end
function small_laplacian(RG::StarAlgebras.StarAlgebra) function small_laplacian(RG::SA.StarAlgebra)
G = StarAlgebras.object(RG) G = SA.object(RG)
S₂ = small_gens(G) S₂ = small_gens(G)
return length(S₂) * one(RG) - sum(RG(s) for s in S₂) return length(S₂) * one(RG) - sum(RG(s) for s in S₂)
end end
function SqAdjOp(A::StarAlgebras.StarAlgebra, n::Integer, Δ₂=small_laplacian(A)) function SqAdjOp(A::SA.StarAlgebra, n::Integer, Δ₂ = small_laplacian(A))
@assert parent(Δ₂) === A @assert parent(Δ₂) === A
alt_n = alternating_group(n) alt_n = alternating_group(n)
G = StarAlgebras.object(A) G = SA.object(A)
act = action_by_conjugation(G, alt_n) act = action_by_conjugation(G, alt_n)
Δ₂s = Dict(σ => SymbolicWedderburn.action(act, σ, Δ₂) for σ in alt_n) Δ₂s = Dict(σ => SW.action(act, σ, Δ₂) for σ in alt_n)
sq, adj, op = zero(A), zero(A), zero(A) sq, adj, op = zero(A), zero(A), zero(A)
tmp = zero(A) tmp = zero(A)
for σ in alt_n for σ in alt_n
StarAlgebras.add!(sq, sq, StarAlgebras.mul!(tmp, Δ₂s[σ], Δ₂s[σ])) SA.add!(sq, sq, SA.mul!(tmp, Δ₂s[σ], Δ₂s[σ]))
for τ in alt_n for τ in alt_n
if isopposite(σ, τ) if isopposite(σ, τ)
StarAlgebras.add!(op, op, StarAlgebras.mul!(tmp, Δ₂s[σ], Δ₂s[τ])) SA.add!(op, op, SA.mul!(tmp, Δ₂s[σ], Δ₂s[τ]))
elseif isadjacent(σ, τ) elseif isadjacent(σ, τ)
StarAlgebras.add!(adj, adj, StarAlgebras.mul!(tmp, Δ₂s[σ], Δ₂s[τ])) SA.add!(adj, adj, SA.mul!(tmp, Δ₂s[σ], Δ₂s[τ]))
end end
end end
end end

View File

@ -20,12 +20,12 @@
optimizer = scs_optimizer(; optimizer = scs_optimizer(;
eps = 1e-10, eps = 1e-10,
max_iters = 5_000, max_iters = 5_000,
accel = 50, accel = -50,
alpha = 1.9, alpha = 1.9,
), ),
) )
@test status == JuMP.ALMOST_OPTIMAL @test status == JuMP.OPTIMAL
@test !certified @test !certified
@test λ < 0 @test λ < 0
end end
@ -33,7 +33,7 @@
@testset "SL(3,F₅)" begin @testset "SL(3,F₅)" begin
N = 3 N = 3
G = MatrixGroups.SpecialLinearGroup{N}( G = MatrixGroups.SpecialLinearGroup{N}(
SymbolicWedderburn.Characters.FiniteFields.GF{5}, SW.Characters.FiniteFields.GF{5},
) )
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2) RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2)
@ -53,7 +53,7 @@
optimizer = scs_optimizer(; optimizer = scs_optimizer(;
eps = 1e-10, eps = 1e-10,
max_iters = 5_000, max_iters = 5_000,
accel = 50, accel = -50,
alpha = 1.9, alpha = 1.9,
), ),
) )
@ -65,15 +65,16 @@
m = PropertyT.sos_problem_dual(elt, unit) m = PropertyT.sos_problem_dual(elt, unit)
PropertyT.solve( PropertyT.solve(
m, m,
cosmo_optimizer(; scs_optimizer(;
eps = 1e-6, eps = 1e-3,
max_iters = 5_000, max_iters = 5_000,
accel = 50, accel = -50,
alpha = 1.9, alpha = 1.9,
), ),
) )
@test JuMP.termination_status(m) in (JuMP.ALMOST_OPTIMAL, JuMP.OPTIMAL) @test JuMP.termination_status(m) in
(JuMP.ITERATION_LIMIT, JuMP.ALMOST_OPTIMAL, JuMP.OPTIMAL)
@test JuMP.objective_value(m) 1.5 atol = 1e-2 @test JuMP.objective_value(m) 1.5 atol = 1e-2
end end
@ -98,12 +99,12 @@
optimizer = scs_optimizer(; optimizer = scs_optimizer(;
eps = 1e-10, eps = 1e-10,
max_iters = 5_000, max_iters = 5_000,
accel = 50, accel = -50,
alpha = 1.9, alpha = 1.9,
), ),
) )
@test status == JuMP.ALMOST_OPTIMAL @test status in (JuMP.ALMOST_OPTIMAL, JuMP.ITERATION_LIMIT)
@test λ < 0 @test λ < 0
@test !certified @test !certified
@ -111,14 +112,14 @@
status, _ = PropertyT.solve( status, _ = PropertyT.solve(
sos_problem, sos_problem,
cosmo_optimizer(; scs_optimizer(;
eps = 1e-7, eps = 1e-7,
max_iters = 10_000, max_iters = 5_000,
accel = 0, accel = -50,
alpha = 1.9, alpha = 1.9,
), ),
) )
@test status == JuMP.OPTIMAL @test status in (JuMP.OPTIMAL, JuMP.ITERATION_LIMIT)
P = JuMP.value.(sos_problem[:P]) P = JuMP.value.(sos_problem[:P])
Q = real.(sqrt(P)) Q = real.(sqrt(P))
certified, λ_cert = certified, λ_cert =
@ -149,11 +150,11 @@
status, _ = PropertyT.solve( status, _ = PropertyT.solve(
opt_problem, opt_problem,
cosmo_optimizer(; scs_optimizer(;
eps = 1e-10, eps = 1e-10,
max_iters = 10_000, max_iters = 10_000,
accel = 0, accel = 50,
alpha = 1.5, alpha = 1.9,
), ),
) )
@ -173,7 +174,11 @@
) )
@test certified @test certified
@test isapprox(λ_cert, λ, rtol = 1e-5) @test isapprox(
PropertyT.IntervalArithmetic.inf(λ_cert),
λ,
rtol = 1e-5,
)
end end
@testset "augmented formulation" begin @testset "augmented formulation" begin
@ -213,7 +218,11 @@
) )
@test certified @test certified
@test isapprox(λ_cert, λ, rtol = 1e-5) @test isapprox(
PropertyT.IntervalArithmetic.inf(λ_cert),
λ,
rtol = 1e-5,
)
@test λ_cert > 2 // 10 @test λ_cert > 2 // 10
end end
end end

View File

@ -5,15 +5,15 @@
@info "running tests for" G @info "running tests for" G
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2) RG, S, sizes = PropertyT.group_algebra(G; halfradius = 2)
P = PermGroup(perm"(1,2)", Perm(circshift(1:N, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:N, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
act = PropertyT.action_by_conjugation(G, Σ) act = PropertyT.action_by_conjugation(G, Σ)
wd = WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RG), SA.basis(RG),
StarAlgebras.Basis{UInt16}(@view basis(RG)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
) )
@info wd @info wd
@ -54,15 +54,18 @@
Δ = RSL(length(S)) - sum(RSL(s) for s in S) Δ = RSL(length(S)) - sum(RSL(s) for s in S)
@testset "Wedderburn formulation" begin @testset "Wedderburn formulation" begin
P = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(
PG.PermGroup(PG.perm"(1,2)"),
P,
)
act = PropertyT.action_by_conjugation(SL, Σ) act = PropertyT.action_by_conjugation(SL, Σ)
wd = WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Rational{Int}, Rational{Int},
Σ, Σ,
act, act,
basis(RSL), SA.basis(RSL),
StarAlgebras.Basis{UInt16}(@view basis(RSL)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RSL)[1:sizes[2]]),
) )
@info wd @info wd
@ -78,12 +81,12 @@
augmented = false, augmented = false,
) )
wdfl = SymbolicWedderburn.WedderburnDecomposition( wdfl = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RSL), SA.basis(RSL),
StarAlgebras.Basis{UInt16}(@view basis(RSL)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RSL)[1:sizes[2]]),
) )
model, varP = PropertyT.sos_problem_primal( model, varP = PropertyT.sos_problem_primal(
@ -147,16 +150,19 @@
unit = Δ unit = Δ
ub = Inf ub = Inf
P = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(
PG.PermGroup(PG.perm"(1,2)"),
P,
)
act = PropertyT.action_by_conjugation(SL, Σ) act = PropertyT.action_by_conjugation(SL, Σ)
wdfl = SymbolicWedderburn.WedderburnDecomposition( wdfl = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RSL), SA.basis(RSL),
StarAlgebras.Basis{UInt16}(@view basis(RSL)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RSL)[1:sizes[2]]),
) )
@info wdfl @info wdfl
@ -170,10 +176,10 @@
status, _ = PropertyT.solve( status, _ = PropertyT.solve(
opt_problem, opt_problem,
scs_optimizer(; cosmo_optimizer(;
eps = 1e-8, eps = 1e-8,
max_iters = 20_000, max_iters = 20_000,
accel = 0, accel = 50,
alpha = 1.9, alpha = 1.9,
), ),
) )

View File

@ -8,11 +8,11 @@ using SparseArrays
end end
@testset "unit tests" begin @testset "unit tests" begin
@test PropertyT.isopposite(perm"(1,2,3)(4)", perm"(1,4,2)") @test PropertyT.isopposite(PG.perm"(1,2,3)(4)", PG.perm"(1,4,2)")
@test PropertyT.isadjacent(perm"(1,2,3)", perm"(1,2)(3)") @test PropertyT.isadjacent(PG.perm"(1,2,3)", PG.perm"(1,2)(3)")
@test !PropertyT.isopposite(perm"(1,2,3)", perm"(1,2)(3)") @test !PropertyT.isopposite(PG.perm"(1,2,3)", PG.perm"(1,2)(3)")
@test !PropertyT.isadjacent(perm"(1,4)", perm"(2,3)(4)") @test !PropertyT.isadjacent(PG.perm"(1,4)", PG.perm"(2,3)(4)")
@test isconstant_on_orbit([1, 1, 1, 2, 2], [2, 3]) @test isconstant_on_orbit([1, 1, 1, 2, 2], [2, 3])
@test !isconstant_on_orbit([1, 1, 1, 2, 2], [2, 3, 4]) @test !isconstant_on_orbit([1, 1, 1, 2, 2], [2, 3, 4])
@ -29,19 +29,19 @@ using SparseArrays
RG(length(S)) - sum(RG(s) for s in S) RG(length(S)) - sum(RG(s) for s in S)
end end
P = PermGroup(perm"(1,2)", Perm(circshift(1:N, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:N, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
act = PropertyT.action_by_conjugation(G, Σ) act = PropertyT.action_by_conjugation(G, Σ)
wd = WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RG), SA.basis(RG),
StarAlgebras.Basis{UInt16}(@view basis(RG)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
) )
@info wd @info wd
ivs = SymbolicWedderburn.invariant_vectors(wd) ivs = SW.invariant_vectors(wd)
sq, adj, op = PropertyT.SqAdjOp(RG, N) sq, adj, op = PropertyT.SqAdjOp(RG, N)
@ -105,16 +105,16 @@ end
Δ = RG(length(S)) - sum(RG(s) for s in S) Δ = RG(length(S)) - sum(RG(s) for s in S)
P = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
act = PropertyT.action_by_conjugation(G, Σ) act = PropertyT.action_by_conjugation(G, Σ)
wd = SymbolicWedderburn.WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RG), SA.basis(RG),
StarAlgebras.Basis{UInt16}(@view basis(RG)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
) )
@info wd @info wd
@ -130,7 +130,7 @@ end
wd; wd;
upper_bound = UB, upper_bound = UB,
halfradius = 2, halfradius = 2,
optimizer = cosmo_optimizer(; accel = 50, alpha = 1.9), optimizer = scs_optimizer(; accel = -50, alpha = 1.9),
) )
@test status == JuMP.OPTIMAL @test status == JuMP.OPTIMAL
@test certified @test certified
@ -156,7 +156,7 @@ end
m, _ = PropertyT.sos_problem_primal(elt, wd) m, _ = PropertyT.sos_problem_primal(elt, wd)
PropertyT.solve( PropertyT.solve(
m, m,
scs_optimizer(; max_iters = 5000, accel = 50, alpha = 1.9), scs_optimizer(; max_iters = 1000, accel = 50, alpha = 1.9),
) )
@test JuMP.termination_status(m) in @test JuMP.termination_status(m) in
@ -193,16 +193,16 @@ end
Δ = RG(length(S)) - sum(RG(s) for s in S) Δ = RG(length(S)) - sum(RG(s) for s in S)
P = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
act = PropertyT.action_by_conjugation(G, Σ) act = PropertyT.action_by_conjugation(G, Σ)
wd = SymbolicWedderburn.WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RG), SA.basis(RG),
StarAlgebras.Basis{UInt16}(@view basis(RG)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[2]]),
) )
@info wd @info wd

View File

@ -20,8 +20,10 @@ end
end end
@testset "Exceptional root systems" begin @testset "Exceptional root systems" begin
Base.:^(t::NTuple{N}, p::PG.AbstractPermutation) where {N} =
ntuple(i -> t[i^p], N)
@testset "F4" begin @testset "F4" begin
F4 = let Σ = PermutationGroups.PermGroup(perm"(1,2,3,4)", perm"(1,2)") F4 = let Σ = PG.PermGroup(PG.perm"(1,2,3,4)", PG.perm"(1,2)")
long = let x = (1, 1, 0, 0) .// 1 long = let x = (1, 1, 0, 0) .// 1
PropertyT.Roots.Root.( PropertyT.Roots.Root.(
union( union(
@ -50,7 +52,7 @@ end
a = F4[1] a = F4[1]
@test isapprox(PropertyT.Roots.₂length(a), sqrt(2)) @test isapprox(PropertyT.Roots.₂length(a), sqrt(2))
b = F4[6] b = F4[4]
@test isapprox(PropertyT.Roots.₂length(b), sqrt(2)) @test isapprox(PropertyT.Roots.₂length(b), sqrt(2))
c = a + b c = a + b
@test isapprox(PropertyT.Roots.₂length(c), 2.0) @test isapprox(PropertyT.Roots.₂length(c), 2.0)
@ -90,9 +92,9 @@ end
@testset "E6-7-8 exceptional root systems" begin @testset "E6-7-8 exceptional root systems" begin
E8 = E8 =
let Σ = PermutationGroups.PermGroup( let Σ = PG.PermGroup(
perm"(1,2,3,4,5,6,7,8)", PG.perm"(1,2,3,4,5,6,7,8)",
perm"(1,2)", PG.perm"(1,2)",
) )
long = let x = (1, 1, 0, 0, 0, 0, 0, 0) .// 1 long = let x = (1, 1, 0, 0, 0, 0, 0, 0) .// 1
PropertyT.Roots.Root.( PropertyT.Roots.Root.(
@ -160,7 +162,6 @@ end
]) ])
@test Set(keys(counts)) == subtypes @test Set(keys(counts)) == subtypes
d, r = divrem(counts[:A₂], 4) d, r = divrem(counts[:A₂], 4)
@info d, r
@test r == 0 && d == 10 @test r == 0 && d == 10
end end
end end

View File

@ -1,5 +1,5 @@
function test_action(basis, group, act) function test_action(basis, group, act)
action = SymbolicWedderburn.action action = SW.action
return @testset "action definition" begin return @testset "action definition" begin
@test all(basis) do b @test all(basis) do b
e = one(group) e = one(group)
@ -22,7 +22,7 @@ function test_action(basis, group, act)
g_h g_h
end end
action = SymbolicWedderburn.action action = SW.action
@test action(act, g, a) in basis @test action(act, g, a) in basis
@test action(act, h, a) in basis @test action(act, h, a) in basis
@test action(act, h, action(act, g, a)) == action(act, g * h, a) @test action(act, h, action(act, g, a)) == action(act, g * h, a)
@ -33,7 +33,7 @@ function test_action(basis, group, act)
return x == y return x == y
end end
if act isa SymbolicWedderburn.ByPermutations if act isa SW.ByPermutations
@test all(basis) do b @test all(basis) do b
return action(act, g, b) basis && action(act, h, b) basis return action(act, g, b) basis && action(act, h, b) basis
end end
@ -50,75 +50,73 @@ end
RSL, S, sizes = PropertyT.group_algebra(SL; halfradius = 2) RSL, S, sizes = PropertyT.group_algebra(SL; halfradius = 2)
@testset "Permutation action" begin @testset "Permutation action" begin
Γ = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) Γ = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
ΓpA = PropertyT.action_by_conjugation(SL, Γ) ΓpA = PropertyT.action_by_conjugation(SL, Γ)
test_action(basis(RSL), Γ, ΓpA) test_action(SA.basis(RSL), Γ, ΓpA)
@testset "mps is successful" begin @testset "mps is successful" begin
charsΓ = charsΓ =
SymbolicWedderburn.Character{ SW.Character{
Rational{Int}, Rational{Int},
}.(SymbolicWedderburn.irreducible_characters(Γ)) }.(SW.irreducible_characters(Γ))
= SymbolicWedderburn._group_algebra(Γ) = SW._group_algebra(Γ)
@time mps, ranks = @time mps, ranks =
SymbolicWedderburn.minimal_projection_system(charsΓ, ) SW.minimal_projection_system(charsΓ, )
@test all(isone, ranks) @test all(isone, ranks)
end end
@testset "Wedderburn decomposition" begin @testset "Wedderburn decomposition" begin
wd = SymbolicWedderburn.WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Rational{Int}, Rational{Int},
Γ, Γ,
ΓpA, ΓpA,
basis(RSL), SA.basis(RSL),
StarAlgebras.Basis{UInt16}(@view basis(RSL)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RSL)[1:sizes[2]]),
) )
@test length(invariant_vectors(wd)) == 918 @test length(SW.invariant_vectors(wd)) == 918
@test SymbolicWedderburn.size.(direct_summands(wd), 1) == @test size.(SW.direct_summands(wd), 1) == [23, 18, 40]
[40, 23, 18] @test all(SW.issimple, SW.direct_summands(wd))
@test all(issimple, direct_summands(wd))
end end
end end
@testset "Wreath action" begin @testset "Wreath action" begin
Γ = let P = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) Γ = let P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
end end
ΓpA = PropertyT.action_by_conjugation(SL, Γ) ΓpA = PropertyT.action_by_conjugation(SL, Γ)
test_action(basis(RSL), Γ, ΓpA) test_action(SA.basis(RSL), Γ, ΓpA)
@testset "mps is successful" begin @testset "mps is successful" begin
charsΓ = charsΓ =
SymbolicWedderburn.Character{ SW.Character{
Rational{Int}, Rational{Int},
}.(SymbolicWedderburn.irreducible_characters(Γ)) }.(SW.irreducible_characters(Γ))
= SymbolicWedderburn._group_algebra(Γ) = SW._group_algebra(Γ)
@time mps, ranks = @time mps, ranks =
SymbolicWedderburn.minimal_projection_system(charsΓ, ) SW.minimal_projection_system(charsΓ, )
@test all(isone, ranks) @test all(isone, ranks)
end end
@testset "Wedderburn decomposition" begin @testset "Wedderburn decomposition" begin
wd = SymbolicWedderburn.WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Rational{Int}, Rational{Int},
Γ, Γ,
ΓpA, ΓpA,
basis(RSL), SA.basis(RSL),
StarAlgebras.Basis{UInt16}(@view basis(RSL)[1:sizes[2]]), SA.Basis{UInt16}(@view SA.basis(RSL)[1:sizes[2]]),
) )
@test length(invariant_vectors(wd)) == 247 @test length(SW.invariant_vectors(wd)) == 247
@test SymbolicWedderburn.size.(direct_summands(wd), 1) == @test size.(SW.direct_summands(wd), 1) == [9, 6, 14, 14, 12]
[14, 9, 6, 14, 12] @test all(SW.issimple, SW.direct_summands(wd))
@test all(issimple, direct_summands(wd))
end end
end end
end end
@ -130,75 +128,73 @@ end
RSAutFn, S, sizes = PropertyT.group_algebra(SAutFn; halfradius = 1) RSAutFn, S, sizes = PropertyT.group_algebra(SAutFn; halfradius = 1)
@testset "Permutation action" begin @testset "Permutation action" begin
Γ = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) Γ = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
ΓpA = PropertyT.action_by_conjugation(SAutFn, Γ) ΓpA = PropertyT.action_by_conjugation(SAutFn, Γ)
test_action(basis(RSAutFn), Γ, ΓpA) test_action(SA.basis(RSAutFn), Γ, ΓpA)
@testset "mps is successful" begin @testset "mps is successful" begin
charsΓ = charsΓ =
SymbolicWedderburn.Character{ SW.Character{
Rational{Int}, Rational{Int},
}.(SymbolicWedderburn.irreducible_characters(Γ)) }.(SW.irreducible_characters(Γ))
= SymbolicWedderburn._group_algebra(Γ) = SW._group_algebra(Γ)
@time mps, ranks = @time mps, ranks =
SymbolicWedderburn.minimal_projection_system(charsΓ, ) SW.minimal_projection_system(charsΓ, )
@test all(isone, ranks) @test all(isone, ranks)
end end
@testset "Wedderburn decomposition" begin @testset "Wedderburn decomposition" begin
wd = SymbolicWedderburn.WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Rational{Int}, Rational{Int},
Γ, Γ,
ΓpA, ΓpA,
basis(RSAutFn), SA.basis(RSAutFn),
StarAlgebras.Basis{UInt16}(@view basis(RSAutFn)[1:sizes[1]]), SA.Basis{UInt16}(@view SA.basis(RSAutFn)[1:sizes[1]]),
) )
@test length(invariant_vectors(wd)) == 93 @test length(SW.invariant_vectors(wd)) == 93
@test SymbolicWedderburn.size.(direct_summands(wd), 1) == @test size.(SW.direct_summands(wd), 1) == [5, 4, 8, 4]
[4, 8, 5, 4] @test all(SW.issimple, SW.direct_summands(wd))
@test all(issimple, direct_summands(wd))
end end
end end
@testset "Wreath action" begin @testset "Wreath action" begin
Γ = let P = PermGroup(perm"(1,2)", Perm(circshift(1:n, -1))) Γ = let P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:n, -1)))
PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Groups.Constructions.WreathProduct(PG.PermGroup(PG.perm"(1,2)"), P)
end end
ΓpA = PropertyT.action_by_conjugation(SAutFn, Γ) ΓpA = PropertyT.action_by_conjugation(SAutFn, Γ)
test_action(basis(RSAutFn), Γ, ΓpA) test_action(SA.basis(RSAutFn), Γ, ΓpA)
@testset "mps is successful" begin @testset "mps is successful" begin
charsΓ = charsΓ =
SymbolicWedderburn.Character{ SW.Character{
Rational{Int}, Rational{Int},
}.(SymbolicWedderburn.irreducible_characters(Γ)) }.(SW.irreducible_characters(Γ))
= SymbolicWedderburn._group_algebra(Γ) = SW._group_algebra(Γ)
@time mps, ranks = @time mps, ranks =
SymbolicWedderburn.minimal_projection_system(charsΓ, ) SW.minimal_projection_system(charsΓ, )
@test all(isone, ranks) @test all(isone, ranks)
end end
@testset "Wedderburn decomposition" begin @testset "Wedderburn decomposition" begin
wd = SymbolicWedderburn.WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Rational{Int}, Rational{Int},
Γ, Γ,
ΓpA, ΓpA,
basis(RSAutFn), SA.basis(RSAutFn),
StarAlgebras.Basis{UInt16}(@view basis(RSAutFn)[1:sizes[1]]), SA.Basis{UInt16}(@view SA.basis(RSAutFn)[1:sizes[1]]),
) )
@test length(invariant_vectors(wd)) == 18 @test length(SW.invariant_vectors(wd)) == 18
@test SymbolicWedderburn.size.(direct_summands(wd), 1) == @test size.(SW.direct_summands(wd), 1) == [2, 1, 2, 1, 2, 1, 1, 2]
[1, 1, 2, 2, 1, 2, 2, 1] @test all(SW.issimple, SW.direct_summands(wd))
@test all(issimple, direct_summands(wd))
end end
end end
end end

View File

@ -29,7 +29,7 @@ function check_positivity(
halfradius = 2, halfradius = 2,
optimizer, optimizer,
) )
@assert aug(elt) == aug(unit) == 0 @assert SA.aug(elt) == SA.aug(unit) == 0
@time sos_problem, Ps = @time sos_problem, Ps =
PropertyT.sos_problem_primal(elt, unit, wd; upper_bound = upper_bound) PropertyT.sos_problem_primal(elt, unit, wd; upper_bound = upper_bound)

View File

@ -4,7 +4,7 @@
p = 7 p = 7
halfradius = 3 halfradius = 3
G = MatrixGroups.SpecialLinearGroup{N}( G = MatrixGroups.SpecialLinearGroup{N}(
SymbolicWedderburn.Characters.FiniteFields.GF{p}, SW.Characters.FiniteFields.GF{p},
) )
RG, S, sizes = PropertyT.group_algebra(G; halfradius = 3) RG, S, sizes = PropertyT.group_algebra(G; halfradius = 3)
@ -22,11 +22,11 @@
unit; unit;
upper_bound = ub, upper_bound = ub,
halfradius = 2, halfradius = 2,
optimizer = cosmo_optimizer(; optimizer = scs_optimizer(;
eps = 1e-7, eps = 1e-8,
max_iters = 5_000, max_iters = 20_000,
accel = 50, accel = -50,
alpha = 1.95, alpha = 1.9,
), ),
) )
@ -37,32 +37,34 @@
m = PropertyT.sos_problem_dual(elt, unit) m = PropertyT.sos_problem_dual(elt, unit)
PropertyT.solve( PropertyT.solve(
m, m,
cosmo_optimizer(; scs_optimizer(;
eps = 1e-7, eps = 1e-8,
max_iters = 10_000, max_iters = 10_000,
accel = 50, accel = -50,
alpha = 1.95, alpha = 1.9,
), ),
) )
@test JuMP.termination_status(m) in @test JuMP.termination_status(m) in
(JuMP.ALMOST_OPTIMAL, JuMP.OPTIMAL) (JuMP.ALMOST_OPTIMAL, JuMP.OPTIMAL)
@test JuMP.objective_value(m) λ_cert atol = 1e-2 @test JuMP.objective_value(m)
PropertyT.IntervalArithmetic.mid(λ_cert) atol = 1e-2
end end
@testset "Wedderburn decomposition" begin @testset "Wedderburn decomposition" begin
P = PermGroup(perm"(1,2)", Perm(circshift(1:N, -1))) P = PG.PermGroup(PG.perm"(1,2)", PG.Perm(circshift(1:N, -1)))
Σ = PropertyT.Constructions.WreathProduct(PermGroup(perm"(1,2)"), P) Σ = Groups.Constructions.WreathProduct(
PG.PermGroup(PG.perm"(1,2)"),
P,
)
act = PropertyT.action_by_conjugation(G, Σ) act = PropertyT.action_by_conjugation(G, Σ)
wd = WedderburnDecomposition( wd = SW.WedderburnDecomposition(
Float64, Float64,
Σ, Σ,
act, act,
basis(RG), SA.basis(RG),
StarAlgebras.Basis{UInt16}( SA.Basis{UInt16}(@view SA.basis(RG)[1:sizes[halfradius]]),
@view basis(RG)[1:sizes[halfradius]]
),
) )
status, certified, λ_cert = check_positivity( status, certified, λ_cert = check_positivity(
@ -71,10 +73,10 @@
wd; wd;
upper_bound = ub, upper_bound = ub,
halfradius = 2, halfradius = 2,
optimizer = cosmo_optimizer(; optimizer = scs_optimizer(;
eps = 1e-7, eps = 1e-8,
max_iters = 10_000, max_iters = 10_000,
accel = 50, accel = -50,
alpha = 1.9, alpha = 1.9,
), ),
) )

View File

@ -3,19 +3,18 @@ using LinearAlgebra
using SparseArrays using SparseArrays
using Groups using Groups
using Groups.GroupsCore
import Groups.MatrixGroups import Groups.MatrixGroups
using PropertyT using PropertyT
using SymbolicWedderburn import SymbolicWedderburn as SW
using SymbolicWedderburn.StarAlgebras import StarAlgebras as SA
using SymbolicWedderburn.PermutationGroups import PermutationGroups as PG
include("optimizers.jl") include("optimizers.jl")
include("check_positivity.jl") include("check_positivity.jl")
include("quick_tests.jl") include("quick_tests.jl")
if haskey(ENV, "FULL_TEST") || haskey(ENV, "CI") if haskey(ENV, "CI")
@testset "PropertyT" begin @testset "PropertyT" begin
include("constratint_matrices.jl") include("constratint_matrices.jl")
include("actions.jl") include("actions.jl")