Skip to content

Commit 51842ad

Browse files
authored
Add support for ObjectiveFunction{ScalarQuadraticFunction} (#276)
1 parent 0d4bfcd commit 51842ad

File tree

1 file changed

+32
-14
lines changed

1 file changed

+32
-14
lines changed

src/MOI_wrapper/MOI_wrapper.jl

Lines changed: 32 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ function MOI.supports(
181181
::Union{
182182
MOI.ObjectiveSense,
183183
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}},
184+
MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Float64}},
184185
},
185186
)
186187
return true
@@ -258,29 +259,46 @@ function MOI.optimize!(
258259
end
259260

260261
model_attributes = MOI.get(src, MOI.ListOfModelAttributesSet())
261-
objective_function_attr =
262-
MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Cdouble}}()
262+
max_sense = false
263+
obj_attr = nothing
263264
for attr in model_attributes
264-
if attr == MOI.ObjectiveSense() || attr == objective_function_attr
265-
continue # These are handled later
265+
if attr == MOI.ObjectiveSense()
266+
max_sense = MOI.get(src, attr) == MOI.MAX_SENSE
266267
elseif attr == MOI.Name()
267268
continue # This can be skipped without consequence
269+
elseif attr isa MOI.ObjectiveFunction
270+
obj_attr = attr
271+
else
272+
throw(MOI.UnsupportedAttribute(attr))
268273
end
269-
throw(MOI.UnsupportedAttribute(attr))
270-
end
271-
max_sense = false
272-
if MOI.ObjectiveSense() in model_attributes
273-
max_sense = MOI.get(src, MOI.ObjectiveSense()) == MOI.MAX_SENSE
274274
end
275-
objective_constant = 0.0
276-
c = zeros(A.n)
277-
if objective_function_attr in model_attributes
278-
obj = MOI.get(src, objective_function_attr)
275+
objective_constant, c, P = 0.0, zeros(A.n), SparseArrays.spzeros(A.n, A.n)
276+
if obj_attr == MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Cdouble}}()
277+
obj = MOI.get(src, obj_attr)
279278
objective_constant = MOI.constant(obj)
280279
for term in obj.terms
281280
c[term.variable.value] += (max_sense ? -1 : 1) * term.coefficient
282281
end
282+
elseif obj_attr ==
283+
MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{Cdouble}}()
284+
obj = MOI.get(src, obj_attr)
285+
objective_constant = MOI.constant(obj)
286+
scale = max_sense ? -1 : 1
287+
for term in obj.affine_terms
288+
c[term.variable.value] += scale * term.coefficient
289+
end
290+
nnz = length(obj.quadratic_terms)
291+
I, J, V = zeros(Int, nnz), zeros(Int, nnz), zeros(Cdouble, nnz)
292+
for (i, qterm) in enumerate(obj.quadratic_terms)
293+
I[i] = min(qterm.variable_1.value, qterm.variable_2.value)
294+
J[i] = max(qterm.variable_1.value, qterm.variable_2.value)
295+
V[i] = scale * qterm.coefficient
296+
end
297+
P = SparseArrays.sparse(I, J, V, A.n, A.n)
298+
elseif obj_attr !== nothing
299+
throw(MOI.UnsupportedAttribute(obj_attr))
283300
end
301+
284302
# `model.primal` contains the result of the previous optimization.
285303
# It is used as a warm start if its length is the same, e.g.
286304
# probably because no variable and/or constraint has been added.
@@ -350,7 +368,7 @@ function MOI.optimize!(
350368
A.m,
351369
A.n,
352370
A,
353-
SparseArrays.spzeros(A.n, A.n), # placeholder: P
371+
P,
354372
Ab.constants.b,
355373
c,
356374
Ab.sets.num_rows[1],

0 commit comments

Comments
 (0)