Skip to content

Commit

Permalink
Update to MOI v0.10 (#40)
Browse files Browse the repository at this point in the history
  • Loading branch information
blegat committed Nov 10, 2021
1 parent 1ebd714 commit 312ab48
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 47 deletions.
8 changes: 4 additions & 4 deletions Project.toml
Expand Up @@ -8,10 +8,10 @@ MathOptInterface = "b8f27783-ece8-5eb3-8dc8-9495eed66fee"
Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7"

[compat]
GLPK = "0.13.0"
Ipopt = "0.6.2"
JuMP = "0.21.2"
MathOptInterface = "0.9.17"
GLPK = "0.15"
Ipopt = "0.8"
JuMP = "0.22"
MathOptInterface = "0.10.3"
julia = "1"

[extras]
Expand Down
26 changes: 13 additions & 13 deletions src/MOI_wrapper.jl
Expand Up @@ -95,10 +95,10 @@ function MOI.empty!(model::Optimizer)
return
end

MOI.Utilities.supports_default_copy_to(::Optimizer, copy_names::Bool) = !copy_names
MOI.supports_incremental_interface(::Optimizer) = true

function MOI.copy_to(model::Optimizer, src::MOI.ModelLike; copy_names = false)
return MOI.Utilities.default_copy_to(model, src, copy_names)
function MOI.copy_to(model::Optimizer, src::MOI.ModelLike)
return MOI.Utilities.default_copy_to(model, src)
end

function _mip(model::Optimizer)
Expand Down Expand Up @@ -189,13 +189,13 @@ _map(variables::Vector{MOI.VariableIndex}, x) = MOI.Utilities.map_indices(vi ->

is_discrete(::Type{<:MOI.AbstractSet}) = false
is_discrete(::Type{<:Union{MOI.Integer, MOI.ZeroOne, MOI.Semiinteger{Float64}}}) = true
function MOI.supports_constraint(model::Optimizer, F::Type{MOI.SingleVariable}, S::Type{<:MOI.AbstractScalarSet})
function MOI.supports_constraint(model::Optimizer, F::Type{MOI.VariableIndex}, S::Type{<:MOI.AbstractScalarSet})
return MOI.supports_constraint(_mip(model), F, S) &&
(is_discrete(S) || MOI.supports_constraint(_cont(model), F, S))
end
function MOI.add_constraint(model::Optimizer, func::MOI.SingleVariable, set::MOI.AbstractScalarSet)
function MOI.add_constraint(model::Optimizer, func::MOI.VariableIndex, set::MOI.AbstractScalarSet)
if is_discrete(typeof(set))
push!(model.int_indices, func.variable.value)
push!(model.int_indices, func.value)
else
MOI.add_constraint(_cont(model), _map(model.cont_variables, func), set)
MOI.add_constraint(_infeasible(model), _map(model.infeasible_variables, func), set)
Expand Down Expand Up @@ -275,11 +275,11 @@ function MOI.set(model::Optimizer, attr::MOI.ObjectiveFunction{SQF}, func::SQF)
end


function MOI.get(model::Optimizer, param::MOI.RawParameter)
function MOI.get(model::Optimizer, param::MOI.RawOptimizerAttribute)
return getproperty(model, Symbol(param.name))
end
MOI.supports(::Optimizer, param::MOI.RawParameter) = Symbol(param.name) in fieldnames(Optimizer)
function MOI.set(model::Optimizer, param::MOI.RawParameter, value)
MOI.supports(::Optimizer, param::MOI.RawOptimizerAttribute) = Symbol(param.name) in fieldnames(Optimizer)
function MOI.set(model::Optimizer, param::MOI.RawOptimizerAttribute, value)
setproperty!(model, Symbol(param.name), value)
end
MOI.supports(::Optimizer, ::MOI.Silent) = true
Expand All @@ -289,17 +289,17 @@ end
MOI.get(model::Optimizer, ::MOI.Silent) = model.silent
MOI.supports(::Optimizer, ::MOI.TimeLimitSec) = true
function MOI.set(model::Optimizer, ::MOI.TimeLimitSec, value::Nothing)
MOI.set(model, MOI.RawParameter("timeout"), Inf)
MOI.set(model, MOI.RawOptimizerAttribute("timeout"), Inf)
end
function MOI.set(model::Optimizer, ::MOI.TimeLimitSec, value)
MOI.set(model, MOI.RawParameter("timeout"), value)
MOI.set(model, MOI.RawOptimizerAttribute("timeout"), value)
end
function MOI.get(model::Optimizer, ::MOI.TimeLimitSec)
value = MOI.get(model, MOI.RawParameter("timeout"))
value = MOI.get(model, MOI.RawOptimizerAttribute("timeout"))
return isfinite(value) ? value : nothing
end

MOI.get(model::Optimizer, ::MOI.SolveTime) = model.total_time
MOI.get(model::Optimizer, ::MOI.SolveTimeSec) = model.total_time

MOI.get(model::Optimizer, ::MOI.TerminationStatus) = model.status
function MOI.get(model::Optimizer, ::MOI.VariablePrimal, v::MOI.VariableIndex)
Expand Down
38 changes: 18 additions & 20 deletions src/algorithm.jl
Expand Up @@ -17,14 +17,14 @@ end
function eval_gradient(func::SQF, grad_f, values)
fill!(grad_f, 0.0)
for term in func.affine_terms
grad_f[term.variable_index.value] += term.coefficient
grad_f[term.variable.value] += term.coefficient
end
for term in func.quadratic_terms
grad_f[term.variable_index_1.value] += term.coefficient * values[term.variable_index_2.value]
grad_f[term.variable_1.value] += term.coefficient * values[term.variable_2.value]
# If variables are the same, the coefficient is already multiplied by 2
# 2 by definition of `SQF`.
if term.variable_index_1 != term.variable_index_2
grad_f[term.variable_index_2.value] += term.coefficient * values[term.variable_index_1.value]
if term.variable_1 != term.variable_2
grad_f[term.variable_2.value] += term.coefficient * values[term.variable_1.value]
end
end
end
Expand Down Expand Up @@ -53,8 +53,7 @@ function MOI.optimize!(model::Optimizer)
if (model.nlp_block !== nothing && model.nlp_block.has_objective) || model.objective isa SQF
if model.θ === nothing
model.θ = MOI.add_variable(model.mip_optimizer)
func = MOI.SingleVariable(model.θ)
MOI.set(model.mip_optimizer, MOI.ObjectiveFunction{typeof(func)}(), func)
MOI.set(model.mip_optimizer, MOI.ObjectiveFunction{typeof(model.θ)}(), model.θ)
end
else
if model.θ !== nothing
Expand Down Expand Up @@ -310,18 +309,17 @@ function fix_int_vars(optimizer::MOI.ModelLike, vars, mip_solution, int_indices)
for i in int_indices
vi = vars[i]
idx = vi.value
ci = MOI.ConstraintIndex{MOI.SingleVariable, MOI.LessThan{Float64}}(idx)
ci = MOI.ConstraintIndex{MOI.VariableIndex, MOI.LessThan{Float64}}(idx)
MOI.is_valid(optimizer, ci) && MOI.delete(optimizer, ci)
ci = MOI.ConstraintIndex{MOI.SingleVariable, MOI.GreaterThan{Float64}}(idx)
ci = MOI.ConstraintIndex{MOI.VariableIndex, MOI.GreaterThan{Float64}}(idx)
MOI.is_valid(optimizer, ci) && MOI.delete(optimizer, ci)
ci = MOI.ConstraintIndex{MOI.SingleVariable, MOI.EqualTo{Float64}}(idx)
ci = MOI.ConstraintIndex{MOI.VariableIndex, MOI.EqualTo{Float64}}(idx)
set = MOI.EqualTo(mip_solution[i])

if MOI.is_valid(optimizer, ci)
MOI.set(optimizer, MOI.ConstraintSet(), ci, set)
else
func = MOI.SingleVariable(vi)
MOI.add_constraint(optimizer, func, set)
MOI.add_constraint(optimizer, vi, set)
end
end
end
Expand Down Expand Up @@ -376,7 +374,7 @@ function solve_subproblem(model::Optimizer, comp::Function)
model.quad_less_than_slack_variables = MOI.add_variables(_infeasible(model), length(model.quad_less_than))
model.quad_less_than_infeasible_con = map(eachindex(model.quad_less_than)) do i
func, set = model.quad_less_than[i]
MOI.add_constraint(_infeasible(model), MOI.Utilities.operate(-, Float64, func, MOI.SingleVariable(model.quad_less_than_slack_variables[i])), set)
MOI.add_constraint(_infeasible(model), MOI.Utilities.operate(-, Float64, func, model.quad_less_than_slack_variables[i]), set)
end
for vi in model.quad_less_than_slack_variables
_add_to_obj(vi)
Expand All @@ -386,7 +384,7 @@ function solve_subproblem(model::Optimizer, comp::Function)
model.quad_greater_than_slack_variables = MOI.add_variables(_infeasible(model), length(model.quad_greater_than))
model.quad_greater_than_infeasible_con = map(eachindex(model.quad_greater_than)) do i
func, set = model.quad_greater_than[i]
MOI.add_constraint(_infeasible(model), MOI.Utilities.operate(+, Float64, func, MOI.SingleVariable(model.quad_greater_than_slack_variables[i])), set)
MOI.add_constraint(_infeasible(model), MOI.Utilities.operate(+, Float64, func, model.quad_greater_than_slack_variables[i]), set)
end
for vi in model.quad_greater_than_slack_variables
_add_to_obj(vi)
Expand Down Expand Up @@ -471,17 +469,17 @@ function add_quad_cuts(model::Optimizer, cont_solution, cons, callback_data)
dgc_idx = Int64[]
dgc_nzv = Float64[]
for term in func.affine_terms
push!(dgc_idx, term.variable_index.value)
push!(dgc_idx, term.variable.value)
push!(dgc_nzv, term.coefficient)
end
for term in func.quadratic_terms
push!(dgc_idx, term.variable_index_1.value)
push!(dgc_nzv, term.coefficient * cont_solution[term.variable_index_2.value])
push!(dgc_idx, term.variable_1.value)
push!(dgc_nzv, term.coefficient * cont_solution[term.variable_2.value])
# If variables are the same, the coefficient is already multiplied by 2
# 2 by definition of `SQF`.
if term.variable_index_1 != term.variable_index_2
push!(dgc_idx, term.variable_index_2.value)
push!(dgc_nzv, term.coefficient * cont_solution[term.variable_index_1.value])
if term.variable_1 != term.variable_2
push!(dgc_idx, term.variable_2.value)
push!(dgc_nzv, term.coefficient * cont_solution[term.variable_1.value])
end
end
add_cut(model, cont_solution, gc, dgc_idx, dgc_nzv, set, callback_data)
Expand Down Expand Up @@ -527,7 +525,7 @@ function add_cuts(model::Optimizer, cont_solution, jac_IJ, jac_V, grad_f, is_max
f = eval_objective(model, cont_solution)
eval_objective_gradient(model, grad_f, cont_solution)
constant = -f
func = MOI.Utilities.operate(-, Float64, MOI.SingleVariable(model.θ))
func = MOI.Utilities.operate(-, Float64, model.θ)
for j in eachindex(grad_f)
if !iszero(grad_f[j])
constant += grad_f[j] * cont_solution[j]
Expand Down
18 changes: 8 additions & 10 deletions test/MOI_wrapper.jl
Expand Up @@ -2,11 +2,10 @@ using Test

#using MathOptInterface
#const MOI = MathOptInterface
const MOIT = MOI.Test

import Pavito

const CONFIG = MOIT.TestConfig(atol=1e-6, rtol=1e-6, duals=false, query=false)
const CONFIG = MOI.DeprecatedTest.Config(atol=1e-6, rtol=1e-6, duals=false, query=false)

@testset "MOI tests - $(msd ? "MSD" : "Iter")" for msd in [false, true]
# The default for `diverging_iterates_tol` is `1e-20` which makes Ipopt terminates with `ITERATION_LIMIT` for most infeasible
Expand All @@ -20,16 +19,15 @@ const CONFIG = MOIT.TestConfig(atol=1e-6, rtol=1e-6, duals=false, query=false)
end

@testset "supports_default_copy_to" begin
@test MOI.Utilities.supports_default_copy_to(optimizer, false)
@test !MOI.Utilities.supports_default_copy_to(optimizer, true)
@test MOI.supports_incremental_interface(optimizer)
end

@testset "Unit" begin
MOIT.feasibility_sense(optimizer, CONFIG)
MOIT.max_sense(optimizer, CONFIG)
MOIT.min_sense(optimizer, CONFIG)
MOIT.time_limit_sec(optimizer, CONFIG)
MOIT.silent(optimizer, CONFIG)
MOI.DeprecatedTest.feasibility_sense(optimizer, CONFIG)
MOI.DeprecatedTest.max_sense(optimizer, CONFIG)
MOI.DeprecatedTest.min_sense(optimizer, CONFIG)
MOI.DeprecatedTest.time_limit_sec(optimizer, CONFIG)
MOI.DeprecatedTest.silent(optimizer, CONFIG)
end

@testset "Integer Linear" begin
Expand All @@ -45,6 +43,6 @@ const CONFIG = MOIT.TestConfig(atol=1e-6, rtol=1e-6, duals=false, query=false)
# GLPK has an integer-infeasible solution
push!(excludes, "knapsack")
end
MOIT.intlineartest(optimizer, CONFIG, excludes)
MOI.DeprecatedTest.intlineartest(optimizer, CONFIG, excludes)
end
end

0 comments on commit 312ab48

Please sign in to comment.