Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Polynomial to QCQP meta-solver #95

Merged
merged 10 commits into from
Oct 2, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ repo = "https://github.com/jump-dev/PolyJuMP.jl.git"
version = "0.7.0"

[deps]
DataStructures = "864edb3b-99cc-5e75-8d2d-829cb0a9cfe8"
DynamicPolynomials = "7c1d4256-1411-5781-91ec-d7bc3513ac07"
JuMP = "4076af6c-e467-56ae-b986-b466b2749572"
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
Expand All @@ -15,6 +16,7 @@ MutableArithmetics = "d8a4904e-b15c-11e9-3269-09a3773c0cb0"
SemialgebraicSets = "8e049039-38e8-557d-ae3a-bc521ccf6204"

[compat]
DataStructures = "0.18"
DynamicPolynomials = "0.5"
JuMP = "1"
MathOptInterface = "1"
Expand Down
1 change: 1 addition & 0 deletions src/PolyJuMP.jl
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,6 @@ include("default.jl")

include("model.jl")
include("KKT/KKT.jl")
include("QCQP/QCQP.jl")

end # module
347 changes: 347 additions & 0 deletions src/QCQP/MOI_wrapper.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,347 @@
import MathOptInterface as MOI

mutable struct Optimizer{T,O<:MOI.ModelLike} <: MOI.AbstractOptimizer
model::O
objective::Union{Nothing,PolyJuMP.ScalarPolynomialFunction{T}}
constraints::DataStructures.OrderedDict{
Type,
Tuple{Type,MOI.Utilities.VectorOfConstraints},
}
end

function Optimizer{T}(model::MOI.ModelLike) where {T}
return Optimizer{T,typeof(model)}(

Check warning on line 13 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L12-L13

Added lines #L12 - L13 were not covered by tests
model,
nothing,
DataStructures.OrderedDict{Type,MOI.Utilities.VectorOfConstraints}(),
)
end

Optimizer(model::MOI.ModelLike) = Optimizer{Float64}(model)

Check warning on line 20 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L20

Added line #L20 was not covered by tests

function MOI.get(

Check warning on line 22 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L22

Added line #L22 was not covered by tests
model::Optimizer{T},
attr::MOI.Bridges.ListOfNonstandardBridges,
) where {T}
list = copy(MOI.get(model.model, attr))
push!(list, PolyJuMP.Bridges.Constraint.ToPolynomialBridge{T})
push!(list, PolyJuMP.Bridges.Objective.ToPolynomialBridge{T})
return list

Check warning on line 29 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L26-L29

Added lines #L26 - L29 were not covered by tests
end

MOI.is_empty(model::Optimizer) = MOI.is_empty(model.model)
function MOI.empty!(model::Optimizer)
MOI.empty!(model.model)
model.objective = nothing
empty!(model.constraints)
return

Check warning on line 37 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L32-L37

Added lines #L32 - L37 were not covered by tests
end

MOI.is_valid(model::Optimizer, i::MOI.Index) = MOI.is_valid(model.model, i)
function MOI.is_valid(

Check warning on line 41 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L40-L41

Added lines #L40 - L41 were not covered by tests
model::Optimizer{T},
::MOI.ConstraintIndex{PolyJuMP.ScalarPolynomialFunction{T},S},
) where {T,S<:MOI.AbstractScalarSet}
return haskey(model.constraints, S) &&

Check warning on line 45 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L45

Added line #L45 was not covered by tests
MOI.is_valid(model.constraints[S][2], ci)
end

function MOI.get(

Check warning on line 49 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L49

Added line #L49 was not covered by tests
model::Optimizer,
attr::MOI.AbstractConstraintAttribute,
ci::MOI.ConstraintIndex,
)
return MOI.get(model.model, attr, ci)

Check warning on line 54 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L54

Added line #L54 was not covered by tests
end

MOI.add_variable(model::Optimizer) = MOI.add_variable(model.model)

Check warning on line 57 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L57

Added line #L57 was not covered by tests

function MOI.supports_add_constrained_variable(

Check warning on line 59 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L59

Added line #L59 was not covered by tests
model::Optimizer,
::Type{S},
) where {S<:MOI.AbstractScalarSet}
return MOI.supports_add_constrained_variable(model.model, S)

Check warning on line 63 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L63

