|
| 1 | +using Test |
| 2 | + |
| 3 | +using MathOptInterface |
| 4 | +const MOI = MathOptInterface |
| 5 | +const MOIT = MathOptInterface.Test |
| 6 | +const MOIU = MathOptInterface.Utilities |
| 7 | +const MOIB = MathOptInterface.Bridges |
| 8 | + |
| 9 | +include("../utilities.jl") |
| 10 | + |
| 11 | +mock = MOIU.MockOptimizer(MOIU.Model{Float64}()) |
| 12 | +config = MOIT.TestConfig() |
| 13 | + |
| 14 | +bridged_mock = MOIB.Variable.Vectorize{Float64}(mock) |
| 15 | + |
| 16 | +@testset "get scalar constraint" begin |
| 17 | + x, cx = MOI.add_constrained_variable(bridged_mock, MOI.GreaterThan(1.0)) |
| 18 | + fx = MOI.SingleVariable(x) |
| 19 | + func = 2.0 * fx |
| 20 | + set = MOI.GreaterThan(5.0) |
| 21 | + err = MOI.ScalarFunctionConstantNotZero{ |
| 22 | + Float64, typeof(func), typeof(set)}(1.0) |
| 23 | + @test_throws err MOI.add_constraint(bridged_mock, func + 1.0, set) |
| 24 | + |
| 25 | + c = MOI.add_constraint(bridged_mock, func, set) |
| 26 | + @test MOI.get(bridged_mock, MOI.ConstraintFunction(), c) ≈ func |
| 27 | + @test MOI.get(bridged_mock, MOI.ConstraintSet(), c) == set |
| 28 | + MOI.set(bridged_mock, MOI.ConstraintName(), c, "c") |
| 29 | + |
| 30 | + @testset "Mock model" begin |
| 31 | + MOI.set(mock, MOI.VariableName(), |
| 32 | + MOI.get(mock, MOI.ListOfVariableIndices()), ["y"]) |
| 33 | + MOI.set(mock, MOI.ConstraintName(), |
| 34 | + MOI.get(mock, MOI.ListOfConstraintIndices{ |
| 35 | + MOI.VectorOfVariables, MOI.Nonnegatives}()), |
| 36 | + ["cy"]) |
| 37 | + s = """ |
| 38 | + variables: y |
| 39 | + cy: [y] in MathOptInterface.Nonnegatives(1) |
| 40 | + c: 2.0y >= 3.0 |
| 41 | + """ |
| 42 | + model = MOIU.Model{Float64}() |
| 43 | + MOIU.loadfromstring!(model, s) |
| 44 | + MOIU.test_models_equal(mock, model, ["y"], ["cy", "c"]) |
| 45 | + end |
| 46 | + @testset "Bridged model" begin |
| 47 | + MOI.set(bridged_mock, MOI.VariableName(), x, "x") |
| 48 | + MOI.set(bridged_mock, MOI.ConstraintName(), cx, "cx") |
| 49 | + s = """ |
| 50 | + variables: x |
| 51 | + cx: x >= 1.0 |
| 52 | + c: 2.0x >= 5.0 |
| 53 | + """ |
| 54 | + model = MOIU.Model{Float64}() |
| 55 | + MOIU.loadfromstring!(model, s) |
| 56 | + MOIU.test_models_equal(bridged_mock, model, ["x"], ["cx", "c"]) |
| 57 | + end |
| 58 | +end |
| 59 | + |
| 60 | +@testset "exp3 with add_constrained_variable for `y`" begin |
| 61 | + mock.optimize! = (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [log(5), 0.0], |
| 62 | + (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => [0.0], |
| 63 | + (MOI.VectorAffineFunction{Float64}, MOI.ExponentialCone) => [[-1.0, log(5)-1, 1/5]]) |
| 64 | + |
| 65 | + MOI.empty!(bridged_mock) |
| 66 | + x = MOI.add_variable(bridged_mock) |
| 67 | + @test MOI.get(bridged_mock, MOI.NumberOfVariables()) == 1 |
| 68 | + fx = MOI.SingleVariable(x) |
| 69 | + xc = MOI.add_constraint(bridged_mock, 2.0fx, MOI.LessThan(4.0)) |
| 70 | + y, yc = MOI.add_constrained_variable(bridged_mock, MOI.LessThan(5.0)) |
| 71 | + @test yc.value == y.value == -1 |
| 72 | + @test MOI.get(bridged_mock, MOI.NumberOfVariables()) == 2 |
| 73 | + @test length(MOI.get(bridged_mock, MOI.ListOfVariableIndices())) == 2 |
| 74 | + @test Set(MOI.get(bridged_mock, MOI.ListOfVariableIndices())) == Set([x, y]) |
| 75 | + fy = MOI.SingleVariable(y) |
| 76 | + ec = MOI.add_constraint(bridged_mock, |
| 77 | + MOIU.operate(vcat, Float64, fx, 1.0, fy), |
| 78 | + MOI.ExponentialCone()) |
| 79 | + |
| 80 | + MOI.optimize!(bridged_mock) |
| 81 | + @test MOI.get(bridged_mock, MOI.VariablePrimal(), x) ≈ log(5) |
| 82 | + @test MOI.get(bridged_mock, MOI.VariablePrimal(), y) ≈ 5.0 |
| 83 | + @test MOI.get(bridged_mock, MOI.ConstraintPrimal(), xc) ≈ 2log(5) |
| 84 | + @test MOI.get(bridged_mock, MOI.ConstraintPrimal(), yc) ≈ 5 |
| 85 | + @test MOI.get(bridged_mock, MOI.ConstraintPrimal(), ec) ≈ [log(5), 1., 5.0] |
| 86 | + @test MOI.get(bridged_mock, MOI.ConstraintDual(), xc) ≈ 0.0 |
| 87 | + @test MOI.get(bridged_mock, MOI.ConstraintDual(), yc) ≈ -1/5 |
| 88 | + @test MOI.get(bridged_mock, MOI.ConstraintDual(), ec) ≈ [-1., log(5)-1, 1/5] |
| 89 | + |
| 90 | + err = ErrorException( |
| 91 | + "Cannot add two `SingleVariable`-in-`MathOptInterface.LessThan{Float64}`" * |
| 92 | + " on the same variable MathOptInterface.VariableIndex(-1)." |
| 93 | + ) |
| 94 | + @test_throws err MOI.add_constraint(bridged_mock, MOI.SingleVariable(y), MOI.LessThan(4.0)) |
| 95 | + |
| 96 | + cis = MOI.get(bridged_mock, MOI.ListOfConstraintIndices{ |
| 97 | + MOI.VectorAffineFunction{Float64}, MOI.ExponentialCone}()) |
| 98 | + @test length(cis) == 1 |
| 99 | + |
| 100 | + @testset "get `UnknownVariableAttribute``" begin |
| 101 | + err = ArgumentError( |
| 102 | + "Variable bridge of type `MathOptInterface.Bridges.Variable.VectorizeBridge{Float64,MathOptInterface.Nonpositives}`" * |
| 103 | + " does not support accessing the attribute `MathOptInterface.Test.UnknownVariableAttribute()`." |
| 104 | + ) |
| 105 | + @test_throws err MOI.get(bridged_mock, MOIT.UnknownVariableAttribute(), y) |
| 106 | + end |
| 107 | + |
| 108 | + @testset "set `ConstraintSet`" begin |
| 109 | + ci = MOI.ConstraintIndex{MOI.SingleVariable, MOI.LessThan{Float64}}(y.value) |
| 110 | + attr = MOI.ConstraintSet() |
| 111 | + err = MOI.SetAttributeNotAllowed(attr, |
| 112 | + "The variable `MathOptInterface.VariableIndex(12345676)` is bridged by the `VectorizeBridge`.") |
| 113 | + @test_throws err MOI.set(bridged_mock, attr, ci, MOI.LessThan(4.0)) |
| 114 | + end |
| 115 | + |
| 116 | + @testset "MultirowChange" begin |
| 117 | + change = MOI.MultirowChange(y, [(3, 0.0)]) |
| 118 | + message = "The change MathOptInterface.MultirowChange{Float64}(MathOptInterface.VariableIndex(-1), Tuple{Int64,Float64}[(3, 0.0)])" * |
| 119 | + " contains variables bridged into a function with nonzero constant." |
| 120 | + err = MOI.ModifyConstraintNotAllowed(cis[1], change, message) |
| 121 | + @test_throws err MOI.modify(bridged_mock, cis[1], change) |
| 122 | + end |
| 123 | + |
| 124 | + @testset "ScalarCoefficientChange" begin |
| 125 | + change = MOI.ScalarCoefficientChange(y, 0.0) |
| 126 | + attr = MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}() |
| 127 | + message = "The change MathOptInterface.ScalarCoefficientChange{Float64}(MathOptInterface.VariableIndex(-1), 0.0)" * |
| 128 | + " contains variables bridged into a function with nonzero constant." |
| 129 | + err = MOI.ModifyObjectiveNotAllowed(change, message) |
| 130 | + @test_throws err MOI.modify(bridged_mock, attr, change) |
| 131 | + end |
| 132 | + |
| 133 | + MOI.set(bridged_mock, MOI.VariableName(), x, "x") |
| 134 | + MOI.set(bridged_mock, MOI.ConstraintName(), xc, "xc") |
| 135 | + MOI.set(bridged_mock, MOI.ConstraintName(), ec, "ec") |
| 136 | + @testset "Mock model" begin |
| 137 | + MOI.set(mock, MOI.VariableName(), |
| 138 | + MOI.get(mock, MOI.ListOfVariableIndices())[2], "z") |
| 139 | + MOI.set(mock, MOI.ConstraintName(), |
| 140 | + MOI.get(mock, MOI.ListOfConstraintIndices{ |
| 141 | + MOI.VectorOfVariables, MOI.Nonpositives}()), |
| 142 | + ["zc"]) |
| 143 | + s = """ |
| 144 | + variables: x, z |
| 145 | + zc: [z] in MathOptInterface.Nonpositives(1) |
| 146 | + xc: 2.0x <= 4.0 |
| 147 | + ec: [x, 1.0, z + 5.0] in MathOptInterface.ExponentialCone() |
| 148 | + """ |
| 149 | + model = MOIU.Model{Float64}() |
| 150 | + MOIU.loadfromstring!(model, s) |
| 151 | + MOIU.test_models_equal(mock, model, ["x", "z"], ["zc", "xc", "ec"]) |
| 152 | + end |
| 153 | + @testset "Bridged model" begin |
| 154 | + MOI.set(bridged_mock, MOI.VariableName(), y, "y") |
| 155 | + MOI.set(bridged_mock, MOI.ConstraintName(), yc, "yc") |
| 156 | + s = """ |
| 157 | + variables: x, y |
| 158 | + yc: y <= 5.0 |
| 159 | + xc: 2.0x <= 4.0 |
| 160 | + ec: [x, 1.0, y] in MathOptInterface.ExponentialCone() |
| 161 | + """ |
| 162 | + model = MOIU.Model{Float64}() |
| 163 | + MOIU.loadfromstring!(model, s) |
| 164 | + MOIU.test_models_equal(bridged_mock, model, ["x", "y"], ["yc", "xc", "ec"]) |
| 165 | + end |
| 166 | + |
| 167 | + test_delete_bridged_variable(bridged_mock, y, MOI.LessThan{Float64}, 2, ( |
| 168 | + (MOI.VectorOfVariables, MOI.Nonpositives, 0), |
| 169 | + )) |
| 170 | +end |
0 commit comments