From cedacb629ada408fd31dcdaeada4d17c597b5a07 Mon Sep 17 00:00:00 2001 From: Martin Biel Date: Fri, 29 May 2020 13:34:15 +0200 Subject: [PATCH 1/2] Bugfix for set ConstraintFunction in ScalarizeBridge. --- src/Bridges/Constraint/scalarize.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Bridges/Constraint/scalarize.jl b/src/Bridges/Constraint/scalarize.jl index 98dc30fa82..a46deb6320 100644 --- a/src/Bridges/Constraint/scalarize.jl +++ b/src/Bridges/Constraint/scalarize.jl @@ -122,7 +122,7 @@ function MOI.modify(model::MOI.ModelLike, bridge::ScalarizeBridge, nothing end function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintFunction, - bridge::ScalarizeBridge{T}, func) where T + bridge::ScalarizeBridge{T,F,S}, func) where {T,F,S} old_constants = bridge.constants bridge.constants = MOI.constant(func, T) new_func = MOIU.scalarize(func, true) @@ -130,7 +130,7 @@ function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintFunction, new_func) for i in eachindex(bridge.constants) if bridge.constants[i] != old_constants[i] - MOI.set(model, MOI.ConstraintSet(), bridge.scalar_constraints, + MOI.set(model, MOI.ConstraintSet(), bridge.scalar_constraints[i], S(-bridge.constants[i])) end end From 097c25be7c45dd0aac5ec3a59ac6056e80eb2c4b Mon Sep 17 00:00:00 2001 From: Martin Biel Date: Fri, 29 May 2020 17:19:16 +0200 Subject: [PATCH 2/2] Added testcase for setting VectorAffineFunction with nonzero constant --- src/Test/UnitTests/modifications.jl | 45 ++++++++++++++++++++++++++++ test/Bridges/Constraint/scalarize.jl | 6 ++++ 2 files changed, 51 insertions(+) diff --git a/src/Test/UnitTests/modifications.jl b/src/Test/UnitTests/modifications.jl index 61da17d786..32853fbed6 100644 --- a/src/Test/UnitTests/modifications.jl +++ b/src/Test/UnitTests/modifications.jl @@ -196,6 +196,51 @@ function solve_func_scalaraffine_lessthan(model::MOI.ModelLike, config::TestConf end modificationtests["solve_func_scalaraffine_lessthan"] = solve_func_scalaraffine_lessthan +""" + solve_func_vectoraffine_nonneg(model::MOI.ModelLike, config::TestConfig) + +Test setting the function in a VectorAffineFunction-in-Nonnegatives +constraint. If `config.solve=true` confirm that it solves correctly, and if +`config.duals=true`, check that the duals are computed correctly. +""" +function solve_func_vectoraffine_nonneg(model::MOI.ModelLike, config::TestConfig) + MOI.empty!(model) + MOIU.loadfromstring!(model,""" + variables: x, y + minobjective: 1.0x + 2.0y + c: [1.0x, 2.0y] in Nonnegatives(2) + """) + x = MOI.get(model, MOI.VariableIndex, "x") + y = MOI.get(model, MOI.VariableIndex, "y") + c = MOI.get(model, MOI.ConstraintIndex, "c") + test_model_solution(model, config; + objective_value = 0.0, + variable_primal = [(x, 0.0), (y, 0.0)], + constraint_primal = [(c, [0.0, 0.0])] + ) + MOI.set(model, MOI.ConstraintFunction(), c, + MOI.VectorAffineFunction([ + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(2.0, y)) + ], + [-1.0, -1.5] + ) + ) + foo = MOI.get(model, MOI.ConstraintFunction(), c) + @test foo ≈ MOI.VectorAffineFunction([ + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, x)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(2.0, y)) + ], + [-1.0, -1.5] + ) + test_model_solution(model, config; + objective_value = 2.5, + variable_primal = [(x, 1.0), (y, 0.75)], + constraint_primal = [(c, [0.0, 0.0])] + ) +end +modificationtests["solve_func_vectoraffine_nonneg"] = solve_func_vectoraffine_nonneg + """ solve_const_vectoraffine_nonpos(model::MOI.ModelLike, config::TestConfig) diff --git a/test/Bridges/Constraint/scalarize.jl b/test/Bridges/Constraint/scalarize.jl index a0336e451f..8c91cf0e90 100644 --- a/test/Bridges/Constraint/scalarize.jl +++ b/test/Bridges/Constraint/scalarize.jl @@ -81,6 +81,12 @@ config = MOIT.TestConfig() ((MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}, 0), (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}, 0))) + # Test setting VectorAffineFunction with nonzero constants + MOIU.set_mock_optimize!(mock, + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0.0, 0.0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 0.75])) + MOIT.solve_func_vectoraffine_nonneg(bridged_mock, config) + # VectorOfVariables-in-Nonnegatives # VectorOfVariables-in-Nonpositives # VectorOfVariables-in-Zeros