Skip to content

Commit bd2fbcd

Browse files
authored
Variable-wise bounds for putinar (#282)
* Variable-wise bounds for putinar * Fixes * Fix * Fixes * Exclude sparsity tests * Fixes * Fix format * Fix * Fixes * Fix * Update solver failing tests * Fix format * Reenable CSDP tests They are fixed by jump-dev/CSDP.jl#89 * Fixes * Fix certificate example CSDP fails because an empty constraint is added * Remove polynomial optimization tutorial * Fix doc
1 parent 5d12b9d commit bd2fbcd

File tree

22 files changed

+822
-762
lines changed

22 files changed

+822
-762
lines changed

docs/Project.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Cyclotomics = "da8f5974-afbb-4dc8-91d8-516d5257c83b"
77
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
88
DifferentialEquations = "0c46a032-eb83-5123-abaf-570d42b7fbaa"
99
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
10+
Dualization = "191a621a-6537-11e9-281d-650236a99e60"
1011
DynamicPolynomials = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
1112
GroupsCore = "d5909c97-4eac-4ecc-a3dc-fdd0858a4120"
1213
HomotopyContinuation = "f213a82b-91d6-5c5d-acf7-10f1c761b327"
@@ -21,6 +22,7 @@ MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
2122
PermutationGroups = "8bc5a954-2dfc-11e9-10e6-cd969bffa420"
2223
Plots = "91a5bcdd-55d7-5caf-9e0b-520d859cae80"
2324
RecipesBase = "3cdcf5f2-1ef4-517c-9805-6587b60abb01"
25+
SCS = "c946c3f1-0d1f-5ce8-9dea-7daa1f7e2d13"
2426
SpecialFunctions = "276daf66-3868-5448-9aa4-cd146d93841b"
2527
SumOfSquares = "4b9e565b-77fc-50a5-a571-1244f986bda1"
2628
SymbolicWedderburn = "858aa9a9-4c7c-4c62-b466-2421203962a2"

docs/src/tutorials/Extension/certificate.jl

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -17,26 +17,40 @@
1717
using Test #src
1818
using DynamicPolynomials
1919
@polyvar x y
20-
p = x^3 - x^2 + 2x*y -y^2 + y^3 + x^3 * y
20+
p = x^3 - x^2 + 2x*y - y^2 + y^3 + x^3 * y
2121
using SumOfSquares
2222
S = @set x >= 0 && y >= 0 && x^2 + y^2 >= 2
2323

2424
# We will now see how to find the optimal solution using Sum of Squares Programming.
2525
# We first need to pick an SDP solver, see [here](https://jump.dev/JuMP.jl/v1.8/installation/#Supported-solvers) for a list of the available choices.
26-
27-
import CSDP
28-
solver = optimizer_with_attributes(CSDP.Optimizer, MOI.Silent() => true)
26+
# Note that SumOfSquares generates a *standard form* SDP (i.e., SDP variables
27+
# and equality constraints) while SCS expects a *geometric form* SDP (i.e.,
28+
# free variables and symmetric matrices depending affinely on these variables
29+
# constrained to belong to the PSD cone).
30+
# JuMP will transform the standard from to the geometric form will create the PSD
31+
# variables as free variables and then constrain then to be PSD.
32+
# While this will work, since the dual of a standard from is in in geometric form,
33+
# dualizing the problem will generate a smaller SDP.
34+
# We use therefore `Dualization.dual_optimizer` so that SCS solves the dual problem.
35+
36+
import SCS
37+
using Dualization
38+
solver = dual_optimizer(SCS.Optimizer)
2939

3040
# 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.
41+
# The following program searches for the largest lower bound.
3242

3343
model = SOSModel(solver)
3444
@variable(model, α)
3545
@objective(model, Max, α)
3646
@constraint(model, c, p >= α, domain = S)
3747
optimize!(model)
38-
@show termination_status(model)
39-
@show objective_value(model)
48+
49+
# We can see that the problem is infeasible, meaning that no lower bound was found.
50+
51+
@test termination_status(model) == MOI.INFEASIBLE #src
52+
@test dual_status(model) == MOI.INFEASIBILITY_CERTIFICATE #src
53+
solution_summary(model)
4054

4155
# We now define the Schmüdgen's certificate:
4256

@@ -91,6 +105,8 @@ ideal_certificate = SOSC.Newton(SOSCone(), MB.MonomialBasis, tuple())
91105
certificate = Schmüdgen(ideal_certificate, SOSCone(), MB.MonomialBasis, maxdegree(p))
92106
@constraint(model, c, p >= α, domain = S, certificate = certificate)
93107
optimize!(model)
94-
@show termination_status(model)
95-
@show objective_value(model)
108+
@test termination_status(model) == MOI.OPTIMAL #src
109+
@test primal_status(model) == MOI.FEASIBLE_POINT #src
110+
@test objective_value(model) 0.8284 rtol=1e-3 #src
96111
@test length(lagrangian_multipliers(c)) == 7 #src
112+
solution_summary(model)

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

Lines changed: 0 additions & 220 deletions
This file was deleted.

src/Bridges/Constraint/empty.jl

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
1-
struct EmptyBridge{T} <: MOI.Bridges.Constraint.AbstractBridge end
1+
struct EmptyBridge{T,F<:MOI.AbstractVectorFunction} <:
2+
MOI.Bridges.Constraint.AbstractBridge end
23

34
function MOI.Bridges.Constraint.bridge_constraint(
4-
::Type{EmptyBridge{T}},
5+
::Type{EmptyBridge{T,F}},
56
model::MOI.ModelLike,
6-
f::MOI.AbstractVectorFunction,
7+
f::F,
78
s::SOS.EmptyCone,
8-
) where {T}
9+
) where {T,F}
910
@assert MOI.output_dimension(f) == MOI.dimension(s)
10-
return EmptyBridge{T}()
11+
return EmptyBridge{T,F}()
1112
end
1213