Added line #L63 was not covered by tests
end

function MOI.supports_add_constrained_variables(

Check warning on line 66 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L66

Added line #L66 was not covered by tests
model::Optimizer,
::Type{MOI.Reals},
)
return MOI.supports_add_constrained_variables(model.model, MOI.Reals)

Check warning on line 70 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L70

Added line #L70 was not covered by tests
end

function MOI.supports_add_constrained_variables(

Check warning on line 73 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L73

Added line #L73 was not covered by tests
model::Optimizer,
::Type{S},
) where {S<:MOI.AbstractVectorSet}
return MOI.supports_add_constrained_variables(model.model, S)

Check warning on line 77 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L77

Added line #L77 was not covered by tests
end

function MOI.supports(model::Optimizer, attr::MOI.AbstractModelAttribute)
return MOI.supports(model.model, attr)

Check warning on line 81 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L80-L81

Added lines #L80 - L81 were not covered by tests
end

function MOI.supports(

Check warning on line 84 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L84

Added line #L84 was not covered by tests
::Optimizer,
::MOI.ObjectiveFunction{<:PolyJuMP.ScalarPolynomialFunction},
)
return true

Check warning on line 88 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L88

Added line #L88 was not covered by tests
end

function MOI.set(

Check warning on line 91 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L91

Added line #L91 was not covered by tests
model::Optimizer{T},
::MOI.ObjectiveFunction{F},
f::F,
) where {T,F<:PolyJuMP.ScalarPolynomialFunction{T}}
model.objective = f
return

Check warning on line 97 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L96-L97

Added lines #L96 - L97 were not covered by tests
end

function MOI.set(model::Optimizer, attr::MOI.AbstractModelAttribute, value)
return MOI.set(model.model, attr, value)

Check warning on line 101 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L100-L101

Added lines #L100 - L101 were not covered by tests
end

function MOI.get(model::Optimizer, attr::MOI.AbstractModelAttribute)
return MOI.get(model.model, attr)

Check warning on line 105 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L104-L105

Added lines #L104 - L105 were not covered by tests
end

function MOI.supports_constraint(

Check warning on line 108 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L108

Added line #L108 was not covered by tests
model::Optimizer,
::Type{F},
::Type{S},
) where {F<:MOI.AbstractFunction,S<:MOI.AbstractSet}
return MOI.supports_constraint(model.model, F, S)

Check warning on line 113 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L113

Added line #L113 was not covered by tests
end
function MOI.supports_constraint(

Check warning on line 115 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L115

Added line #L115 was not covered by tests
model::Optimizer{T},
::Type{<:PolyJuMP.ScalarPolynomialFunction{T}},
::Type{S},
) where {T,S<:MOI.AbstractScalarSet}
return MOI.supports_constraint(

Check warning on line 120 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L120

Added line #L120 was not covered by tests
model.model,
MOI.ScalarQuadraticFunction{T},
S,
)
end

function MOI.add_constraint(

Check warning on line 127 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L127

Added line #L127 was not covered by tests
model::Optimizer,
func::MOI.AbstractFunction,
set::MOI.AbstractSet,
)
return MOI.add_constraint(model.model, func, set)

Check warning on line 132 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L132

Added line #L132 was not covered by tests
end
function MOI.add_constraint(

Check warning on line 134 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L134

Added line #L134 was not covered by tests
model::Optimizer{T},
func::PolyJuMP.ScalarPolynomialFunction{T,P},
set::MOI.AbstractScalarSet,
) where {T,P}
F = typeof(func)
S = typeof(set)
if !haskey(model.constraints, S)
con = MOI.Utilities.VectorOfConstraints{F,S}()
model.constraints[S] = (P, con)

Check warning on line 143 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L139-L143

Added lines #L139 - L143 were not covered by tests
end
return MOI.add_constraint(model.constraints[S][2], func, set)

Check warning on line 145 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L145

Added line #L145 was not covered by tests
end

function MOI.get(

Check warning on line 148 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L148

Added line #L148 was not covered by tests
model::Optimizer{T},
attr::Union{MOI.ConstraintFunction,MOI.ConstraintSet},
ci::MOI.ConstraintIndex{<:PolyJuMP.ScalarPolynomialFunction{T},S},
) where {T,S}
return MOI.get(model.constraints[S][2], attr, ci)

