Skip to content

Commit def6f44

Browse files
committed
Fix sos constraint with FixedVariablesSet
1 parent 75c904f commit def6f44

File tree

5 files changed

+81
-1
lines changed

5 files changed

+81
-1
lines changed

src/sos_polynomial_bridge.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,12 @@ function SOSPolynomialBridge{T, F, DT, VBS, MCT, BT, MT, MVT}(
2222
}
2323
@assert MOI.output_dimension(f) == length(s.monomials)
2424
p = MP.polynomial(collect(MOIU.eachscalar(f)), s.monomials)
25+
# As `*(::MOI.ScalarAffineFunction{T}, ::S)` is only defined if `S == T`, we
26+
# need to call `changecoefficienttype`. This is critical since `T` is
27+
# `Float64` when used with JuMP and the coefficient type is often `Int` if
28+
# `set.domain.V` is `FullSpace` or `FixedPolynomialsSet`.
2529
# FIXME convert needed because the coefficient type of `r` is `Any` otherwise if `domain` is `AlgebraicSet`
26-
r = convert(typeof(p), rem(p, ideal(s.domain)))
30+
r = convert(typeof(p), rem(p, ideal(MP.changecoefficienttype(s.domain, T))))
2731
X = monomials_half_newton_polytope(MP.monomials(r), s.newton_polytope)
2832
Q, variable_bridge = add_matrix_variable_bridge(model, MCT, length(X), T)
2933
g = build_gram_matrix(Q, X)

test/Mock/mock_tests.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ using Test, JuMP
66
@testset "Term" begin
77
include("term.jl")
88
end
9+
@testset "Term fixed" begin
10+
include("term_fixed.jl")
11+
end
912
@testset "Bivariate quadratic" begin
1013
include("bivariate_quadratic.jl")
1114
end

test/Mock/term_fixed.jl

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
config = MOI.Test.TestConfig()
2+
optimize!(mock) = MOIU.mock_optimize!(mock, [1.0, 0.0],
3+
(MOI.VectorAffineFunction{Float64}, MOI.Nonnegatives) => [[1.0]],
4+
(MOI.VectorAffineFunction{Float64}, MOI.Zeros) => [[1.0]])
5+
mock = bridged_mock(optimize!)
6+
Tests.sos_term_fixed_test(mock, config)
7+
Tests.sdsos_term_fixed_test(mock, config)
8+
Tests.dsos_term_fixed_test(mock, config)

test/Tests/Tests.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ const soc_tests = Dict{String, Function}()
77
const sd_tests = Dict{String, Function}()
88

99
include("term.jl")
10+
include("term_fixed.jl")
1011
include("bivariate_quadratic.jl")
1112
include("horn.jl")
1213
include("concave_then_convex_cubic.jl")

test/Tests/term_fixed.jl

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
using Test
2+
using SumOfSquares
3+
using DynamicPolynomials
4+
5+
# Like `term_test` but with a variable `y` fixed to 1.
6+
function term_fixed_test(
7+
optimizer, config::MOIT.TestConfig, cone::SumOfSquares.PolyJuMP.PolynomialSet)
8+
atol = config.atol
9+
rtol = config.rtol
10+
11+
model = _model(optimizer)
12+
13+
@variable(model, α)
14+
15+
@polyvar x y
16+
set = @set y == 1
17+
cref = @constraint(model, (α - 1) * x^2 * y in cone, domain = set)
18+
19+
@objective(model, Min, α)
20+
optimize!(model)
21+
22+
@test termination_status(model) == MOI.OPTIMAL
23+
@test objective_value(model) 1.0 atol=atol rtol=rtol
24+
25+
@test primal_status(model) == MOI.FEASIBLE_POINT
26+
@test value(α) 1.0 atol=atol rtol=rtol
27+
28+
@test_throws SumOfSquares.ValueNotSupported value(cref)
29+
p = gram_matrix(cref)
30+
@test getmat(p) zeros(1, 1) atol=atol rtol=rtol
31+
@test p.x == [x]
32+
33+
@test dual_status(model) == MOI.FEASIBLE_POINT
34+
for (m, μ) in [(x^2 * y, dual(cref)), (x^2, moments(cref))]
35+
@test μ isa AbstractMeasure{Float64}
36+
@test length(moments(μ)) == 1
37+
@test moment_value(moments(μ)[1]) 1.0 atol=atol rtol=rtol
38+
@test monomial(moments(μ)[1]) == m
39+
end
40+
41+
ν = moment_matrix(cref)
42+
@test getmat(ν) ones(1, 1) atol=atol rtol=rtol
43+
@test ν.x == [x]
44+
45+
S = SumOfSquares.SOSPolynomialSet{
46+
SumOfSquares.typeof(set), typeof(cone), SumOfSquares.MonomialBasis,
47+
Monomial{true},MonomialVector{true},Tuple{}
48+
}
49+
@test list_of_constraint_types(model) == [(Vector{JuMP.AffExpr}, S)]
50+
test_delete_bridge(
51+
model, cref, 1,
52+
((MOI.VectorOfVariables, MOI.Nonnegatives, 0),
53+
(MOI.VectorAffineFunction{Float64},
54+
SumOfSquares.PolyJuMP.ZeroPolynomialSet{
55+
typeof(set), SumOfSquares.MonomialBasis,
56+
Monomial{true}, MonomialVector{true}},
57+
0)))
58+
end
59+
sos_term_fixed_test(optimizer, config) = term_fixed_test(optimizer, config, SOSCone())
60+
sd_tests["sos_term_fixed"] = sos_term_fixed_test
61+
sdsos_term_fixed_test(optimizer, config) = term_fixed_test(optimizer, config, SDSOSCone())
62+
soc_tests["sdsos_term_fixed"] = sdsos_term_fixed_test
63+
dsos_term_fixed_test(optimizer, config) = term_fixed_test(optimizer, config, DSOSCone())
64+
linear_tests["dsos_term_fixed"] = dsos_term_fixed_test

0 commit comments

Comments
 (0)