mirror of
https://github.com/kalmarek/PropertyT.jl.git
synced 2024-11-25 00:40:28 +01:00
add cocycle constraints from SDP duality paper by M.Nitsche
This commit is contained in:
parent
acb6b08ba9
commit
b01e26104e
105
src/sos_sdps.jl
105
src/sos_sdps.jl
@ -36,6 +36,31 @@ function sos_problem_dual(
|
|||||||
return model
|
return model
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function geometric_constraints!(
|
||||||
|
model::JuMP.Model,
|
||||||
|
elt::StarAlgebras.AlgebraElement,
|
||||||
|
)
|
||||||
|
A = parent(elt)
|
||||||
|
G = parent(A)
|
||||||
|
mstr = A.mstructure
|
||||||
|
b = basis(A)
|
||||||
|
y = model[:y]
|
||||||
|
for g in gens(G)
|
||||||
|
for h in gens(G)
|
||||||
|
gh = mstr[b[g], b[h]]
|
||||||
|
if elt[gh] > 0
|
||||||
|
for γ in axes(mstr, 1)
|
||||||
|
γgh = mstr[γ, gh]
|
||||||
|
γg = mstr[γ, b[g]]
|
||||||
|
γh = mstr[γ, b[h]]
|
||||||
|
JuMP.@constraint model y[γgh] + y[γ] == y[γg] + y[γh]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return model
|
||||||
|
end
|
||||||
|
|
||||||
function decompose(
|
function decompose(
|
||||||
elt::StarAlgebras.AlgebraElement,
|
elt::StarAlgebras.AlgebraElement,
|
||||||
wd::WedderburnDecomposition,
|
wd::WedderburnDecomposition,
|
||||||
@ -70,6 +95,29 @@ function decompose(v::AbstractVector, invariant_vecs)
|
|||||||
return res, norm(current - v)
|
return res, norm(current - v)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function _dot(elt::StarAlgebras.AlgebraElement, Y, wd::WedderburnDecomposition)
|
||||||
|
inv_vecs = invariant_vectors(wd)
|
||||||
|
v = StarAlgebras.coeffs(elt)
|
||||||
|
res, error = _dot(v, Y, inv_vecs)
|
||||||
|
_eps = length(v) * eps(typeof(error))
|
||||||
|
error < _eps || @warn "elt does not seem to be invariant" error
|
||||||
|
return res
|
||||||
|
end
|
||||||
|
|
||||||
|
function _dot(v::AbstractVector, Y::AbstractVector{<:JuMP.AbstractVariableRef})
|
||||||
|
@assert length(inv_vecs) == length(Y)
|
||||||
|
@assert length(v) == length(first(inv_vecs))
|
||||||
|
res = JuMP.AffExpr()
|
||||||
|
|
||||||
|
cfs, error = decompose(v, inv_vecs)
|
||||||
|
|
||||||
|
for i in SparseArrays.nonzeroinds(cfs)
|
||||||
|
(c, y) = cfs[i], Y[i]
|
||||||
|
JuMP.add_to_expression!(res, c, y)
|
||||||
|
end
|
||||||
|
return res, error
|
||||||
|
end
|
||||||
|
|
||||||
function sos_problem_dual(
|
function sos_problem_dual(
|
||||||
elt::StarAlgebras.AlgebraElement,
|
elt::StarAlgebras.AlgebraElement,
|
||||||
order_unit::StarAlgebras.AlgebraElement,
|
order_unit::StarAlgebras.AlgebraElement,
|
||||||
@ -123,6 +171,44 @@ function sos_problem_dual(
|
|||||||
return model, Ps
|
return model, Ps
|
||||||
end
|
end
|
||||||
|
|
||||||
|
function __find_firstnz(i, inv_vecs)
|
||||||
|
for (idx, iv) in enumerate(inv_vecs)
|
||||||
|
iv[i] ≠ 0 && return idx
|
||||||
|
end
|
||||||
|
return nothing
|
||||||
|
end
|
||||||
|
|
||||||
|
function geometric_constraints!(
|
||||||
|
model::JuMP.Model,
|
||||||
|
elt::StarAlgebras.AlgebraElement,
|
||||||
|
wd::WedderburnDecomposition,
|
||||||
|
)
|
||||||
|
A = parent(elt)
|
||||||
|
G = parent(A)
|
||||||
|
mstr = A.mstructure
|
||||||
|
b = basis(A)
|
||||||
|
y = model[:y_orb]
|
||||||
|
# cfs = PropertyT.decompose(elt, wd)
|
||||||
|
inv_vecs = invariant_vectors(wd)
|
||||||
|
for g in gens(G)
|
||||||
|
for h in gens(G)
|
||||||
|
gh = mstr[b[g], b[h]]
|
||||||
|
if elt[gh] > 0
|
||||||
|
for (γ, iv) in enumerate(inv_vecs)
|
||||||
|
γ_basis_idx = first(SparseArrays.nonzeroinds(iv))
|
||||||
|
γ_basis_idx > size(mstr, 1) && break
|
||||||
|
|
||||||
|
γgh = __find_firstnz(mstr[γ_basis_idx, gh], inv_vecs)
|
||||||
|
γg = __find_firstnz(mstr[γ_basis_idx, b[g]], inv_vecs)
|
||||||
|
γh = __find_firstnz(mstr[γ_basis_idx, b[h]], inv_vecs)
|
||||||
|
|
||||||
|
JuMP.@constraint model y[γgh] + y[γ] == y[γg] + y[γh]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
"""
|
"""
|
||||||
sos_problem_primal(X, [u = zero(X); upper_bound=Inf])
|
sos_problem_primal(X, [u = zero(X); upper_bound=Inf])
|
||||||
Formulate sum of squares decomposition problem for `X - λ·u`.
|
Formulate sum of squares decomposition problem for `X - λ·u`.
|
||||||
@ -147,10 +233,11 @@ function sos_problem_primal(
|
|||||||
upper_bound = Inf,
|
upper_bound = Inf,
|
||||||
augmented::Bool = iszero(StarAlgebras.aug(elt)) &&
|
augmented::Bool = iszero(StarAlgebras.aug(elt)) &&
|
||||||
iszero(StarAlgebras.aug(order_unit)),
|
iszero(StarAlgebras.aug(order_unit)),
|
||||||
|
support = 1:size(parent(elt).mstructure, 1),
|
||||||
)
|
)
|
||||||
@assert parent(elt) === parent(order_unit)
|
@assert parent(elt) === parent(order_unit)
|
||||||
|
|
||||||
N = LinearAlgebra.checksquare(parent(elt).mstructure)
|
N = length(support)
|
||||||
model = JuMP.Model()
|
model = JuMP.Model()
|
||||||
P = JuMP.@variable(model, P[1:N, 1:N], Symmetric)
|
P = JuMP.@variable(model, P[1:N, 1:N], Symmetric)
|
||||||
JuMP.@constraint(model, psd, P in PSDCone())
|
JuMP.@constraint(model, psd, P in PSDCone())
|
||||||
@ -159,11 +246,11 @@ function sos_problem_primal(
|
|||||||
@warn "Setting `upper_bound` together with zero `order_unit` has no effect"
|
@warn "Setting `upper_bound` together with zero `order_unit` has no effect"
|
||||||
end
|
end
|
||||||
|
|
||||||
A = constraints(parent(elt); augmented = augmented)
|
A = constraints(parent(elt), support; augmented = augmented)
|
||||||
|
|
||||||
if !iszero(order_unit)
|
if !iszero(order_unit)
|
||||||
λ = JuMP.@variable(model, λ)
|
λ = JuMP.@variable(model, λ)
|
||||||
if isfinite(upper_bound)
|
if !isfinite(upper_bound)
|
||||||
JuMP.@constraint model λ <= upper_bound
|
JuMP.@constraint model λ <= upper_bound
|
||||||
end
|
end
|
||||||
JuMP.@objective(model, Max, λ)
|
JuMP.@objective(model, Max, λ)
|
||||||
@ -282,9 +369,9 @@ function sos_problem_primal(
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
id_one = findfirst(invariant_vectors(wedderburn)) do v
|
id_one = let b = basis(parent(elt)), iv = invariant_vectors(wedderburn)
|
||||||
b = basis(parent(elt))
|
id_v = sparsevec([b[one(first(b))]], [1 // 1], length(first(iv)))
|
||||||
return sparsevec([b[one(first(b))]], [1 // 1], length(v)) == v
|
findfirst(==(id_v), iv)
|
||||||
end
|
end
|
||||||
|
|
||||||
prog = ProgressMeter.Progress(
|
prog = ProgressMeter.Progress(
|
||||||
@ -303,12 +390,12 @@ function sos_problem_primal(
|
|||||||
if !feasibility_problem # add λ or not?
|
if !feasibility_problem # add λ or not?
|
||||||
λ = JuMP.@variable(model, λ)
|
λ = JuMP.@variable(model, λ)
|
||||||
JuMP.@objective(model, Max, λ)
|
JuMP.@objective(model, Max, λ)
|
||||||
|
end
|
||||||
if isfinite(upper_bound)
|
if isfinite(upper_bound)
|
||||||
JuMP.@constraint(model, λ <= upper_bound)
|
|
||||||
if feasibility_problem
|
if feasibility_problem
|
||||||
@warn "setting `upper_bound` with zero `orderunit` has no effect"
|
@warn "setting `upper_bound` with zero `orderunit` has no effect"
|
||||||
end
|
else
|
||||||
|
JuMP.@constraint(model, ub, λ <= upper_bound)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user