Check warning on line 153 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L153

Added line #L153 was not covered by tests
end

function MOI.get(

Check warning on line 156 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L156

Added line #L156 was not covered by tests
model::Optimizer{T},
attr::MOI.ListOfConstraintIndices{<:PolyJuMP.ScalarPolynomialFunction{T},S},
) where {T,S<:MOI.AbstractScalarSet}
return MOI.get(model.constraints[S][2], attr)

Check warning on line 160 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L160

Added line #L160 was not covered by tests
end

function MOI.supports_incremental_interface(model::Optimizer)
return MOI.supports_incremental_interface(model.model)

Check warning on line 164 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L163-L164

Added lines #L163 - L164 were not covered by tests
end

function MOI.copy_to(dest::Optimizer, src::MOI.ModelLike)
return MOI.Utilities.default_copy_to(dest, src)

Check warning on line 168 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L167-L168

Added lines #L167 - L168 were not covered by tests
end

MOI.optimize!(model::Optimizer) = MOI.optimize!(model.model)

Check warning on line 171 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L171

Added line #L171 was not covered by tests

function _quad_convert(p::MP.AbstractPolynomialLike{T}, index, div) where {T}
q = zero(MOI.ScalarQuadraticFunction{T})
for t in MP.terms(p)
α = MP.coefficient(t)
mono = MP.monomial(t)
if MP.degree(mono) == 0
MA.operate!(+, q, α)

Check warning on line 179 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L173-L179

Added lines #L173 - L179 were not covered by tests
else
if haskey(index, mono)
MA.operate!(MA.add_mul, q, α, index[mono])

Check warning on line 182 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L181-L182

Added lines #L181 - L182 were not covered by tests
else
x = div[mono]
y = MP.div_multiple(mono, x)
MA.operate!(MA.add_mul, q, α, index[x], index[y])

Check warning on line 186 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L184-L186

Added lines #L184 - L186 were not covered by tests
end
end
end
return q

Check warning on line 190 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L189-L190

Added lines #L189 - L190 were not covered by tests
end

function _add_monomials!(p::PolyJuMP.ScalarPolynomialFunction, monos1)
monos2 = MP.monomials(p.polynomial)
if isnothing(monos1)
return monos2

Check warning on line 196 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L193-L196

Added lines #L193 - L196 were not covered by tests
else
return MP.merge_monomial_vectors([monos1, monos2])

Check warning on line 198 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L198

Added line #L198 was not covered by tests
end
end

function _subs!(

Check warning on line 202 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L202

Added line #L202 was not covered by tests
p::PolyJuMP.ScalarPolynomialFunction{T,P},
::Nothing,
) where {T,P}
return p,

Check warning on line 206 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L206

Added line #L206 was not covered by tests
Dict{MOI.VariableIndex,MP.variable_union_type(P)}(
vi => var for (vi, var) in zip(p.variables, MP.variables(p.polynomial))
)
end

function _subs!(

Check warning on line 212 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L212

Added line #L212 was not covered by tests
p::PolyJuMP.ScalarPolynomialFunction,
index_to_var::Dict{K,V},
) where {K,V}
old_var = V[]
new_var = V[]
for (vi, var) in zip(p.variables, MP.variables(p.polynomial))
if haskey(index_to_var, vi)
if var != index_to_var[vi]
push!(old_var, var)
push!(new_var, index_to_var[vi])

Check warning on line 222 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L216-L222

Added lines #L216 - L222 were not covered by tests
end
else
index_to_var[vi] = var

Check warning on line 225 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L225

Added line #L225 was not covered by tests
end
end
if !isempty(old_var)
poly = MP.subs(p.polynomial, old_var => new_var)
p = PolyJuMP.ScalarPolynomialFunction(poly, p.variables)

Check warning on line 230 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L227-L230

Added lines #L227 - L230 were not covered by tests
end
return p, index_to_var

Check warning on line 232 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L232

Added line #L232 was not covered by tests
end

function _add_variables!(

Check warning on line 235 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L235

Added line #L235 was not covered by tests
p::PolyJuMP.ScalarPolynomialFunction{T,P},
d,
) where {T,P}
if isnothing(d)
d = Dict{MP.monomial_type(P),MOI.VariableIndex}()

Check warning on line 240 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L239-L240