1314
function MOI.supports_constraint(
@@ -25,14 +26,28 @@ function MOI.Bridges.added_constraint_types(::Type{<:EmptyBridge})
2526
end
2627
function MOI.Bridges.Constraint.concrete_bridge_type(
2728
::Type{<:EmptyBridge{T}},
28-
::Type{<:MOI.AbstractVectorFunction},
29+
::Type{F},
2930
::Type{SOS.EmptyCone},
30-
) where {T}
31-
return EmptyBridge{T}
31+
) where {T,F<:MOI.AbstractVectorFunction}
32+
return EmptyBridge{T,F}
3233
end
3334

3435
# Indices
35-
function MOI.delete(model::MOI.ModelLike, bridge::EmptyBridge) end
36+
function MOI.delete(::MOI.ModelLike, ::EmptyBridge) end
37+
38+
function _empty_function(::Type{MOI.VectorOfVariables})
39+
return MOI.VectorOfVariables(MOI.VariableIndex[])
40+
end
41+
function _empty_function(::Type{F}) where {F}
42+
return MOI.Utilities.zero_with_output_dimension(F, 0)
43+
end
44+
function MOI.get(
45+
::MOI.ModelLike,
46+
::MOI.ConstraintFunction,
47+
::EmptyBridge{T,F},
48+
) where {T,F}
49+
return _empty_function(F)
50+
end
3651

3752
function MOI.get(
3853
::MOI.ModelLike,

src/Bridges/Constraint/sos_polynomial.jl

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,16 @@ function MOI.get(
161161
end
162162

163163
# Indices
164-
_delete_variables(model, Q::Vector{MOI.VariableIndex}) = MOI.delete(model, Q)
164+
function _delete_variables(model, Q::Vector{MOI.VariableIndex})
165+
if !isempty(Q)
166+
# FIXME Since there is not variables in the list, we cannot
167+
# identify the `EmptyBridge` to delete
168+
MOI.delete(model, Q)
169+
end
170+
end
165171
function _delete_variables(model, Qs::Vector{Vector{MOI.VariableIndex}})
166172
for Q in Qs
167-
MOI.delete(model, Q)
173+
_delete_variables(model, Q)
168174
end
169175
end
170176
function MOI.delete(model::MOI.ModelLike, bridge::SOSPolynomialBridge)

src/Bridges/Variable/scaled_diagonally_dominant.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,8 @@
88
99
A matrix is SDD iff it is the sum of psd matrices Mij that are zero except
1010
for entries ii, ij and jj [Lemma 9, AM17]. This bridge substitute the
11-
constrained variables in [`SumOfSquares.ScaledDiagonallyDominantConeTriangle`](@ref)
12-
into a sum of constrained variables in [`SumOfSquares.PositiveSemidefinite2x2ConeTriangle`](@ref).
11+
constrained variables in [`SOS.ScaledDiagonallyDominantConeTriangle`](@ref)
12+
into a sum of constrained variables in [`SOS.PositiveSemidefinite2x2ConeTriangle`](@ref).
1313
1414
[AM17] Ahmadi, A. A. & Majumdar, A.
1515
*DSOS and SDSOS Optimization: More Tractable Alternatives to Sum of Squares and Semidefinite Optimization*

0 commit comments

Comments
 (0)