Skip to content

Commit 2a0b748

Browse files
authored
[breaking] remove QuadraticObjectiveCoef (#213)
1 parent a958e5f commit 2a0b748

4 files changed

Lines changed: 1 addition & 364 deletions

File tree

src/MOI_wrapper.jl

Lines changed: 1 addition & 133 deletions
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,6 @@ function MOI.is_empty(model::Optimizer)
135135
model.affine_objective_cache === nothing &&
136136
model.quadratic_objective_cache === nothing &&
137137
MOI.is_empty(model.original_objective_cache) &&
138-
isempty(model.quadratic_objective_cache_product) &&
139138
#
140139
isempty(model.vector_affine_constraint_cache) &&
141140
#
@@ -172,7 +171,6 @@ function MOI.empty!(model::Optimizer{T}) where {T}
172171
model.affine_objective_cache = nothing
173172
model.quadratic_objective_cache = nothing
174173
MOI.empty!(model.original_objective_cache)
175-
empty!(model.quadratic_objective_cache_product)
176174
#
177175
empty!(model.vector_affine_constraint_cache)
178176
#
@@ -1232,8 +1230,7 @@ function MOI.modify(
12321230
chg::Union{MOI.ScalarConstantChange{T},MOI.ScalarCoefficientChange{T}},
12331231
) where {F<:MathOptInterface.AbstractScalarFunction,T}
12341232
if model.quadratic_objective_cache !== nothing ||
1235-
model.affine_objective_cache !== nothing ||
1236-
!isempty(model.quadratic_objective_cache_product)
1233+
model.affine_objective_cache !== nothing
12371234
error(
12381235
"A parametric objective cannot be modified as it would conflict with the parameter update mechanism. Please set a new objective or use parameters to perform such updates.",
12391236
)
@@ -1946,128 +1943,6 @@ function MOI.set(
19461943
return model.constraints_interpretation = value
19471944
end
19481945

1949-
struct QuadraticObjectiveCoef <: MOI.AbstractModelAttribute end
1950-
1951-
function _set_quadratic_product_in_obj!(model::Optimizer{T}) where {T}
1952-
n = length(model.quadratic_objective_cache_product)
1953-
1954-
f = if model.affine_objective_cache !== nothing
1955-
_current_function(model.affine_objective_cache)
1956-
elseif model.quadratic_objective_cache !== nothing
1957-
_current_function(model.quadratic_objective_cache)
1958-
else
1959-
F = MOI.get(model.original_objective_cache, MOI.ObjectiveFunctionType())
1960-
MOI.get(model.original_objective_cache, MOI.ObjectiveFunction{F}())
1961-
end
1962-
F = typeof(f)
1963-
1964-
quadratic_prods_vector = MOI.ScalarQuadraticTerm{T}[]
1965-
sizehint!(quadratic_prods_vector, n)
1966-
1967-
for ((x, y), fparam) in model.quadratic_objective_cache_product
1968-
# x, y = prod_var
1969-
evaluated_fparam = _evaluate_parametric_expression(model, fparam)
1970-
push!(
1971-
quadratic_prods_vector,
1972-
MOI.ScalarQuadraticTerm(evaluated_fparam, x, y),
1973-
)
1974-
end
1975-
1976-
f_new = if F <: MOI.VariableIndex
1977-
MOI.ScalarQuadraticFunction(
1978-
quadratic_prods_vector,
1979-
MOI.ScalarAffineTerm{T}[MOI.ScalarAffineTerm{T}(1.0, f)],
1980-
0.0,
1981-
)
1982-
elseif F <: MOI.ScalarAffineFunction{T}
1983-
MOI.ScalarQuadraticFunction(quadratic_prods_vector, f.terms, f.constant)
1984-
elseif F <: MOI.ScalarQuadraticFunction{T}
1985-
quadratic_terms = vcat(f.quadratic_terms, quadratic_prods_vector)
1986-
MOI.ScalarQuadraticFunction(quadratic_terms, f.affine_terms, f.constant)
1987-
end
1988-
1989-
MOI.set(
1990-
model.optimizer,
1991-
MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{T}}(),
1992-
f_new,
1993-
)
1994-
1995-
return
1996-
end
1997-
1998-
function _evaluate_parametric_expression(model::Optimizer, p::MOI.VariableIndex)
1999-
return model.parameters[p_idx(p)]
2000-
end
2001-
2002-
function _evaluate_parametric_expression(
2003-
model::Optimizer,
2004-
fparam::MOI.ScalarAffineFunction{T},
2005-
) where {T}
2006-
constant = fparam.constant
2007-
terms = fparam.terms
2008-
evaluated_parameter_expression = zero(T)
2009-
for term in terms
2010-
coef = term.coefficient
2011-
p = term.variable
2012-
evaluated_parameter_expression += coef * model.parameters[p_idx(p)]
2013-
evaluated_parameter_expression += constant
2014-
end
2015-
return evaluated_parameter_expression
2016-
end
2017-
2018-
function MOI.set(
2019-
model::Optimizer,
2020-
::QuadraticObjectiveCoef,
2021-
(x1, x2)::Tuple{MOI.VariableIndex,MOI.VariableIndex},
2022-
::Nothing,
2023-
)
2024-
if x1.value > x2.value
2025-
aux = x1
2026-
x1 = x2
2027-
x2 = aux
2028-
end
2029-
delete!(model.quadratic_objective_cache_product, (x1, x2))
2030-
model.quadratic_objective_cache_product_changed = true
2031-
return
2032-
end
2033-
2034-
function MOI.set(
2035-
model::Optimizer,
2036-
::QuadraticObjectiveCoef,
2037-
(x1, x2)::Tuple{MOI.VariableIndex,MOI.VariableIndex},
2038-
f_param::Union{MOI.VariableIndex,MOI.ScalarAffineFunction{T}},
2039-
) where {T}
2040-
if x1.value > x2.value
2041-
aux = x1
2042-
x1 = x2
2043-
x2 = aux
2044-
end
2045-
model.quadratic_objective_cache_product[(x1, x2)] = f_param
2046-
model.quadratic_objective_cache_product_changed = true
2047-
return
2048-
end
2049-
2050-
function MOI.get(
2051-
model::Optimizer,
2052-
::QuadraticObjectiveCoef,
2053-
(x1, x2)::Tuple{MOI.VariableIndex,MOI.VariableIndex},
2054-
)
2055-
if x1.value > x2.value
2056-
aux = x1
2057-
x1 = x2
2058-
x2 = aux
2059-
end
2060-
if haskey(model.quadratic_objective_cache_product, (x1, x2))
2061-
return model.quadratic_objective_cache_product[(x1, x2)]
2062-
else
2063-
throw(
2064-
ErrorException(
2065-
"Parameter not set in product of variables ($x1,$x2)",
2066-
),
2067-
)
2068-
end
2069-
end
2070-
20711946
#
20721947
# Optimize
20731948
#
@@ -2076,13 +1951,6 @@ function MOI.optimize!(model::Optimizer)
20761951
if !isempty(model.updated_parameters)
20771952
update_parameters!(model)
20781953
end
2079-
if (
2080-
!isempty(model.quadratic_objective_cache_product) ||
2081-
model.quadratic_objective_cache_product_changed
2082-
)
2083-
model.quadratic_objective_cache_product_changed = false
2084-
_set_quadratic_product_in_obj!(model)
2085-
end
20861954
MOI.optimize!(model.optimizer)
20871955
if MOI.get(model, MOI.DualStatus()) != MOI.NO_SOLUTION &&
20881956
model.evaluate_duals

src/ParametricOptInterface.jl

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -196,12 +196,6 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
196196
quadratic_objective_cache::Union{Nothing,ParametricQuadraticFunction{T}}
197197
cubic_objective_cache::Union{Nothing,ParametricCubicFunction{T}}
198198
original_objective_cache::MOI.Utilities.ObjectiveContainer{T}
199-
# Store parametric expressions for product of variables
200-
quadratic_objective_cache_product::Dict{
201-
Tuple{MOI.VariableIndex,MOI.VariableIndex},
202-
MOI.AbstractFunction,
203-
}
204-
quadratic_objective_cache_product_changed::Bool
205199

206200
# vector affine function data
207201
# vector_constraint_cache::DoubleDict{Vector{MOI.VectorAffineTerm{T}}}
@@ -273,11 +267,6 @@ mutable struct Optimizer{T,OT<:MOI.ModelLike} <: MOI.AbstractOptimizer
273267
nothing,
274268
nothing, # cubic_objective_cache
275269
MOI.Utilities.ObjectiveContainer{T}(),
276-
Dict{
277-
Tuple{MOI.VariableIndex,MOI.VariableIndex},
278-
MOI.AbstractFunction,
279-
}(),
280-
false,
281270
# vec affine
282271
# DoubleDict{Vector{MOI.VectorAffineTerm{T}}}(),
283272
DoubleDict{ParametricVectorAffineFunction{T}}(),

test/test_JuMP.jl

Lines changed: 0 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -964,83 +964,6 @@ function test_jump_direct_soc_parameters()
964964
return
965965
end
966966

967-
function test_jump_direct_qp_objective()
968-
optimizer = POI.Optimizer(Ipopt.Optimizer)
969-
model = direct_model(optimizer)
970-
MOI.set(model, MOI.Silent(), true)
971-
@variable(model, x >= 0)
972-
@variable(model, y >= 0)
973-
@variable(model, p in MOI.Parameter(1.0))
974-
@constraint(model, 2x + y <= 4)
975-
@constraint(model, x + 2y <= 4)
976-
@objective(model, Max, (x^2 + y^2) / 2)
977-
optimize!(model)
978-
@test objective_value(model) 16 / 9 atol = ATOL
979-
@test value(x) 4 / 3 atol = ATOL
980-
@test value(y) 4 / 3 atol = ATOL
981-
MOI.set(
982-
backend(model),
983-
POI.QuadraticObjectiveCoef(),
984-
(index(x), index(y)),
985-
2index(p) + 3,
986-
)
987-
optimize!(model)
988-
@test canonical_compare(
989-
MOI.get(
990-
backend(model),
991-
POI.QuadraticObjectiveCoef(),
992-
(index(x), index(y)),
993-
),
994-
MOI.ScalarAffineFunction{Int64}(
995-
MOI.ScalarAffineTerm{Int64}[MOI.ScalarAffineTerm{Int64}(
996-
2,
997-
MOI.VariableIndex(POI.PARAMETER_INDEX_THRESHOLD + 1),
998-
)],
999-
3,
1000-
),
1001-
)
1002-
@test objective_value(model) 32 / 3 atol = ATOL
1003-
@test value(x) 4 / 3 atol = ATOL
1004-
@test value(y) 4 / 3 atol = ATOL
1005-
MOI.set(model, POI.ParameterValue(), p, 2.0)
1006-
optimize!(model)
1007-
@test objective_value(model) 128 / 9 atol = ATOL
1008-
@test value(x) 4 / 3 atol = ATOL
1009-
@test value(y) 4 / 3 atol = ATOL
1010-
MOI.set(
1011-
backend(model),
1012-
POI.QuadraticObjectiveCoef(),
1013-
(index(x), index(y)),
1014-
nothing,
1015-
)
1016-
optimize!(model)
1017-
@test objective_value(model) 16 / 9 atol = ATOL
1018-
@test value(x) 4 / 3 atol = ATOL
1019-
@test value(y) 4 / 3 atol = ATOL
1020-
# now in reverse order
1021-
MOI.set(
1022-
backend(model),
1023-
POI.QuadraticObjectiveCoef(),
1024-
(index(y), index(x)),
1025-
2index(p) + 3,
1026-
)
1027-
optimize!(model)
1028-
@test objective_value(model) 128 / 9 atol = ATOL
1029-
@test value(x) 4 / 3 atol = ATOL
1030-
@test value(y) 4 / 3 atol = ATOL
1031-
MOI.set(
1032-
backend(model),
1033-
POI.QuadraticObjectiveCoef(),
1034-
(index(y), index(x)),
1035-
nothing,
1036-
)
1037-
optimize!(model)
1038-
@test objective_value(model) 16 / 9 atol = ATOL
1039-
@test value(x) 4 / 3 atol = ATOL
1040-
@test value(y) 4 / 3 atol = ATOL
1041-
return
1042-
end
1043-
1044967
function test_jump_direct_rsoc_constraints()
1045968
"""
1046969
Problem RSOC

0 commit comments

Comments
 (0)