diff --git a/Project.toml b/Project.toml index 8255f05..75f97da 100644 --- a/Project.toml +++ b/Project.toml @@ -19,9 +19,9 @@ Groups = "0.7" IntervalArithmetic = "0.20" JuMP = "1.3" ProgressMeter = "1.7" -SCS = "1.1.0" +SCS = "1.1" StaticArrays = "1" -SymbolicWedderburn = "0.3.2" +SymbolicWedderburn = "0.3.4" julia = "1.6" [extras] diff --git a/src/PropertyT.jl b/src/PropertyT.jl index 6b97d5d..16430ee 100644 --- a/src/PropertyT.jl +++ b/src/PropertyT.jl @@ -26,13 +26,13 @@ include("gradings.jl") include("actions/actions.jl") -function group_algebra(G::Groups.Group, S=gens(G); halfradius::Integer, twisted::Bool) +function group_algebra(G::Groups.Group, S = gens(G); halfradius::Integer) S = union!(S, inv.(S)) @info "generating wl-metric ball of radius $(2halfradius)" @time E, sizes = Groups.wlmetric_ball(S, radius=2halfradius) @info "sizes = $(sizes)" @info "computing the *-algebra structure for G" - @time RG = StarAlgebras.StarAlgebra{twisted}( + @time RG = StarAlgebras.StarAlgebra( G, StarAlgebras.Basis{UInt32}(E), (sizes[halfradius], sizes[halfradius]), diff --git a/src/certify.jl b/src/certify.jl index cdebcc9..2079791 100644 --- a/src/certify.jl +++ b/src/certify.jl @@ -8,26 +8,25 @@ end function __sos_via_sqr!( res::StarAlgebras.AlgebraElement, P::AbstractMatrix; - augmented::Bool + augmented::Bool, + id = (b = basis(parent(res)); b[one(first(b))]), ) - StarAlgebras.zero!(res) A = parent(res) - b = basis(A) - @assert size(A.mstructure) == size(P) - e = b[one(b[1])] + mstr = A.mstructure + @assert size(mstr) == size(P) - for i in axes(A.mstructure, 1) - x = StarAlgebras._istwisted(A.mstructure) ? StarAlgebras.star(b[i]) : b[i] - for j in axes(A.mstructure, 2) + StarAlgebras.zero!(res) + for j in axes(mstr, 2) + for i in axes(mstr, 1) p = P[i, j] - xy = b[A.mstructure[i, j]] - # either result += P[x,y]*(x*y) - res[xy] += p + x_star_y = mstr[-i, j] + res[x_star_y] += p + # either result += P[x,y]*(x'*y) if augmented - # or result += P[x,y]*(1-x)*(1-y) == P[x,y]*(2-x-y+xy) - y = b[j] - res[e] += p - res[x] -= p + # or result += P[x,y]*(1-x)'*(1-y) == P[x,y]*(1-x'-y+x'y) + res[id] += p + x_star, y = mstr[-i, id], j + res[x_star] -= p res[y] -= p end end diff --git a/src/constraint_matrix.jl b/src/constraint_matrix.jl index 5734837..73f3238 100644 --- a/src/constraint_matrix.jl +++ b/src/constraint_matrix.jl @@ -132,3 +132,50 @@ function LinearAlgebra.dot(cm::ConstraintMatrix, m::AbstractMatrix{T}) where {T} neg = isempty(cm.neg) ? zero(first(m)) : sum(@view m[cm.neg]) return convert(eltype(cm), cm.val) * (pos - neg) end + +function constraints(A::StarAlgebras.StarAlgebra; augmented::Bool) + return constraints(basis(A), A.mstructure; augmented = augmented) +end + +function constraints( + basis::StarAlgebras.AbstractBasis, + mstr::StarAlgebras.MultiplicativeStructure; + augmented = false, +) + cnstrs = _constraints( + mstr; + augmented = augmented, + num_constraints = length(basis), + id = basis[one(first(basis))], + ) + + return Dict( + basis[i] => ConstraintMatrix(c, size(mstr)..., 1) for + (i, c) in pairs(cnstrs) + ) +end + +function _constraints( + mstr::StarAlgebras.MultiplicativeStructure; + augmented::Bool = false, + num_constraints = maximum(mstr), + id, +) + cnstrs = [signed(eltype(mstr))[] for _ in 1:num_constraints] + LI = LinearIndices(size(mstr)) + + for ci in CartesianIndices(size(mstr)) + k = LI[ci] + i, j = Tuple(ci) + a_star_b = mstr[-i, j] + push!(cnstrs[a_star_b], k) + if augmented + # (1-a)'(1-b) = 1 - a' - b + a'b + push!(cnstrs[id], k) + a_star, b = mstr[-i, id], j + push!(cnstrs[a_star], -k) + push!(cnstrs[b], -k) + end + end + return cnstrs +end diff --git a/src/sos_sdps.jl b/src/sos_sdps.jl index 2f6faea..04a8916 100644 --- a/src/sos_sdps.jl +++ b/src/sos_sdps.jl @@ -11,10 +11,8 @@ function sos_problem_dual( ) @assert parent(elt) == parent(order_unit) algebra = parent(elt) - mstructure = if StarAlgebras._istwisted(algebra.mstructure) - algebra.mstructure - else - StarAlgebras.MTable{true}(basis(algebra), table_size=size(algebra.mstructure)) + moment_matrix = let m = algebra.mstructure + [m[-i, j] for i in axes(m, 1) for j in axes(m, 2)] end # 1 variable for every primal constraint @@ -24,7 +22,7 @@ function sos_problem_dual( model = Model() @variable model y[1:length(basis(algebra))] @constraint model λ_dual dot(order_unit, y) == 1 - @constraint(model, psd, y[mstructure] in PSDCone()) + @constraint(model, psd, y[moment_matrix] in PSDCone()) if !isinf(lower_bound) throw("Not Implemented yet") @@ -37,45 +35,6 @@ function sos_problem_dual( return model end -function constraints( - basis::StarAlgebras.AbstractBasis, - mstr::AbstractMatrix{<:Integer}; - augmented::Bool=false, - table_size=size(mstr) -) - cnstrs = [signed(eltype(mstr))[] for _ in basis] - LI = LinearIndices(table_size) - - for ci in CartesianIndices(table_size) - k = LI[ci] - a_star_b = basis[mstr[k]] - push!(cnstrs[basis[a_star_b]], k) - if augmented - # (1-a_star)(1-b) = 1 - a_star - b + a_star_b - - i, j = Tuple(ci) - a, b = basis[i], basis[j] - - push!(cnstrs[basis[one(a)]], k) - push!(cnstrs[basis[StarAlgebras.star(a)]], -k) - push!(cnstrs[basis[b]], -k) - end - end - - return Dict( - basis[i] => ConstraintMatrix(c, table_size..., 1) for (i, c) in pairs(cnstrs) - ) -end - -function constraints(A::StarAlgebras.StarAlgebra; augmented::Bool, twisted::Bool) - mstructure = if StarAlgebras._istwisted(A.mstructure) == twisted - A.mstructure - else - StarAlgebras.MTable{twisted}(basis(A), table_size=size(A.mstructure)) - end - return constraints(basis(A), mstructure, augmented=augmented) -end - """ sos_problem_primal(X, [u = zero(X); upper_bound=Inf]) Formulate sum of squares decomposition problem for `X - λ·u`. @@ -111,7 +70,7 @@ function sos_problem_primal( @warn "Setting `upper_bound` together with zero `order_unit` has no effect" end - A = constraints(parent(elt), augmented=augmented, twisted=true) + A = constraints(parent(elt); augmented = augmented) if !iszero(order_unit) λ = JuMP.@variable(model, λ) @@ -135,9 +94,9 @@ end function invariant_constraint!( result::AbstractMatrix, basis::StarAlgebras.AbstractBasis, - cnstrs::AbstractDict{K,CM}, + cnstrs::AbstractDict{K,<:ConstraintMatrix}, invariant_vec::SparseVector, -) where {K,CM<:ConstraintMatrix} +) where {K} result .= zero(eltype(result)) for i in SparseArrays.nonzeroinds(invariant_vec) g = basis[i] @@ -234,7 +193,7 @@ function sos_problem_primal( U = convert(Vector{T}, StarAlgebras.coeffs(orderunit)) # defining constraints based on the multiplicative structure - cnstrs = constraints(parent(elt), augmented=augmented, twisted=true) + cnstrs = constraints(parent(elt); augmented = augmented) prog = ProgressMeter.Progress( length(invariant_vectors(wedderburn)),