Skip to content

Commit 766dbba

Browse files
committed
Add Schmüdgen certificate
1 parent f1d1ed1 commit 766dbba

File tree

2 files changed

+105
-2
lines changed

2 files changed

+105
-2
lines changed
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
# # Certificate
2+
3+
#md # [![](https://mybinder.org/badge_logo.svg)](@__BINDER_ROOT_URL__/generated/Extension/certificate.ipynb)
4+
#md # [![](https://img.shields.io/badge/show-nbviewer-579ACA.svg)](@__NBVIEWER_ROOT_URL__/generated/Extension/certificate.ipynb)
5+
# **Contributed by**: Benoît Legat
6+
7+
# ## Introduction
8+
9+
# Consider the polynomial optimization problem (a variation from [L09, Example 2.2]) of
10+
# minimizing the polynomial $x^3 - x^2 + 2xy - y^2 + y^3$
11+
# over the polyhedron defined by the inequalities $x \ge 0, y \ge 0$ and $x + y \geq 1$.
12+
13+
# [L09] Lasserre, J. B.
14+
# *Moments, positive polynomials and their applications*.
15+
# World Scientific, **2009**.
16+
17+
using Test #src
18+
using DynamicPolynomials
19+
@polyvar x y
20+
p = x^3 - x^2 + 2x*y -y^2 + y^3 + x^3 * y
21+
using SumOfSquares
22+
S = @set x >= 0 && y >= 0 && x^2 + y^2 >= 2
23+
24+
# We will now see how to find the optimal solution using Sum of Squares Programming.
25+
# We first need to pick an SDP solver, see [here](https://jump.dev/JuMP.jl/v0.21.6/installation/#Supported-solvers) for a list of the available choices.
26+
27+
import CSDP
28+
solver = optimizer_with_attributes(CSDP.Optimizer, MOI.Silent() => true)
29+
30+
# A Sum-of-Squares certificate that $p \ge \alpha$ over the domain `S`, ensures that $\alpha$ is a lower bound to the polynomial optimization problem.
31+
# The following program searches for the largest upper bound and finds zero.
32+
33+
model = SOSModel(solver)
34+
@variable(model, α)
35+
@objective(model, Max, α)
36+
@constraint(model, c, p >= α, domain = S)
37+
optimize!(model)
38+
@show termination_status(model)
39+
@show objective_value(model)
40+
41+
# We now define the Schmüdgen's certificate:
42+
43+
using MultivariateBases
44+
const MB = MultivariateBases
45+
const SOS = SumOfSquares
46+
const SOSC = SOS.Certificate
47+
struct Schmüdgen{IC <: SOSC.AbstractIdealCertificate, CT <: SOS.SOSLikeCone, BT <: SOS.AbstractPolynomialBasis} <: SOSC.AbstractPreorderCertificate
48+
ideal_certificate::IC
49+
cone::CT
50+
basis::Type{BT}
51+
maxdegree::Int
52+
end
53+
54+
SOSC.get(certificate::Schmüdgen, ::SOSC.Cone) = certificate.cone
55+
56+
function SOSC.get(::Schmüdgen, ::SOSC.PreprocessedDomain, domain::BasicSemialgebraicSet, p)
57+
return SOSC.DomainWithVariables(domain, variables(p))
58+
end
59+
60+
function SOSC.get(::Schmüdgen, ::SOSC.PreorderIndices, domain::SOSC.DomainWithVariables)
61+
n = length(domain.domain.p)
62+
if n >= Sys.WORD_SIZE
63+
error("There are $(2^n - 1) products in Schmüdgen's certificate, they cannot even be indexed with `$Int`.")
64+
end
65+
return map(SOSC.PreorderIndex, 1:(2^n-1))
66+
end
67+
68+
function SOSC.get(certificate::Schmüdgen, ::SOSC.MultiplierBasis, index::SOSC.PreorderIndex, domain::SOSC.DomainWithVariables)
69+
q = SOSC.get(certificate, SOSC.Generator(), index, domain)
70+
vars = sort!([domain.variables..., variables(q)...], rev = true)
71+
unique!(vars)
72+
return SOSC.maxdegree_gram_basis(certificate.basis, vars, SOSC.multiplier_maxdegree(certificate.maxdegree, q))
73+
end
74+
function SOSC.get(::Type{Schmüdgen{IC, CT, BT}}, ::SOSC.MultiplierBasisType) where {IC, CT, BT}
75+
return BT
76+
end
77+
78+
function SOSC.get(::Schmüdgen, ::SOSC.Generator, index::SOSC.PreorderIndex, domain::SOSC.DomainWithVariables)
79+
I = [i for i in eachindex(domain.domain.p) if !iszero(index.value & (1 << (i - 1)))]
80+
return prod([domain.domain.p[i] for i in eachindex(domain.domain.p) if !iszero(index.value & (1 << (i - 1)))])
81+
end
82+
83+
SOSC.get(certificate::Schmüdgen, ::SOSC.IdealCertificate) = certificate.ideal_certificate
84+
SOSC.get(::Type{<:Schmüdgen{IC}}, ::SOSC.IdealCertificate) where {IC} = IC
85+
86+
SOS.matrix_cone_type(::Type{<:Schmüdgen{IC, CT}}) where {IC, CT} = SOS.matrix_cone_type(CT)
87+
88+
# Let's try again with our the Schmüdgen certificate:
89+
90+
model = SOSModel(solver)
91+
@variable(model, α)
92+
@objective(model, Max, α)
93+
ideal_certificate = SOSC.Newton(SOSCone(), MB.MonomialBasis, tuple())
94+
certificate = Schmüdgen(ideal_certificate, SOSCone(), MB.MonomialBasis, maxdegree(p))
95+
@constraint(model, c, p >= α, domain = S, certificate = certificate)
96+
optimize!(model)
97+
@show termination_status(model)
98+
@show objective_value(model)
99+
@test length(lagrangian_multipliers(c)) == 7 #src

docs/src/tutorials/Polynomial Optimization/polynomial_optimization.jl

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,14 @@
66

77
# ## Introduction
88

9-
# Consider the polynomial optimization problem of
10-
# minimizing the polynomial $x^3 - x^2 + 2xy -y^2 + y^3$
9+
# Consider the polynomial optimization problem [L09, Example 2.2] of
10+
# minimizing the polynomial $x^3 - x^2 + 2xy - y^2 + y^3$
1111
# over the polyhedron defined by the inequalities $x \ge 0, y \ge 0$ and $x + y \geq 1$.
1212

13+
# [L09] Lasserre, J. B.
14+
# *Moments, positive polynomials and their applications*.
15+
# World Scientific, **2009**.
16+
1317
using Test #src
1418
using DynamicPolynomials
1519
@polyvar x y

0 commit comments

Comments
 (0)