Skip to content

Commit 4bf3245

Browse files
committed
Fix creation of polynomials with grammonomials keyword
1 parent ff18504 commit 4bf3245

File tree

7 files changed

+80
-19
lines changed

7 files changed

+80
-19
lines changed

src/constraint.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ addpolynonnegativeconstraint{T<:VectorOfPolyType{false}}(m::JuMP.Model, P::Matri
3030
addpolynonnegativeconstraint{T<:VectorOfPolyType{true}}(m::JuMP.Model, P::Matrix{T}, domain::BasicSemialgebraicSet) = matconstraux(PolyVar{true}, m, P, domain)
3131

3232
function addpolynonnegativeconstraint(m::JuMP.Model, p, domain::BasicSemialgebraicSet)
33-
# TODO We might want to add this as a function in MultivariatePolynomials.jl
3433
mindeg, maxdeg = extdeg(p)
3534
for q in domain.p
3635
mindegq, maxdegq = extdeg(q)
@@ -44,6 +43,7 @@ function addpolynonnegativeconstraint(m::JuMP.Model, p, domain::BasicSemialgebra
4443
s = createnonnegativepoly(m, :Gram, MonomialVector(vars(p), mind:maxd))
4544
p -= s*q
4645
end
46+
# FIXME If p is a MatPolynomial, p.x will not be correct
4747
Z = getmonomialsforcertificate(p.x)
4848
slack = createnonnegativepoly(m, :Gram, Z)
4949
q = p - slack

src/variable.jl

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ function createpoly{C}(m::JuMP.Model, monotype::Symbol, x::MonomialVector{C})
66
end
77
gram = monotype == :Gram
88
if gram
9-
Z = dot(x, x).x
9+
Z = (sum(x)^2).x
1010
else
1111
Z = x
1212
end
@@ -15,21 +15,27 @@ end
1515
createpoly(m::JuMP.Model, monotype::Symbol, x::Vector) = createpoly(m, monotype, MonomialVector(x))
1616

1717
function createnonnegativepoly{C}(m::JuMP.Model, monotype::Symbol, x::MonomialVector{C})
18-
if monotype == :Default
19-
monotype = :Gram
20-
end
21-
gram = monotype == :Gram
22-
if gram
23-
Z = x
18+
if isempty(x)
19+
# Need MultivariatePolynomials v0.0.2
20+
#zero(MatPolynomial{C, JuMP.Variable})
21+
MatPolynomial(JuMP.Variable[], x)
2422
else
25-
Z = getmonomialsforcertificate(x)
26-
end
27-
p = MatPolynomial{C, JuMP.Variable}((i, j) -> Variable(m, -Inf, Inf, :Cont), Z)
28-
push!(m.varCones, (:SDP, p.Q[1].col:p.Q[end].col))
29-
if !gram
30-
# The coefficients of a monomial not in Z do not all have to be zero, only their sum
31-
addpolyeqzeroconstraint(m, removemonomials(Polynomial(p), x))
23+
if monotype == :Default
24+
monotype = :Gram
25+
end
26+
gram = monotype == :Gram
27+
if gram
28+
Z = x
29+
else
30+
Z = getmonomialsforcertificate(x)
31+
end
32+
p = MatPolynomial{C, JuMP.Variable}((i, j) -> Variable(m, -Inf, Inf, :Cont), Z)
33+
push!(m.varCones, (:SDP, p.Q[1].col:p.Q[end].col))
34+
if !gram
35+
# The coefficients of a monomial not in Z do not all have to be zero, only their sum
36+
addpolyeqzeroconstraint(m, removemonomials(Polynomial(p), x))
37+
end
38+
p
3239
end
33-
p
3440
end
3541
createnonnegativepoly(m::JuMP.Model, monotype::Symbol, x::Vector) = createnonnegativepoly(m, monotype, MonomialVector(x))

test/constraint.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
@testset "Non-symmetric matrix SOS constraint with $solver" for solver in sdp_solvers
1+
@testset "Non-symmetric matrix SOS constraint" begin
22
@polyvar x
33
m = SOSModel()
44
@test_throws ArgumentError addpolynonnegativeconstraint(m, [1 x; -x 0], BasicSemialgebraicSet())

test/lyapunov.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
include("switchedsystems.jl")
2+
#include("sosdemo2.jl")

test/runtests.jl

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,16 +4,18 @@ using SumOfSquares
44
using PolyJuMP
55
using Base.Test
66

7+
include("variable.jl")
8+
include("constraint.jl")
9+
710
include("solvers.jl")
811

912
include("certificate.jl")
10-
include("constraint.jl")
1113

1214
include("motzkin.jl")
1315

1416
# SOSTools demos
1517
include("sospoly.jl")
16-
include("sosdemo2.jl")
18+
include("lyapunov.jl")
1719
include("sosdemo3.jl")
1820
include("sosdemo4.jl")
1921
include("sosdemo5.jl")

test/switchedsystems.jl

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
# See https://github.com/blegat/SwitchedSystems.jl
2+
3+
# Example 2.8 of
4+
# P. Parrilo and A. Jadbabaie
5+
# Approximation of the joint spectral radius using sum of squares
6+
# Linear Algebra and its Applications, Elsevier, 2008, 428, 2385-2402
7+
# Inspired from the construction of:
8+
# Ando, T. and Shih, M.-h.
9+
# Simultaneous Contractibility.
10+
# SIAM Journal on Matrix Analysis & Applications, 1998, 19, 487
11+
# The JSR is √2
12+
13+
@testset "[PJ08] Example 2.8 with $solver" for solver in sdp_solvers
14+
@polyvar x[1:2]
15+
A1 = [1 0; 1 0]
16+
A2 = [0 1; 0 -1]
17+
expected_ub = [2, 1]
18+
function testlyap(d, γ, expected_status)
19+
m = SOSModel(solver = solver)
20+
X = monomials(x, d)
21+
@polyvariable(m, p, grammonomials = X)
22+
# p strictly positive
23+
q = sum(x.^(2*d))
24+
@polyconstraint m p >= q
25+
c1 = @polyconstraint m p(A1 * x, x) <= γ^(2*d) * p
26+
c2 = @polyconstraint m p(A2 * x, x) <= γ^(2*d) * p
27+
28+
@test expected_status == solve(m; suppress_warnings=true)
29+
30+
if expected_status == :Infeasible
31+
μ1 = getdual(c1)
32+
μ2 = getdual(c2)
33+
34+
# The dual constraint should work on any polynomial.
35+
# Let's test it with q
36+
lhs = dot(μ1, q(A1 * x, x)) + dot(μ2, q(A2 * x, x))
37+
rhs = dot(μ1, q) + dot(μ2, q)
38+
@test 1e-6 * max(abs(lhs), abs(rhs)) + lhs >= rhs
39+
end
40+
end
41+
testlyap(1, 2 - 1e-4, :Infeasible)
42+
testlyap(1, 2 + 1e-3, :Optimal)
43+
testlyap(2, 1 - 1e-3, :Infeasible)
44+
testlyap(2, 1 + 1e-2, :Optimal)
45+
end

test/variable.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
@testset "Creating polynomial with empty MonomialVector" begin
2+
x = MonomialVector{true}()
3+
m = SOSModel()
4+
@inferred createnonnegativepoly(m, :Gram, x)
5+
@test createnonnegativepoly(m, :Gram, x) == 0
6+
end

0 commit comments

Comments
 (0)