From 68939f2e4da8befd3833eaac46fba0ecabaa564e Mon Sep 17 00:00:00 2001 From: Oscar Dowson Date: Mon, 4 Mar 2024 22:54:07 +1300 Subject: [PATCH] Fix final_touch if no higher-order polynomials are present (#109) * Fix final_touch if no higher-order polynomials are present * Add test --- src/QCQP/MOI_wrapper.jl | 38 ++++++++++++++++++++------------------ test/qcqp.jl | 13 +++++++++++++ 2 files changed, 33 insertions(+), 18 deletions(-) diff --git a/src/QCQP/MOI_wrapper.jl b/src/QCQP/MOI_wrapper.jl index 9e6d25d..cb1e79f 100644 --- a/src/QCQP/MOI_wrapper.jl +++ b/src/QCQP/MOI_wrapper.jl @@ -318,25 +318,27 @@ function MOI.Utilities.final_touch(model::Optimizer{T}, _) where {T} end end end - div = decompose(monos) - for mono in sort(collect(keys(div))) - if haskey(vars, mono) - continue + if !isnothing(monos) + div = decompose(monos) + for mono in sort(collect(keys(div))) + if haskey(vars, mono) + continue + end + a = div[mono] + monomial_variable_index(model, vars, div, a) + b = MP.div_multiple(mono, a) + monomial_variable_index(model, vars, div, b) + end + if !isnothing(model.objective) + func, index_to_var = _subs!(model.objective, index_to_var) + obj = _quad_convert(func.polynomial, vars, div) + MOI.set(model.model, MOI.ObjectiveFunction{typeof(obj)}(), obj) + end + for S in keys(model.constraints) + F = PolyJuMP.ScalarPolynomialFunction{T,model.constraints[S][1]} + cis = MOI.get(model, MOI.ListOfConstraintIndices{F,S}()) + _add_constraints(model, cis, index_to_var, vars, div) end - a = div[mono] - monomial_variable_index(model, vars, div, a) - b = MP.div_multiple(mono, a) - monomial_variable_index(model, vars, div, b) - end - if !isnothing(model.objective) - func, index_to_var = _subs!(model.objective, index_to_var) - obj = _quad_convert(func.polynomial, vars, div) - MOI.set(model.model, MOI.ObjectiveFunction{typeof(obj)}(), obj) - end - for S in keys(model.constraints) - F = PolyJuMP.ScalarPolynomialFunction{T,model.constraints[S][1]} - cis = MOI.get(model, MOI.ListOfConstraintIndices{F,S}()) - _add_constraints(model, cis, index_to_var, vars, div) end return end diff --git a/test/qcqp.jl b/test/qcqp.jl index 427111c..45af152 100644 --- a/test/qcqp.jl +++ b/test/qcqp.jl @@ -144,6 +144,19 @@ function test_objective_and_constraint(x, y, T) o * a3 * b3 + o * a6 end +function test_no_monomials(x, y, T) + inner = Model{T}() + model = PolyJuMP.JuMP.GenericModel{T}() do + return PolyJuMP.QCQP.Optimizer{T}(MOI.Utilities.MockOptimizer(inner)) + end + PolyJuMP.@variable(model, 0 <= x[1:2] <= 1) + PolyJuMP.@constraint(model, x[1] * x[2] == 0.5) + PolyJuMP.@objective(model, Min, sum(x)) + PolyJuMP.optimize!(model) + @test MOI.get(inner, MOI.NumberOfVariables()) == 2 + return +end + function runtests(x, y) for name in names(@__MODULE__; all = true) if startswith("$name", "test_")