Added lines #L239 - L240 were not covered by tests
else
M = promote_type(keytype(d), MP.monomial_type(P))
if keytype(d) !== M
d = convert(Dict{M,MOI.VariableIndex}, d)

Check warning on line 244 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L242-L244

Added lines #L242 - L244 were not covered by tests
end
end
for (v, vi) in zip(MP.variables(p.polynomial), p.variables)
d[v] = vi
end
return d

Check warning on line 250 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L247-L250

Added lines #L247 - L250 were not covered by tests
end

function monomial_variable_index(

Check warning on line 253 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L253

Added line #L253 was not covered by tests
model::Optimizer{T},
d::Dict,
div,
mono::MP.AbstractMonomialLike,
) where {T}
if !haskey(d, mono)
x = div[mono]
vx = monomial_variable_index(model, d, div, x)
y = MP.div_multiple(mono, x)
vy = monomial_variable_index(model, d, div, y)
lx, ux = MOI.Utilities.get_bounds(model, T, vx)
ly, uy = MOI.Utilities.get_bounds(model, T, vy)
bounds = (lx * ly, lx * uy, ux * ly, ux * uy)
l = min(bounds...)
if vx == vy
l = max(l, zero(T))

Check warning on line 269 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L259-L269

Added lines #L259 - L269 were not covered by tests
end
u = max(bounds...)
d[mono], _ =

Check warning on line 272 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L271-L272

Added lines #L271 - L272 were not covered by tests
MOI.add_constrained_variable(model.model, MOI.Interval(l, u))
MOI.add_constraint(

Check warning on line 274 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L274

Added line #L274 was not covered by tests
model,
MA.@rewrite(one(T) * d[mono] - one(T) * vx * vy),

Check warning on line 276 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L276

Added line #L276 was not covered by tests
MOI.EqualTo(zero(T)),
)
end
return d[mono]

Check warning on line 280 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L280

Added line #L280 was not covered by tests
end

function _add_constraints(model::Optimizer, cis, index_to_var, d, div)
for ci in cis
func = MOI.get(model, MOI.ConstraintFunction(), ci)
set = MOI.get(model, MOI.ConstraintSet(), ci)
func, index_to_var = _subs!(func, index_to_var)
quad = _quad_convert(func.polynomial, d, div)
MOI.add_constraint(model, quad, set)
end

Check warning on line 290 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L283-L290

Added lines #L283 - L290 were not covered by tests
end

function MOI.Utilities.final_touch(model::Optimizer{T}, _) where {T}
index_to_var = nothing
vars = nothing
monos = nothing
if !isnothing(model.objective)
func, index_to_var = _subs!(model.objective, index_to_var)
vars = _add_variables!(func, vars)
monos = _add_monomials!(func, monos)

Check warning on line 300 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L293-L300

Added lines #L293 - L300 were not covered by tests
end
if !isempty(model.constraints)
for S in keys(model.constraints)
for ci in MOI.get(

Check warning on line 304 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L302-L304

Added lines #L302 - L304 were not covered by tests
model,
MOI.ListOfConstraintIndices{
PolyJuMP.ScalarPolynomialFunction{
T,
model.constraints[S][1],
},
S,
}(),
)
func = MOI.get(model, MOI.ConstraintFunction(), ci)
func, index_to_var = _subs!(func, index_to_var)
vars = _add_variables!(func, vars)
monos = _add_monomials!(func, monos)
end
end

Check warning on line 319 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L314-L319

Added lines #L314 - L319 were not covered by tests
end
div = decompose(monos)
for mono in sort(collect(keys(div)))
if haskey(vars, mono)
continue

Check warning on line 324 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L321-L324

Added lines #L321 - L324 were not covered by tests
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)

Check warning on line 334 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L326-L334

Added lines #L326 - L334 were not covered by tests
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

Check warning on line 341 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L336-L341

Added lines #L336 - L341 were not covered by tests
end

function MOI.get(model::Optimizer, attr::MOI.SolverName)
name = MOI.get(model.model, attr)
return "PolyJuMP.QCQP with $name"

Check warning on line 346 in src/QCQP/MOI_wrapper.jl

View check run for this annotation

Codecov / codecov/patch

src/QCQP/MOI_wrapper.jl#L344-L346

Added lines #L344 - L346 were not covered by tests
end
Loading
Loading