Skip to content

Commit d300936

Browse files
committed
Use an enum for the objective sink of ModelWithQuad
1 parent f04f2c4 commit d300936

2 files changed

Lines changed: 20 additions & 17 deletions

File tree

src/Nonlinear/model_with_quad.jl

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@
44
# Use of this source code is governed by an MIT-style license that can be found
55
# in the LICENSE.md file or at https://opensource.org/licenses/MIT.
66

7+
# Where the objective of a `ModelWithQuad` currently lives.
8+
@enum(_ObjectiveSink, _NONE, _QUAD, _INNER)
9+
710
"""
811
ModelWithQuad{T,M}(
912
qp::QPBlockData{T},
1013
inner::M;
11-
objective_sink::Symbol = :none,
14+
objective_sink::_ObjectiveSink = _NONE,
1215
) where {T,M}
1316
1417
A model layer that owns the variables of the model, stores affine and
@@ -29,8 +32,8 @@ that storage as `parameters::Vector{T}`, like [`Model`](@ref) does:
2932
Add constraints with [`add_constraint`](@ref) or `MOI.add_constraint`, and
3033
set the objective with [`set_objective`](@ref): affine and quadratic
3134
functions are routed to the QP block, everything else to the inner model.
32-
`objective_sink` records where the objective currently lives (`:none`,
33-
`:quad` or `:inner`).
35+
`objective_sink` records where the objective currently lives (`_NONE`,
36+
`_QUAD` or `_INNER`).
3437
3538
Create the corresponding evaluator, [`EvaluatorWithQuad`](@ref), with
3639
`Evaluator(model, backend)`, or construct it directly from an inner
@@ -41,12 +44,12 @@ mutable struct ModelWithQuad{T,M}
4144
variables::MOI.Utilities.VariablesContainer{T}
4245
qp::QPBlockData{T}
4346
inner::M
44-
objective_sink::Symbol # :none, :quad or :inner
47+
objective_sink::_ObjectiveSink
4548

4649
function ModelWithQuad{T}(
4750
qp::QPBlockData{T},
4851
inner::M;
49-
objective_sink::Symbol = :none,
52+
objective_sink::_ObjectiveSink = _NONE,
5053
) where {T,M}
5154
model = new{T,M}(
5255
MOI.Utilities.VariablesContainer{T}(),
@@ -223,7 +226,7 @@ function set_objective(
223226
) where {T}
224227
MOI.set(model.qp, MOI.ObjectiveFunction{typeof(obj)}(), obj)
225228
set_objective(model.inner, nothing)
226-
model.objective_sink = :quad
229+
model.objective_sink = _QUAD
227230
return
228231
end
229232

@@ -234,7 +237,7 @@ function set_objective(model::ModelWithQuad{T}, obj) where {T}
234237
obj = _replace_parameters(obj)
235238
end
236239
set_objective(model.inner, obj)
237-
model.objective_sink = obj === nothing ? :none : :inner
240+
model.objective_sink = obj === nothing ? _NONE : _INNER
238241
return
239242
end
240243

@@ -385,9 +388,9 @@ end
385388

386389
function MOI.eval_objective(d::EvaluatorWithQuad{T}, x) where {T}
387390
sink = d.model.objective_sink
388-
if sink == :quad
391+
if sink == _QUAD
389392
return MOI.eval_objective(d.model.qp, x)
390-
elseif sink == :inner
393+
elseif sink == _INNER
391394
return MOI.eval_objective(d.inner, x)
392395
else
393396
return zero(T)
@@ -396,9 +399,9 @@ end
396399

397400
function MOI.eval_objective_gradient(d::EvaluatorWithQuad{T}, grad, x) where {T}
398401
sink = d.model.objective_sink
399-
if sink == :quad
402+
if sink == _QUAD
400403
MOI.eval_objective_gradient(d.model.qp, grad, x)
401-
elseif sink == :inner
404+
elseif sink == _INNER
402405
MOI.eval_objective_gradient(d.inner, grad, x)
403406
else
404407
grad .= zero(T)
@@ -534,7 +537,7 @@ end
534537
_has_objective(d::Evaluator) = d.model.objective !== nothing
535538

536539
function _has_objective(d::EvaluatorWithQuad)
537-
if d.model.objective_sink == :quad
540+
if d.model.objective_sink == _QUAD
538541
return true
539542
end
540543
return _has_objective(d.inner)

test/Nonlinear/test_model_with_quad.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -165,14 +165,14 @@ end
165165
function test_objective_sink_switching()
166166
model = Nonlinear.ModelWithQuad(Nonlinear.Model())
167167
x = MOI.add_variable(model)
168-
@test model.objective_sink == :none
168+
@test model.objective_sink == Nonlinear._NONE
169169
f = MOI.ScalarQuadraticFunction(
170170
[MOI.ScalarQuadraticTerm(2.0, x, x)],
171171
MOI.ScalarAffineTerm{Float64}[],
172172
0.0,
173173
)
174174
Nonlinear.set_objective(model, f)
175-
@test model.objective_sink == :quad
175+
@test model.objective_sink == Nonlinear._QUAD
176176
@test MOI.get(model, MOI.ObjectiveFunctionType()) ==
177177
MOI.ScalarQuadraticFunction{Float64}
178178
@test MOI.get(model, MOI.ObjectiveFunction{typeof(f)}()) f
@@ -183,7 +183,7 @@ function test_objective_sink_switching()
183183
# Switch to a nonlinear objective: the quadratic objective must be
184184
# cleared, including its Hessian entries.
185185
Nonlinear.set_objective(model, :(sin($x)))
186-
@test model.objective_sink == :inner
186+
@test model.objective_sink == Nonlinear._INNER
187187
d = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode())
188188
MOI.initialize(d, [:Grad, :Jac, :Hess])
189189
@test MOI.eval_objective(d, [3.0]) == sin(3.0)
@@ -195,12 +195,12 @@ function test_objective_sink_switching()
195195
# Switch to a linear objective, and then remove it.
196196
g = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(2.0, x)], 1.0)
197197
Nonlinear.set_objective(model, g)
198-
@test model.objective_sink == :quad
198+
@test model.objective_sink == Nonlinear._QUAD
199199
d = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode())
200200
MOI.initialize(d, [:Grad, :Jac])
201201
@test MOI.eval_objective(d, [3.0]) == 7.0
202202
Nonlinear.set_objective(model, nothing)
203-
@test model.objective_sink == :none
203+
@test model.objective_sink == Nonlinear._NONE
204204
d = Nonlinear.Evaluator(model, Nonlinear.SparseReverseMode())
205205
MOI.initialize(d, [:Grad, :Jac])
206206
@test MOI.eval_objective(d, [3.0]) == 0.0

0 commit comments

Comments
 (0)