diff --git a/src/Test/Test.jl b/src/Test/Test.jl index b4ff5aaa37..001d7881f2 100644 --- a/src/Test/Test.jl +++ b/src/Test/Test.jl @@ -116,7 +116,7 @@ function MOI.Test.setup_test( end ``` """ -setup_test(::Any, ::MOI.ModelLike, ::Config) = nothing +setup_test(::Any, ::MOI.ModelLike, ::Config{T}) where {T} = nothing """ version_added(::typeof(function_name)) diff --git a/src/Test/test_linear.jl b/src/Test/test_linear.jl index 8c3c9bd9c7..332f3c3fd3 100644 --- a/src/Test/test_linear.jl +++ b/src/Test/test_linear.jl @@ -40,11 +40,8 @@ function test_linear_integration( ) v = MOI.add_variables(model, 2) @test MOI.get(model, MOI.NumberOfVariables()) == 2 - cf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], v), - zero(T), - ) - c = MOI.add_constraint(model, cf, MOI.LessThan(one(T))) + cf = MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T(1), v), T(0)) + c = MOI.add_constraint(model, cf, MOI.LessThan(T(1))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, @@ -54,12 +51,12 @@ function test_linear_integration( }(), ) == 1 end - vc1 = MOI.add_constraint(model, v[1], MOI.GreaterThan(zero(T))) + vc1 = MOI.add_constraint(model, v[1], MOI.GreaterThan(T(0))) # We test this after the creation of every `VariableIndex` constraint # to ensure a good coverage of corner cases. @test vc1.value == v[1].value # test fallback - vc2 = MOI.add_constraint(model, v[2], MOI.GreaterThan(zero(T))) + vc2 = MOI.add_constraint(model, v[2], MOI.GreaterThan(T(0))) @test vc2.value == v[2].value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -70,13 +67,8 @@ function test_linear_integration( # Note: adding some redundant zero coefficients to catch solvers that don't # handle duplicate coefficients correctly: objf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{ - T, - }.( - [zero(T), zero(T), -one(T), zero(T), zero(T), zero(T)], - [v; v; v], - ), - zero(T), + MOI.ScalarAffineTerm{T}.(T[0, 0, -1, 0, 0, 0], [v; v; v]), + T(0), ) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @@ -90,41 +82,33 @@ function test_linear_integration( ) @test cf ≈ MOI.get(model, MOI.ConstraintFunction(), c) s = MOI.get(model, MOI.ConstraintSet(), c) - @test s == MOI.LessThan(one(T)) + @test s == MOI.LessThan(T(1)) s = MOI.get(model, MOI.ConstraintSet(), vc1) - @test s == MOI.GreaterThan(zero(T)) + @test s == MOI.GreaterThan(T(0)) s = MOI.get(model, MOI.ConstraintSet(), vc2) - @test s == MOI.GreaterThan(zero(T)) + @test s == MOI.GreaterThan(T(0)) end if _supports(config, MOI.optimize!) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMIZE_NOT_CALLED MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ -1 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(-1), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ -1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(-1), config) end - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [1, 0] atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[1, 0], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(1), config) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc1) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc2) ≈ 1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ConstraintDual(), c), T(-1), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc1), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc2), T(1), config) end end # change objective to Max +x - objf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), zero(T)], v), - zero(T), - ) + objf = + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T[1, 0], v), T(0)) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) if _supports(config, MOI.ObjectiveFunction) @@ -138,21 +122,16 @@ function test_linear_integration( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 1 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(1), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(1), config) end - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [1, 0] atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[1, 0], config) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc1) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc2) ≈ 1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ConstraintDual(), c), T(-1), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc1), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc2), T(1), config) end end # add new variable to get : @@ -170,14 +149,14 @@ function test_linear_integration( ) @test vars == [v[1], v[2]] || vars == [v[2], v[1]] @test MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), v[1])], - zero(T), + [MOI.ScalarAffineTerm{T}(T(1), v[1])], + T(0), ) ≈ MOI.get( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) end - vc3 = MOI.add_constraint(model, v[3], MOI.GreaterThan(zero(T))) + vc3 = MOI.add_constraint(model, v[3], MOI.GreaterThan(T(0))) @test vc3.value == v[3].value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -186,14 +165,12 @@ function test_linear_integration( ) == 3 end if _supports(config, MOI.ScalarCoefficientChange) - MOI.modify(model, c, MOI.ScalarCoefficientChange{T}(z, one(T))) + MOI.modify(model, c, MOI.ScalarCoefficientChange{T}(z, T(1))) else MOI.delete(model, c) - cf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T), one(T)], v), - zero(T), - ) - c = MOI.add_constraint(model, cf, MOI.LessThan(one(T))) + cf = + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T(1), v), T(0)) + c = MOI.add_constraint(model, cf, MOI.LessThan(T(1))) end MOI.modify( model, @@ -218,25 +195,18 @@ function test_linear_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus(1)) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 2 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(2), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 2 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(2), config) end - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [0, 0, 1] atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), [0, 0, 1], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(1), config) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -2 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc1) ≈ 1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc2) ≈ 2 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc3) ≈ 0 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ConstraintDual(), c), T(-2), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc1), T(1), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc2), T(2), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc3), T(0), config) end end # setting lb of x to -1 to get : @@ -244,27 +214,25 @@ function test_linear_integration( # s.t. x + y + z <= 1 # x >= -1 # y,z >= 0 - MOI.set(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan(-one(T))) + MOI.set(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan(T(-1))) if _supports(config, MOI.optimize!) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 3 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(3), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 3 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(3), config) end - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [-1, 0, 2] atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[-1, 0, 2], config) end # put lb of x back to 0 and fix z to zero to get : # max x + 2z # s.t. x + y + z <= 1 # x, y >= 0, z = 0 (vc3) - MOI.set(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan(zero(T))) + MOI.set(model, MOI.ConstraintSet(), vc1, MOI.GreaterThan(T(0))) MOI.delete(model, vc3) - vc3 = MOI.add_constraint(model, v[3], MOI.EqualTo(zero(T))) + vc3 = MOI.add_constraint(model, v[3], MOI.EqualTo(T(0))) @test vc3.value == v[3].value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -277,9 +245,8 @@ function test_linear_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 1 atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [1, 0, 0] atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(1), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[1, 0, 0], config) end # modify affine linear constraint set to be == 2 to get : # max x + 2z @@ -289,23 +256,8 @@ function test_linear_integration( # Note: adding some redundant zero coefficients to catch solvers that don't # handle duplicate coefficients correctly: cf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{ - T, - }.( - [ - zero(T), - zero(T), - zero(T), - one(T), - one(T), - one(T), - zero(T), - zero(T), - zero(T), - ], - [v; v; v], - ), - zero(T), + MOI.ScalarAffineTerm{T}.(T[0, 0, 0, 1, 1, 1, 0, 0, 0], [v; v; v]), + T(0), ) c = MOI.add_constraint(model, cf, MOI.EqualTo(T(2))) if _supports(config, MOI.NumberOfConstraints) @@ -329,17 +281,16 @@ function test_linear_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 2 atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [2, 0, 0] atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(2), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[2, 0, 0], config) end # modify objective function to x + 2y to get : # max x + 2y # s.t. x + y + z == 2 (c) # x,y >= 0, z = 0 objf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), T(2), zero(T)], v), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, 2, 0], v), + T(0), ) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -354,9 +305,8 @@ function test_linear_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 4 atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [0, 2, 0] atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[0, 2, 0], config) end # add constraint x - y >= 0 (c2) to get : # max x+2y @@ -364,10 +314,10 @@ function test_linear_integration( # x - y >= 0 (c2) # x,y >= 0 (vc1,vc2), z = 0 (vc3) cf2 = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T), zero(T)], v), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -1, 0], v), + T(0), ) - c2 = MOI.add_constraint(model, cf2, MOI.GreaterThan(zero(T))) + c2 = MOI.add_constraint(model, cf2, MOI.GreaterThan(T(0))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, @@ -408,35 +358,27 @@ function test_linear_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 3 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(3), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 3 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(3), config) end - @test MOI.get(model, MOI.VariablePrimal(), v) ≈ [1, 1, 0] atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 2 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c2) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), vc1) ≈ 1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), vc2) ≈ 1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), vc3) ≈ 0 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[1, 1, 0], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(2), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c2), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), vc1), T(1), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), vc2), T(1), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), vc3), T(0), config) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus(1)) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -T(3 // 2) atol = - atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), c2) ≈ T(1 // 2) atol = - atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), vc1) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc2) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), vc3) ≈ T(3 // 2) atol = - atol rtol = rtol + @test ≈(MOI.get(model, MOI.ConstraintDual(), c), T(-3 // 2), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), c2), T(1 // 2), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc1), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), vc2), T(0), config) + @test ≈( + MOI.get(model, MOI.ConstraintDual(), vc3), + T(3 // 2), + config, + ) end end if _supports(config, MOI.ConstraintFunction) @@ -467,8 +409,8 @@ function test_linear_integration( @test_throws err MOI.get(model, MOI.ConstraintSet(), vc1) @test MOI.get(model, MOI.ConstraintFunction(), c2) ≈ MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([-one(T), zero(T)], [v[2], z]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[-1, 0], [v[2], z]), + T(0), ) vrs = MOI.get(model, MOI.ListOfVariableIndices()) @test vrs == [v[2], z] || vrs == [z, v[2]] @@ -476,8 +418,8 @@ function test_linear_integration( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) ≈ MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), zero(T)], [v[2], z]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, 0], [v[2], z]), + T(0), ) end end @@ -485,39 +427,34 @@ end function setup_test( ::typeof(test_linear_integration), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1, 0], - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1], + T[1, 0], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1], ), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1, 0], - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1], + T[1, 0], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1], ), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [0, 0, 1], - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-2], + T[0, 0, 1], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-2], ), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [-1, 0, 2]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1, 0, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [2, 0, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 2, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[-1, 0, 2]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[1, 0, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[2, 0, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[0, 2, 0]), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1, 1, 0], - (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) => - [-1.5], - (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => - [0.5], + T[1, 1, 0], + (MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}) => T[-3//2], + (MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}) => T[1//2], ), ) return @@ -560,10 +497,10 @@ function test_linear_integration_2( y = MOI.add_variable(model) @test MOI.get(model, MOI.NumberOfVariables()) == 2 cf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ) - c = MOI.add_constraint(model, cf, MOI.LessThan(one(T))) + c = MOI.add_constraint(model, cf, MOI.LessThan(T(1))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, @@ -573,9 +510,9 @@ function test_linear_integration_2( }(), ) == 1 end - vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test vc1.value == x.value - vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test vc2.value == y.value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -584,8 +521,8 @@ function test_linear_integration_2( ) == 2 end objf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([-one(T), zero(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[-1, 0], [x, y]), + T(0), ) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @@ -595,24 +532,25 @@ function test_linear_integration_2( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ -1 atol = atol rtol = rtol + @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(-1) atol = atol rtol = + rtol if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ -1 atol = atol rtol = + @test MOI.get(model, MOI.DualObjectiveValue()) ≈ T(-1) atol = atol rtol = rtol end - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(1) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ 0 atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(0) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ T(1) atol = atol rtol = rtol if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c) ≈ T(-1) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), vc1) ≈ 0 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), vc1) ≈ T(0) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), vc2) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), vc2) ≈ T(1) atol = atol rtol = rtol end if _supports(config, MOI.ConstraintBasisStatus) @@ -629,17 +567,17 @@ end function setup_test( ::typeof(test_linear_integration_2), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1, 0], - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1], + T[1, 0], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => [MOI.NONBASIC], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => + [MOI.NONBASIC], ], variable_basis_status = [MOI.BASIC, MOI.NONBASIC_AT_LOWER], ), @@ -688,12 +626,9 @@ function test_linear_inactive_bounds( @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.LessThan{T}) x = MOI.add_variable(model) @test MOI.get(model, MOI.NumberOfVariables()) == 1 - vc = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + vc = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test vc.value == x.value - cf = MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), x)], - zero(T), - ) + cf = MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), x)], T(0)) c = MOI.add_constraint(model, cf, MOI.GreaterThan(T(3))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -708,10 +643,7 @@ function test_linear_inactive_bounds( }(), ) == 1 end - objf = MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), x)], - zero(T), - ) + objf = MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), x)], T(0)) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) if _supports(config, MOI.optimize!) @@ -734,12 +666,9 @@ function test_linear_inactive_bounds( @test MOI.is_empty(model) x = MOI.add_variable(model) @test MOI.get(model, MOI.NumberOfVariables()) == 1 - vc = MOI.add_constraint(model, x, MOI.LessThan(zero(T))) + vc = MOI.add_constraint(model, x, MOI.LessThan(T(0))) @test vc.value == x.value - cf = MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), x)], - zero(T), - ) + cf = MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), x)], T(0)) c = MOI.add_constraint(model, cf, MOI.LessThan(T(3))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -754,10 +683,7 @@ function test_linear_inactive_bounds( }(), ) == 1 end - objf = MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), x)], - zero(T), - ) + objf = MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), x)], T(0)) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) if _supports(config, MOI.optimize!) @@ -766,8 +692,9 @@ function test_linear_inactive_bounds( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 0 atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ 0 atol = atol rtol = + @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(0) atol = atol rtol = + rtol + @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(0) atol = atol rtol = rtol if _supports(config, MOI.ConstraintBasisStatus) @test MOI.get(model, MOI.VariableBasisStatus(), x) == @@ -780,15 +707,16 @@ end function setup_test( ::typeof(test_linear_inactive_bounds), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, [3], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.NONBASIC], + (MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}) => + [MOI.NONBASIC], ], variable_basis_status = [MOI.BASIC], ), @@ -796,7 +724,8 @@ function setup_test( mock, [0], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => [MOI.BASIC], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => + [MOI.BASIC], ], variable_basis_status = [MOI.NONBASIC_AT_UPPER], ), @@ -838,36 +767,36 @@ function test_linear_LessThan_and_GreaterThan( x = MOI.add_variable(model) y = MOI.add_variable(model) # Min x - y - # s.t. zero(T) <= x (c1) - # y <= zero(T) (c2) + # s.t. T(0) <= x (c1) + # y <= T(0) (c2) MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -1], [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) - fx = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(one(T), x)], zero(T)) - c1 = MOI.add_constraint(model, fx, MOI.GreaterThan(zero(T))) - fy = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(one(T), y)], zero(T)) - c2 = MOI.add_constraint(model, fy, MOI.LessThan(zero(T))) + fx = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(T(1), x)], T(0)) + c1 = MOI.add_constraint(model, fx, MOI.GreaterThan(T(0))) + fy = MOI.ScalarAffineFunction([MOI.ScalarAffineTerm(T(1), y)], T(0)) + c2 = MOI.add_constraint(model, fy, MOI.LessThan(T(0))) if _supports(config, MOI.optimize!) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMIZE_NOT_CALLED MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(0) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(0) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(0) atol = atol rtol = rtol end # Min x - y # s.t. T(100) <= x - # y <= zero(T) + # y <= T(0) MOI.set(model, MOI.ConstraintSet(), c1, MOI.GreaterThan(T(100))) if _supports(config, MOI.optimize!) MOI.optimize!(model) @@ -877,13 +806,13 @@ function test_linear_LessThan_and_GreaterThan( rtol @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(100) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(0) atol = atol rtol = rtol end # Min x - y # s.t. T(100) <= x - # y <= -T(100) - MOI.set(model, MOI.ConstraintSet(), c2, MOI.LessThan(-T(100))) + # y <= T(-100) + MOI.set(model, MOI.ConstraintSet(), c2, MOI.LessThan(T(-100))) if _supports(config, MOI.optimize!) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @@ -892,7 +821,7 @@ function test_linear_LessThan_and_GreaterThan( rtol @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(100) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ -T(100) atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(-100) atol = atol rtol = rtol end return @@ -901,13 +830,13 @@ end function setup_test( ::typeof(test_linear_LessThan_and_GreaterThan), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[0, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[100, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[100, -100]), ) return end @@ -959,12 +888,12 @@ function test_linear_integration_modification( y = MOI.add_variable(model) @test MOI.get(model, MOI.NumberOfVariables()) == 2 cf1 = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, 1], [x, y]), + T(0), ) cf2 = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), T(2)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, 2], [x, y]), + T(0), ) c1 = MOI.add_constraint(model, cf1, MOI.LessThan(T(4))) c2 = MOI.add_constraint(model, cf2, MOI.LessThan(T(4))) @@ -977,9 +906,9 @@ function test_linear_integration_modification( }(), ) == 2 end - vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test vc1.value == x.value - vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test vc2.value == y.value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( @@ -988,8 +917,8 @@ function test_linear_integration_modification( ) == 2 end objf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ) MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -1000,8 +929,11 @@ function test_linear_integration_modification( @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(8 // 3) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), [x, y]) ≈ - [T(4 // 3), T(4 // 3)] atol = atol rtol = rtol + @test ≈( + MOI.get(model, MOI.VariablePrimal(), [x, y]), + T[4//3, 4//3], + config, + ) end # copy and solve again # missing test @@ -1018,8 +950,8 @@ function test_linear_integration_modification( else MOI.delete(model, c1) cf1 = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), T(3)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, 3], [x, y]), + T(0), ) c1 = MOI.add_constraint(model, cf1, MOI.LessThan(T(4))) end @@ -1027,9 +959,8 @@ function test_linear_integration_modification( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 2 atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), [x, y]) ≈ [T(2), zero(T)] atol = - atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(2), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), [x, y]), T[2, 0], config) end # delconstrs and solve # maximize x + y @@ -1043,9 +974,8 @@ function test_linear_integration_modification( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 4 atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), [x, y]) ≈ [T(4), zero(T)] atol = - atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), 4, config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), [x, y]), T[4, 0], config) end # delvars and solve # maximize y @@ -1059,7 +989,8 @@ function test_linear_integration_modification( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 2 atol = atol rtol = rtol + @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(2) atol = atol rtol = + rtol @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(2) atol = atol rtol = rtol end @@ -1068,14 +999,14 @@ end function setup_test( ::typeof(test_linear_integration_modification), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [4 / 3, 4 / 3]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [2, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [4, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [2]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[4//3, 4//3]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[2, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[4, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[2]), ) return end @@ -1113,94 +1044,84 @@ function test_linear_modify_GreaterThan_and_LessThan_constraints( x = MOI.add_variable(model) y = MOI.add_variable(model) # Min x - y - # s.t. zero(T) <= x (c1) - # y <= zero(T) (c2) + # s.t. T(0) <= x (c1) + # y <= T(0) (c2) MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -1], [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) fx = convert(MOI.ScalarAffineFunction{T}, x) - c1 = MOI.add_constraint(model, fx, MOI.GreaterThan(zero(T))) + c1 = MOI.add_constraint(model, fx, MOI.GreaterThan(T(0))) fy = convert(MOI.ScalarAffineFunction{T}, y) - c2 = MOI.add_constraint(model, fy, MOI.LessThan(zero(T))) + c2 = MOI.add_constraint(model, fy, MOI.LessThan(T(0))) if _supports(config, MOI.ConstraintFunction) @test MOI.get(model, MOI.ConstraintFunction(), c1) ≈ fx - @test MOI.get(model, MOI.ConstraintSet(), c1) == - MOI.GreaterThan(zero(T)) + @test MOI.get(model, MOI.ConstraintSet(), c1) == MOI.GreaterThan(T(0)) @test MOI.get(model, MOI.ConstraintFunction(), c2) ≈ fy - @test MOI.get(model, MOI.ConstraintSet(), c2) == MOI.LessThan(zero(T)) + @test MOI.get(model, MOI.ConstraintSet(), c2) == MOI.LessThan(T(0)) end if _supports(config, MOI.optimize!) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMIZE_NOT_CALLED MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ zero(T) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ zero(T) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(0), config) end # Min x - y # s.t. T(100) <= x - # y <= zero(T) + # y <= T(0) MOI.set(model, MOI.ConstraintSet(), c1, MOI.GreaterThan(T(100))) if _supports(config, MOI.ConstraintFunction) @test MOI.get(model, MOI.ConstraintFunction(), c1) ≈ fx @test MOI.get(model, MOI.ConstraintSet(), c1) == MOI.GreaterThan(T(100)) @test MOI.get(model, MOI.ConstraintFunction(), c2) ≈ fy - @test MOI.get(model, MOI.ConstraintSet(), c2) == MOI.LessThan(zero(T)) + @test MOI.get(model, MOI.ConstraintSet(), c2) == MOI.LessThan(T(0)) end if _supports(config, MOI.optimize!) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(100) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(100) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(100), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(100), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(0), config) end # Min x - y # s.t. T(100) <= x - # y <= -T(100) - MOI.set(model, MOI.ConstraintSet(), c2, MOI.LessThan(-T(100))) + # y <= T(-100) + MOI.set(model, MOI.ConstraintSet(), c2, MOI.LessThan(T(-100))) if _supports(config, MOI.ConstraintFunction) @test MOI.get(model, MOI.ConstraintFunction(), c1) ≈ fx @test MOI.get(model, MOI.ConstraintSet(), c1) == MOI.GreaterThan(T(100)) @test MOI.get(model, MOI.ConstraintFunction(), c2) ≈ fy - @test MOI.get(model, MOI.ConstraintSet(), c2) == MOI.LessThan(-T(100)) + @test MOI.get(model, MOI.ConstraintSet(), c2) == MOI.LessThan(T(-100)) end if _supports(config, MOI.optimize!) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(200) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(100) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ -T(100) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(200), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(100), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(-100), config) end end function setup_test( ::typeof(test_linear_modify_GreaterThan_and_LessThan_constraints), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[0, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[100, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[100, -100]), ) return end @@ -1254,30 +1175,30 @@ function test_linear_VectorAffineFunction( x = MOI.add_variable(model) y = MOI.add_variable(model) # Min x - y - # s.t. zero(T) <= x (c1) - # y <= zero(T) (c2) + # s.t. T(0) <= x (c1) + # y <= T(0) (c2) MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -1], [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) c1 = MOI.add_constraint( model, MOI.VectorAffineFunction{T}( - [MOI.VectorAffineTerm{T}(1, MOI.ScalarAffineTerm{T}(one(T), x))], - [zero(T)], + [MOI.VectorAffineTerm{T}(1, MOI.ScalarAffineTerm{T}(T(1), x))], + T[0], ), MOI.Nonnegatives(1), ) c2 = MOI.add_constraint( model, MOI.VectorAffineFunction{T}( - [MOI.VectorAffineTerm{T}(1, MOI.ScalarAffineTerm{T}(one(T), y))], - [zero(T)], + [MOI.VectorAffineTerm{T}(1, MOI.ScalarAffineTerm{T}(T(1), y))], + T[0], ), MOI.Nonpositives(1), ) @@ -1286,30 +1207,22 @@ function test_linear_VectorAffineFunction( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ zero(T) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ zero(T) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(0), config) end # Min x - y # s.t. T(100) <= x - # y <= zero(T) + # y <= T(0) if _supports(config, MOI.VectorConstantChange) - MOI.modify(model, c1, MOI.VectorConstantChange([-T(100)])) + MOI.modify(model, c1, MOI.VectorConstantChange(T[-100])) else MOI.delete(model, c1) c1 = MOI.add_constraint( model, MOI.VectorAffineFunction{T}( - [ - MOI.VectorAffineTerm{T}( - 1, - MOI.ScalarAffineTerm{T}(one(T), x), - ), - ], - [-T(100)], + [MOI.VectorAffineTerm{T}(1, MOI.ScalarAffineTerm{T}(T(1), x))], + T[-100], ), MOI.Nonnegatives(1), ) @@ -1318,30 +1231,22 @@ function test_linear_VectorAffineFunction( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(100) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(100) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(100), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(100), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(0), config) end # Min x - y # s.t. T(100) <= x - # y <= -T(100) + # y <= T(-100) if _supports(config, MOI.VectorConstantChange) - MOI.modify(model, c2, MOI.VectorConstantChange([T(100)])) + MOI.modify(model, c2, MOI.VectorConstantChange(T[100])) else MOI.delete(model, c2) c2 = MOI.add_constraint( model, MOI.VectorAffineFunction{T}( - [ - MOI.VectorAffineTerm{T}( - 1, - MOI.ScalarAffineTerm{T}(one(T), y), - ), - ], - [T(100)], + [MOI.VectorAffineTerm{T}(1, MOI.ScalarAffineTerm{T}(T(1), y))], + T[100], ), MOI.Nonpositives(1), ) @@ -1350,25 +1255,22 @@ function test_linear_VectorAffineFunction( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(200) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(100) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ -T(100) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(200), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(100), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(-100), config) end end function setup_test( ::typeof(test_linear_VectorAffineFunction), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, 0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [100, -100]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[0, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[100, 0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[100, -100]), ) return end @@ -1411,22 +1313,19 @@ function test_linear_INFEASIBLE( c = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, 1], [x, y]), + T(0), ), - MOI.LessThan(-one(T)), + MOI.LessThan(T(-1)), ) - bndx = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + bndx = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test bndx.value == x.value - bndy = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + bndy = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test bndy.value == y.value MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), - MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), x)], - zero(T), - ), + MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), x)], T(0)), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) if _supports(config, MOI.optimize!) @@ -1456,8 +1355,8 @@ end function setup_test( ::typeof(test_linear_INFEASIBLE), mock::MOIU.MockOptimizer, - config::Config, -) + config::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( @@ -1465,8 +1364,7 @@ function setup_test( MOI.INFEASIBLE, MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1], ), ) return @@ -1484,8 +1382,6 @@ function test_linear_DUAL_INFEASIBLE( model::MOI.ModelLike, config::Config{T}, ) where {T} - atol = config.atol - rtol = config.rtol # min -x-y # s.t. -x+2y <= 0 # x,y >= 0 @@ -1510,21 +1406,21 @@ function test_linear_DUAL_INFEASIBLE( MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([-one(T), T(2)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[-1, 2], [x, y]), + T(0), ), - MOI.LessThan(zero(T)), + MOI.LessThan(T(0)), ) - vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test vc1.value == x.value - vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test vc2.value == y.value MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([-one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(-1), [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @@ -1544,8 +1440,8 @@ end function setup_test( ::typeof(test_linear_DUAL_INFEASIBLE), mock::MOIU.MockOptimizer, - config::Config, -) + config::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( @@ -1595,21 +1491,21 @@ function test_linear_DUAL_INFEASIBLE_2( MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -1], [x, y]), + T(0), ), - MOI.EqualTo(zero(T)), + MOI.EqualTo(T(0)), ) - vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + vc1 = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test vc1.value == x.value - vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + vc2 = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test vc2.value == y.value MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([-one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(-1), [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @@ -1631,14 +1527,14 @@ end function setup_test( ::typeof(test_linear_DUAL_INFEASIBLE_2), mock::MOIU.MockOptimizer, - config::Config, -) + config::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, MOI.DUAL_INFEASIBLE, - (MOI.INFEASIBILITY_CERTIFICATE, [1, 1]), + (MOI.INFEASIBILITY_CERTIFICATE, T[1, 1]), ), ) return @@ -1657,8 +1553,6 @@ function test_linear_add_constraints( model::MOI.ModelLike, config::Config{T}, ) where {T} - atol = config.atol - rtol = config.rtol # maximize 1000 x + 350 y # # s.t. x >= 30 @@ -1695,7 +1589,7 @@ function test_linear_add_constraints( vc12 = MOI.add_constraints( model, [x, y], - [MOI.GreaterThan(T(30)), MOI.GreaterThan(zero(T))], + [MOI.GreaterThan(T(30)), MOI.GreaterThan(T(0))], ) @test vc12[1].value == x.value @test vc12[2].value == y.value @@ -1703,22 +1597,22 @@ function test_linear_add_constraints( model, [ MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -T(3 // 2)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -3//2], [x, y]), + T(0), ), ], - [MOI.GreaterThan(zero(T))], + [MOI.GreaterThan(T(0))], ) c23 = MOI.add_constraints( model, [ MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(12), T(8)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[12, 8], [x, y]), + T(0), ), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(1_000), T(300)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1_000, 300], [x, y]), + T(0), ), ], [MOI.LessThan(T(1_000)), MOI.LessThan(T(70_000))], @@ -1727,8 +1621,8 @@ function test_linear_add_constraints( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(1_000), T(350)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1_000, 350], [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -1737,12 +1631,9 @@ function test_linear_add_constraints( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 790_000 / T(11) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ 650 / T(11) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ 400 / T(11) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(790_000 // 11), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(650 // 11), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(400 // 11), config) if _supports(config, MOI.ConstraintBasisStatus) @test MOI.get(model, MOI.VariableBasisStatus(), x) == MOI.BASIC @test MOI.get(model, MOI.VariableBasisStatus(), y) == MOI.BASIC @@ -1759,16 +1650,18 @@ end function setup_test( ::typeof(test_linear_add_constraints), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [650 / 11, 400 / 11], + T[650//11, 400//11], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => [MOI.NONBASIC, MOI.NONBASIC], - (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => [MOI.BASIC], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => + [MOI.NONBASIC, MOI.NONBASIC], + (MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}) => + [MOI.BASIC], ], variable_basis_status = [MOI.BASIC, MOI.BASIC], ), @@ -1816,15 +1709,15 @@ function test_linear_integration_Interval( vc = MOI.add_constraints( model, [x, y], - [MOI.GreaterThan(zero(T)), MOI.GreaterThan(zero(T))], + [MOI.GreaterThan(T(0)), MOI.GreaterThan(T(0))], ) @test vc[1].value == x.value @test vc[2].value == y.value c = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ), MOI.Interval(T(5), T(10)), ) @@ -1832,8 +1725,8 @@ function test_linear_integration_Interval( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -1842,19 +1735,15 @@ function test_linear_integration_Interval( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(10) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(10), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ T(10) atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(10)) end - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 10 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(10)) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ConstraintDual(), c), T(-1), config) end if _supports(config, MOI.ConstraintBasisStatus) # There are multiple optimal bases. Either x or y can be in the @@ -1871,8 +1760,8 @@ function test_linear_integration_Interval( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @@ -1891,7 +1780,7 @@ function test_linear_integration_Interval( if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c) ≈ T(1) atol = atol rtol = rtol end if _supports(config, MOI.ConstraintBasisStatus) @@ -1920,7 +1809,7 @@ function test_linear_integration_Interval( @test MOI.get(model, MOI.DualObjectiveValue()) ≈ T(2) atol = atol rtol = rtol end - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 2 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ T(2) atol = atol rtol = rtol if _supports(config, MOI.ConstraintBasisStatus) # There are multiple optimal bases. Either x or y can be in the @@ -1935,7 +1824,7 @@ function test_linear_integration_Interval( if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c) ≈ T(1) atol = atol rtol = rtol end end @@ -1943,8 +1832,8 @@ function test_linear_integration_Interval( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -1972,47 +1861,47 @@ end function setup_test( ::typeof(test_linear_integration_Interval), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [5.0, 5.0], + T[5, 5], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => [MOI.NONBASIC_AT_UPPER], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => + [MOI.NONBASIC_AT_UPPER], ], variable_basis_status = [MOI.BASIC, MOI.BASIC], - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => - [-1], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => T[-1], ), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [2.5, 2.5], + T[5//2, 5//2], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => [MOI.NONBASIC_AT_LOWER], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => + [MOI.NONBASIC_AT_LOWER], ], variable_basis_status = [MOI.BASIC, MOI.BASIC], - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => - [1], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => T[1], ), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1.0, 1.0], - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => - [1], + T[1, 1], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => T[1], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => [MOI.NONBASIC_AT_LOWER], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => + [MOI.NONBASIC_AT_LOWER], ], variable_basis_status = [MOI.BASIC, MOI.BASIC], ), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [6.0, 6.0], - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => - [-1], + T[6, 6], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => T[-1], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => [MOI.NONBASIC_AT_UPPER], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => + [MOI.NONBASIC_AT_UPPER], ], variable_basis_status = [MOI.BASIC, MOI.BASIC], ), @@ -2060,24 +1949,24 @@ function test_linear_Interval_inactive( vc = MOI.add_constraints( model, [x, y], - [MOI.GreaterThan(zero(T)), MOI.GreaterThan(zero(T))], + [MOI.GreaterThan(T(0)), MOI.GreaterThan(T(0))], ) @test vc[1].value == x.value @test vc[2].value == y.value c = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ), - MOI.Interval(-one(T), T(10)), + MOI.Interval(T(-1), T(10)), ) MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @@ -2086,19 +1975,19 @@ function test_linear_Interval_inactive( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(0) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ T(0) atol = atol rtol = rtol if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c) ≈ T(0) atol = atol rtol = + rtol + @test MOI.get(model, MOI.ConstraintDual(), vc[1]) ≈ T(1) atol = atol rtol = + rtol + @test MOI.get(model, MOI.ConstraintDual(), vc[2]) ≈ T(1) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), vc[1]) ≈ one(T) atol = - atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), vc[2]) ≈ one(T) atol = - atol rtol = rtol end if _supports(config, MOI.ConstraintBasisStatus) @test ( @@ -2117,22 +2006,22 @@ end function setup_test( ::typeof(test_linear_Interval_inactive), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [0.0, 0.0], + T[0, 0], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => [MOI.BASIC], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => + [MOI.BASIC], ], variable_basis_status = [ MOI.NONBASIC_AT_LOWER, MOI.NONBASIC_AT_LOWER, ], - (MOI.ScalarAffineFunction{Float64}, MOI.Interval{Float64}) => - [0], + (MOI.ScalarAffineFunction{T}, MOI.Interval{T}) => [0], ), ) return @@ -2202,27 +2091,18 @@ function test_linear_transform( v = MOI.add_variables(model, 2) c1 = MOI.add_constraint( model, - MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], v), - zero(T), - ), - MOI.GreaterThan(one(T)), + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T(1), v), T(0)), + MOI.GreaterThan(T(1)), ) c2 = MOI.add_constraint( model, - MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], v), - zero(T), - ), + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T(1), v), T(0)), MOI.GreaterThan(T(2)), ) MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), - MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), one(T)], v), - zero(T), - ), + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T(1), v), T(0)), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) if _supports(config, MOI.optimize!) @@ -2244,7 +2124,7 @@ function test_linear_transform( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ one(T) atol = atol rtol = + @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(1) atol = atol rtol = rtol end end @@ -2252,12 +2132,12 @@ end function setup_test( ::typeof(test_linear_transform), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 1.0]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0.5, 0.5]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[1, 1]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[1//2, 1//2]), ) return end @@ -2305,30 +2185,24 @@ function test_linear_INFEASIBLE_2( c1 = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), -T(3)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, -3], [x, y]), + T(0), ), - MOI.LessThan(-T(7)), + MOI.LessThan(T(-7)), ) c2 = MOI.add_constraint( model, - MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), y)], - zero(T), - ), + MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), y)], T(0)), MOI.LessThan(T(2)), ) - bndx = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + bndx = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test bndx.value == x.value - bndy = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + bndy = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test bndy.value == y.value MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), - MOI.ScalarAffineFunction{T}( - [MOI.ScalarAffineTerm{T}(one(T), x)], - zero(T), - ), + MOI.ScalarAffineFunction{T}([MOI.ScalarAffineTerm{T}(T(1), x)], T(0)), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) if _supports(config, MOI.optimize!) @@ -2357,8 +2231,8 @@ end function setup_test( ::typeof(test_linear_INFEASIBLE_2), mock::MOIU.MockOptimizer, - config::Config, -) + config::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( @@ -2366,8 +2240,7 @@ function setup_test( MOI.INFEASIBLE, MOI.NO_SOLUTION, MOI.INFEASIBILITY_CERTIFICATE, - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1, -1], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1, -1], ), ) return @@ -2410,18 +2283,18 @@ function test_linear_FEASIBILITY_SENSE( c1 = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), T(3)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, 3], [x, y]), + T(0), ), - MOI.GreaterThan(one(T)), + MOI.GreaterThan(T(1)), ) c2 = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[1, -1], [x, y]), + T(0), ), - MOI.EqualTo(zero(T)), + MOI.EqualTo(T(0)), ) MOI.set(model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE) @test MOI.get(model, MOI.ObjectiveSense()) == MOI.FEASIBILITY_SENSE @@ -2434,18 +2307,17 @@ function test_linear_FEASIBILITY_SENSE( xsol = MOI.get(model, MOI.VariablePrimal(), x) ysol = MOI.get(model, MOI.VariablePrimal(), y) c1sol = 2 * xsol + 3 * ysol - @test c1sol >= 1 || isapprox(c1sol, one(T), atol = atol, rtol = rtol) - @test xsol - ysol ≈ 0 atol = atol rtol = rtol + @test c1sol >= 1 || isapprox(c1sol, T(1), atol = atol, rtol = rtol) + @test xsol - ysol ≈ T(0) atol = atol rtol = rtol c1primval = MOI.get(model, MOI.ConstraintPrimal(), c1) - @test c1primval >= 1 || - isapprox(c1sol, one(T), atol = atol, rtol = rtol) - @test MOI.get(model, MOI.ConstraintPrimal(), c2) ≈ 0 atol = atol rtol = + @test c1primval >= 1 || isapprox(c1sol, T(1), atol = atol, rtol = rtol) + @test MOI.get(model, MOI.ConstraintPrimal(), c2) ≈ T(0) atol = atol rtol = rtol if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c1) ≈ 0 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c1) ≈ T(0) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), c2) ≈ 0 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c2) ≈ T(0) atol = atol rtol = rtol end end @@ -2454,17 +2326,15 @@ end function setup_test( ::typeof(test_linear_FEASIBILITY_SENSE), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1 / 5, 1 / 5], - (MOI.ScalarAffineFunction{Float64}, MOI.GreaterThan{Float64}) => - [0], - (MOI.ScalarAffineFunction{Float64}, MOI.EqualTo{Float64}) => - [0], + T[1//5, 1//5], + (MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T}) => T[0], + (MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}) => T[0], ), ) return @@ -2509,24 +2379,24 @@ function test_linear_integration_delete_variables( c = MOI.add_constraint( model, MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(3), T(2), one(T)], [x, y, z]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[3, 2, 1], [x, y, z]), + T(0), ), MOI.LessThan(T(2)), ) - clbx = MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) + clbx = MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) @test clbx.value == x.value - clby = MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + clby = MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) @test clby.value == y.value - clbz = MOI.add_constraint(model, z, MOI.GreaterThan(zero(T))) + clbz = MOI.add_constraint(model, z, MOI.GreaterThan(T(0))) @test clbz.value == z.value - cubz = MOI.add_constraint(model, z, MOI.LessThan(one(T))) + cubz = MOI.add_constraint(model, z, MOI.LessThan(T(1))) @test cubz.value == z.value MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), T(2), T(3)], [x, y, z]), + MOI.ScalarAffineTerm{T}.(T[1, 2, 3], [x, y, z]), T(4), ), ) @@ -2536,39 +2406,25 @@ function test_linear_integration_delete_variables( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 8 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(8), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 8 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(8), config) end - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ 1 / T(2) atol = atol rtol = - rtol - @test MOI.get(model, MOI.VariablePrimal(), z) ≈ 1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 2 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), clbx) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), clby) ≈ 1 / T(2) atol = - atol rtol = rtol - @test MOI.get(model, MOI.ConstraintPrimal(), clbz) ≈ 1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintPrimal(), cubz) ≈ 1 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), x), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), y), T(1 // 2), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z), T(1), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(2), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), clbx), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), clby), T(1 // 2), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), clbz), T(1), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), cubz), T(1), config) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -1 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), clbx) ≈ 2 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), clby) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), clbz) ≈ 0 atol = atol rtol = - rtol - @test MOI.get(model, MOI.ConstraintDual(), cubz) ≈ -2 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.ConstraintDual(), c), T(-1), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), clbx), T(2), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), clby), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), clbz), T(0), config) + @test ≈(MOI.get(model, MOI.ConstraintDual(), cubz), T(-2), config) if _supports(config, MOI.ConstraintBasisStatus) @test MOI.get(model, MOI.VariableBasisStatus(), x) == MOI.NONBASIC_AT_LOWER @@ -2590,17 +2446,17 @@ function test_linear_integration_delete_variables( @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 6 atol = atol rtol = rtol end - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(1) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ 2 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintPrimal(), c) ≈ T(2) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintPrimal(), clby) ≈ 1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintPrimal(), clby) ≈ T(1) atol = atol rtol = rtol if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ConstraintDual(), c) ≈ -1 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), c) ≈ T(-1) atol = atol rtol = rtol - @test MOI.get(model, MOI.ConstraintDual(), clby) ≈ 0 atol = atol rtol = + @test MOI.get(model, MOI.ConstraintDual(), clby) ≈ T(0) atol = atol rtol = rtol end end @@ -2609,32 +2465,31 @@ end function setup_test( ::typeof(test_linear_integration_delete_variables), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [0, 1 / 2, 1], + T[0, 1//2, 1], constraint_basis_status = [ - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => [MOI.NONBASIC], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => + [MOI.NONBASIC], ], variable_basis_status = [ MOI.NONBASIC_AT_LOWER, MOI.BASIC, MOI.NONBASIC_AT_UPPER, ], - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1], - (MOI.VariableIndex, MOI.GreaterThan{Float64}) => [2, 0, 0], - (MOI.VariableIndex, MOI.LessThan{Float64}) => [-2], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1], + (MOI.VariableIndex, MOI.GreaterThan{T}) => T[2, 0, 0], + (MOI.VariableIndex, MOI.LessThan{T}) => T[-2], ), (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [1], - (MOI.ScalarAffineFunction{Float64}, MOI.LessThan{Float64}) => - [-1], - (MOI.VariableIndex, MOI.GreaterThan{Float64}) => [0], + T[1], + (MOI.ScalarAffineFunction{T}, MOI.LessThan{T}) => T[-1], + (MOI.VariableIndex, MOI.GreaterThan{T}) => T[0], ), ) # test_linear_integration_delete_variables has double variable bounds for @@ -2682,18 +2537,15 @@ function test_linear_VectorAffineFunction_empty_row( c = MOI.add_constraint( model, MOI.VectorAffineFunction{T}( - MOI.VectorAffineTerm{T}.(2, MOI.ScalarAffineTerm{T}.([one(T)], x)), - zeros(2), + MOI.VectorAffineTerm{T}.(2, MOI.ScalarAffineTerm{T}.(T[1], x)), + zeros(T, 2), ), MOI.Zeros(2), ) MOI.set( model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), - MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([zero(T)], x), - zero(T), - ), + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T[0], x), T(0)), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) if _supports(config, MOI.optimize!) @@ -2701,13 +2553,11 @@ function test_linear_VectorAffineFunction_empty_row( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test MOI.get(model, MOI.ObjectiveValue()) ≈ 0 atol = atol rtol = rtol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(0), config) if _supports(config, MOI.DualObjectiveValue) - @test MOI.get(model, MOI.DualObjectiveValue()) ≈ 0 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.DualObjectiveValue()), T(0), config) end - @test MOI.get(model, MOI.VariablePrimal(), x[1]) ≈ 0 atol = atol rtol = - rtol + @test ≈(MOI.get(model, MOI.VariablePrimal(), x[1]), T(0), config) if _supports(config, MOI.ConstraintDual) @test MOI.get(model, MOI.DualStatus()) == MOI.FEASIBLE_POINT end @@ -2717,14 +2567,14 @@ end function setup_test( ::typeof(test_linear_VectorAffineFunction_empty_row), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( mock, - [0.0], - (MOI.VectorAffineFunction{Float64}, MOI.Zeros) => [[0.0, 0.0]], + T[0], + (MOI.VectorAffineFunction{T}, MOI.Zeros) => [T[0, 0]], ), ) return @@ -2748,7 +2598,7 @@ The problem is s.t. x + y <= 1 x, y >= 0 ``` -where `x` starts at `one(T)`. Start point for `y` is unspecified. +where `x` starts at `T(1)`. Start point for `y` is unspecified. """ function test_linear_VariablePrimalStart_partial( model::MOI.ModelLike, @@ -2758,29 +2608,29 @@ function test_linear_VariablePrimalStart_partial( rtol = config.rtol x = MOI.add_variable(model) y = MOI.add_variable(model) - MOI.set(model, MOI.VariablePrimalStart(), x, one(T)) - MOI.add_constraint(model, x, MOI.GreaterThan(zero(T))) - MOI.add_constraint(model, y, MOI.GreaterThan(zero(T))) + MOI.set(model, MOI.VariablePrimalStart(), x, T(1)) + MOI.add_constraint(model, x, MOI.GreaterThan(T(0))) + MOI.add_constraint(model, y, MOI.GreaterThan(T(0))) obj = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([T(2), one(T)], [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T[2, 1], [x, y]), + T(0), ) MOI.set(model, MOI.ObjectiveFunction{typeof(obj)}(), obj) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) x_plus_y = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.(one(T), [x, y]), - zero(T), + MOI.ScalarAffineTerm{T}.(T(1), [x, y]), + T(0), ) - MOI.add_constraint(model, x_plus_y, MOI.LessThan(one(T))) + MOI.add_constraint(model, x_plus_y, MOI.LessThan(T(1))) if _supports(config, MOI.optimize!) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT @test MOI.get(model, MOI.ObjectiveValue()) ≈ T(2) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), x) ≈ one(T) atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), x) ≈ T(1) atol = atol rtol = rtol - @test MOI.get(model, MOI.VariablePrimal(), y) ≈ zero(T) atol = atol rtol = + @test MOI.get(model, MOI.VariablePrimal(), y) ≈ T(0) atol = atol rtol = rtol end end @@ -2788,17 +2638,20 @@ end function setup_test( ::typeof(test_linear_VariablePrimalStart_partial), mock::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( mock, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1.0, 0.0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[1, 0]), ) return end """ - test_linear_integer_integration(model::MOI.ModelLike, config::Config) + test_linear_integer_integration( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Run an integration test on the MILP: ``` @@ -2810,67 +2663,68 @@ s.t. x + y + z <= 10 z is binary ``` """ -function test_linear_integer_integration(model::MOI.ModelLike, config::Config) +function test_linear_integer_integration( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports_incremental_interface(model) @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) @requires MOI.supports_constraint( model, - MOI.ScalarAffineFunction{Float64}, - MOI.LessThan{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.LessThan{T}, ) @requires MOI.supports_constraint( model, MOI.VariableIndex, - MOI.GreaterThan{Float64}, + MOI.GreaterThan{T}, ) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.Integer) v = MOI.add_variables(model, 3) @test MOI.get(model, MOI.NumberOfVariables()) == 3 - cf = - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 1.0, 1.0], v), 0.0) - c = MOI.add_constraint(model, cf, MOI.LessThan(10.0)) + cf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(T(1), v), T(0)) + c = MOI.add_constraint(model, cf, MOI.LessThan(T(10))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, MOI.NumberOfConstraints{ - MOI.ScalarAffineFunction{Float64}, - MOI.LessThan{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.LessThan{T}, }(), ) == 1 end - cf2 = - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 2.0, 1.0], v), 0.0) - c2 = MOI.add_constraint(model, cf2, MOI.LessThan(15.0)) + cf2 = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(T[1, 2, 1], v), T(0)) + c2 = MOI.add_constraint(model, cf2, MOI.LessThan(T(15))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, MOI.NumberOfConstraints{ - MOI.ScalarAffineFunction{Float64}, - MOI.LessThan{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.LessThan{T}, }(), ) == 2 end - vc1 = MOI.add_constraint(model, v[1], MOI.Interval(0.0, 5.0)) + vc1 = MOI.add_constraint(model, v[1], MOI.Interval(T(0), T(5))) # We test this after the creation of every `VariableIndex` constraint # to ensure a good coverage of corner cases. @test vc1.value == v[1].value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, - MOI.NumberOfConstraints{MOI.VariableIndex,MOI.Interval{Float64}}(), + MOI.NumberOfConstraints{MOI.VariableIndex,MOI.Interval{T}}(), ) == 1 end - vc2 = MOI.add_constraint(model, v[2], MOI.Interval(0.0, 10.0)) + vc2 = MOI.add_constraint(model, v[2], MOI.Interval(T(0), T(10))) @test vc2.value == v[2].value if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, - MOI.NumberOfConstraints{MOI.VariableIndex,MOI.Interval{Float64}}(), + MOI.NumberOfConstraints{MOI.VariableIndex,MOI.Interval{T}}(), ) == 2 end vc3 = MOI.add_constraint(model, v[2], MOI.Integer()) @@ -2889,13 +2743,11 @@ function test_linear_integer_integration(model::MOI.ModelLike, config::Config) MOI.NumberOfConstraints{MOI.VariableIndex,MOI.ZeroOne}(), ) == 1 end - objf = - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.1, 2.0, 5.0], v), 0.0) - MOI.set( - model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), - objf, + objf = MOI.ScalarAffineFunction( + MOI.ScalarAffineTerm.(T[11//10, 2, 5], v), + T(0), ) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MAX_SENSE if _supports(config, MOI.optimize!) @@ -2905,18 +2757,14 @@ function test_linear_integer_integration(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) in [MOI.FEASIBLE_POINT, MOI.NEARLY_FEASIBLE_POINT] - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 19.4, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [4, 5, 1], - config, - ) - @test isapprox(MOI.get(model, MOI.ConstraintPrimal(), c), 10, config) - @test isapprox(MOI.get(model, MOI.ConstraintPrimal(), c2), 15, config) - @test MOI.get(model, MOI.ObjectiveBound()) >= 19.4 - config.atol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(97 // 5), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[4, 5, 1], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(10), config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c2), T(15), config) + @test MOI.get(model, MOI.ObjectiveBound()) >= T(97 // 5) - config.atol # FIXME the following are currently not implemented in MockOptimizer - # @test MOI.get(model, MOI.RelativeGap()) >= 0.0 - # @test MOI.get(model, MOI.SolveTimeSec()) >= 0.0 + # @test MOI.get(model, MOI.RelativeGap()) >= T(0) + # @test MOI.get(model, MOI.SolveTimeSec()) >= T(0) # @test MOI.get(model, MOI.SimplexIterations()) >= 0 # @test MOI.get(model, MOI.BarrierIterations()) >= 0 # @test MOI.get(model, MOI.NodeCount()) >= 0 @@ -2927,62 +2775,57 @@ end function setup_test( ::typeof(test_linear_integer_integration), model::MOI.Utilities.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 20.0) - MOIU.mock_optimize!(mock, [4, 5, 1]) + MOI.set(mock, MOI.ObjectiveBound(), T(20)) + MOIU.mock_optimize!(mock, T[4, 5, 1]) end, ) return end """ - test_linear_SOS1_integration(model::MOI.ModelLike, config::Config) + test_linear_SOS1_integration(model::MOI.ModelLike, config::Config{T}) where {T} Test Special Ordered Sets of type 1. """ -function test_linear_SOS1_integration(model::MOI.ModelLike, config::Config) +function test_linear_SOS1_integration( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports_incremental_interface(model) @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) - @requires MOI.supports_constraint( - model, - MOI.VectorOfVariables, - MOI.SOS1{Float64}, - ) - @requires MOI.supports_constraint( - model, - MOI.VariableIndex, - MOI.LessThan{Float64}, - ) + @requires MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.SOS1{T}) + @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.LessThan{T}) v = MOI.add_variables(model, 3) @test MOI.get(model, MOI.NumberOfVariables()) == 3 - vc1 = MOI.add_constraint(model, v[1], MOI.LessThan(1.0)) + vc1 = MOI.add_constraint(model, v[1], MOI.LessThan(T(1))) @test vc1.value == v[1].value - vc2 = MOI.add_constraint(model, v[2], MOI.LessThan(1.0)) + vc2 = MOI.add_constraint(model, v[2], MOI.LessThan(T(1))) @test vc2.value == v[2].value - vc3 = MOI.add_constraint(model, v[3], MOI.LessThan(2.0)) + vc3 = MOI.add_constraint(model, v[3], MOI.LessThan(T(2))) @test vc3.value == v[3].value c1 = MOI.add_constraint( model, MOI.VectorOfVariables([v[1], v[2]]), - MOI.SOS1([1.0, 2.0]), + MOI.SOS1(T[1, 2]), ) c2 = MOI.add_constraint( model, MOI.VectorOfVariables([v[1], v[3]]), - MOI.SOS1([1.0, 2.0]), + MOI.SOS1(T[1, 2]), ) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, - MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.SOS1{Float64}}(), + MOI.NumberOfConstraints{MOI.VectorOfVariables,MOI.SOS1{T}}(), ) == 2 end #= @@ -2992,15 +2835,10 @@ function test_linear_SOS1_integration(model::MOI.ModelLike, config::Config) cs_sos = MOI.get(model, MOI.ConstraintSet(), c2) cf_sos = MOI.get(model, MOI.ConstraintFunction(), c2) p = sortperm(cs_sos.weights) - @test isapprox(cs_sos.weights[p], [1.0, 2.0], config) + @test ≈(cs_sos.weights[p], T[1, 2], config) @test cf_sos.variables[p] == v[[1, 3]] - objf = - MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([2.0, 1.0, 1.0], v), 0.0) - MOI.set( - model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), - objf, - ) + objf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(T[2, 1, 1], v), T(0)) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MAX_SENSE if _supports(config, MOI.optimize!) @@ -3009,12 +2847,8 @@ function test_linear_SOS1_integration(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 3, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [0, 1, 2], - config, - ) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(3), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[0, 1, 2], config) end MOI.delete(model, c1) MOI.delete(model, c2) @@ -3023,12 +2857,8 @@ function test_linear_SOS1_integration(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 5, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [1, 1, 2], - config, - ) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(5), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[1, 1, 2], config) end return end @@ -3036,49 +2866,44 @@ end function setup_test( ::typeof(test_linear_SOS1_integration), model::MOI.Utilities.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [0, 1, 2]), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, [1, 1, 2]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[0, 1, 2]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[1, 1, 2]), ) return end """ - test_linear_SOS2_integration(model::MOI.ModelLike, config::Config) + test_linear_SOS2_integration(model::MOI.ModelLike, config::Config{T}) where {T} Test Special Ordered Sets of type 2. """ -function test_linear_SOS2_integration(model::MOI.ModelLike, config::Config) +function test_linear_SOS2_integration( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports_incremental_interface(model) @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) - @requires MOI.supports_constraint( - model, - MOI.VectorOfVariables, - MOI.SOS1{Float64}, - ) - @requires MOI.supports_constraint( - model, - MOI.VectorOfVariables, - MOI.SOS2{Float64}, - ) + @requires MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.SOS1{T}) + @requires MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.SOS2{T}) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) @requires MOI.supports_constraint( model, - MOI.ScalarAffineFunction{Float64}, - MOI.EqualTo{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.EqualTo{T}, ) v = MOI.add_variables(model, 10) @test MOI.get(model, MOI.NumberOfVariables()) == 10 bin_constraints = [] for i in 1:8 - vc = MOI.add_constraint(model, v[i], MOI.Interval(0.0, 2.0)) + vc = MOI.add_constraint(model, v[i], MOI.Interval(T(0), T(2))) @test vc.value == v[i].value push!(bin_constraints, MOI.add_constraint(model, v[i], MOI.ZeroOne())) @test bin_constraints[i].value == v[i].value @@ -3086,29 +2911,26 @@ function test_linear_SOS2_integration(model::MOI.ModelLike, config::Config) MOI.add_constraint( model, MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([1.0, 2.0, 3.0, -1.0], v[[1, 2, 3, 9]]), - 0.0, + MOI.ScalarAffineTerm.(T[1, 2, 3, -1], v[[1, 2, 3, 9]]), + T(0), ), - MOI.EqualTo(0.0), + MOI.EqualTo(T(0)), ) MOI.add_constraint( model, MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.( - [5.0, 4.0, 7.0, 2.0, 1.0, -1.0], - v[[4, 5, 6, 7, 8, 10]], - ), - 0.0, + MOI.ScalarAffineTerm.(T[5, 4, 7, 2, 1, -1], v[[4, 5, 6, 7, 8, 10]]), + T(0), ), - MOI.EqualTo(0.0), + MOI.EqualTo(T(0)), ) MOI.add_constraint( model, MOI.VectorOfVariables(v[[1, 2, 3]]), - MOI.SOS1([1.0, 2.0, 3.0]), + MOI.SOS1(T[1, 2, 3]), ) vv = MOI.VectorOfVariables(v[[4, 5, 6, 7, 8]]) - sos2 = MOI.SOS2([5.0, 4.0, 7.0, 2.0, 1.0]) + sos2 = MOI.SOS2(T[5, 4, 7, 2, 1]) c = MOI.add_constraint(model, vv, sos2) #= To allow for permutations in the sets and variable vectors @@ -3117,17 +2939,13 @@ function test_linear_SOS2_integration(model::MOI.ModelLike, config::Config) cs_sos = MOI.get(model, MOI.ConstraintSet(), c) cf_sos = MOI.get(model, MOI.ConstraintFunction(), c) p = sortperm(cs_sos.weights) - @test isapprox(cs_sos.weights[p], [1.0, 2.0, 4.0, 5.0, 7.0], config) + @test ≈(cs_sos.weights[p], T[1, 2, 4, 5, 7], config) @test cf_sos.variables[p] == v[[8, 7, 5, 4, 6]] objf = MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([1.0, 1.0], [v[9], v[10]]), - 0.0, - ) - MOI.set( - model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), - objf, + MOI.ScalarAffineTerm.(T(1), [v[9], v[10]]), + T(0), ) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MAX_SENSE if _supports(config, MOI.optimize!) @@ -3136,10 +2954,10 @@ function test_linear_SOS2_integration(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 15.0, config) - @test isapprox( + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(15), config) + @test ≈( MOI.get(model, MOI.VariablePrimal(), v), - [0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 3.0, 12.0], + T[0, 0, 1, 1, 0, 1, 0, 0, 3, 12], config, ) end @@ -3151,10 +2969,10 @@ function test_linear_SOS2_integration(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 30.0, config) - @test isapprox( + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(30), config) + @test ≈( MOI.get(model, MOI.VariablePrimal(), v), - [0.0, 0.0, 2.0, 2.0, 0.0, 2.0, 0.0, 0.0, 6.0, 24.0], + T[0, 0, 2, 2, 0, 2, 0, 0, 6, 24], config, ) end @@ -3164,24 +2982,23 @@ end function setup_test( ::typeof(test_linear_SOS2_integration), model::MOI.Utilities.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( - mock, - [0.0, 0.0, 1.0, 1.0, 0.0, 1.0, 0.0, 0.0, 3.0, 12.0], - ), - (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!( - mock, - [0.0, 0.0, 2.0, 2.0, 0.0, 2.0, 0.0, 0.0, 6.0, 24.0], - ), + (mock::MOIU.MockOptimizer) -> + MOIU.mock_optimize!(mock, T[0, 0, 1, 1, 0, 1, 0, 0, 3, 12]), + (mock::MOIU.MockOptimizer) -> + MOIU.mock_optimize!(mock, T[0, 0, 2, 2, 0, 2, 0, 0, 6, 24]), ) return end """ - test_linear_integer_solve_twice(model::MOI.ModelLike, config::Config) + test_linear_integer_solve_twice( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Test solving a model twice on the integer knapsack problem. The problem is: @@ -3192,29 +3009,28 @@ s.t. 0 <= z - 0.5 eᵀ b / 40 <= 0.999 z in {0, 1, 2, ..., 100} ``` """ -function test_linear_integer_solve_twice(model::MOI.ModelLike, config::Config) +function test_linear_integer_solve_twice( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports_incremental_interface(model) @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.Integer) + @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.Interval{T}) @requires MOI.supports_constraint( model, - MOI.VariableIndex, - MOI.Interval{Float64}, - ) - @requires MOI.supports_constraint( - model, - MOI.ScalarAffineFunction{Float64}, - MOI.Interval{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.Interval{T}, ) z = MOI.add_variable(model) vc1 = MOI.add_constraint(model, z, MOI.Integer()) @test vc1.value == z.value - vc2 = MOI.add_constraint(model, z, MOI.Interval(0.0, 100.0)) + vc2 = MOI.add_constraint(model, z, MOI.Interval(T(0), T(100))) @test vc2.value == z.value b = MOI.add_variables(model, 10) for bi in b @@ -3224,20 +3040,23 @@ function test_linear_integer_solve_twice(model::MOI.ModelLike, config::Config) c = MOI.add_constraint( model, MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.(vcat(1.0, fill(-0.5 / 40, 10)), vcat(z, b)), - 0.0, + MOI.ScalarAffineTerm.( + vcat(T(1), fill(T(-1 // 80), 10)), + vcat(z, b), + ), + T(0), ), - MOI.Interval(0.0, 0.999), + MOI.Interval(T(0), T(999 // 1_000)), ) MOI.set( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction( MOI.ScalarAffineTerm.( - vcat(1.0, fill(-0.5 / 40, 3)), + vcat(T(1), fill(T(-1 // 80), 3)), vcat(z, b[1:3]), ), - 0.0, + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -3246,12 +3065,12 @@ function test_linear_integer_solve_twice(model::MOI.ModelLike, config::Config) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 1, config) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(1), config) # test for CPLEX.jl #76 MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 1, config) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(1), config) end return end @@ -3259,19 +3078,22 @@ end function setup_test( ::typeof(test_linear_integer_solve_twice), model::MOI.Utilities.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} # FIXME [1, 0...] is not the correct optimal solution but it passes the test MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> - MOIU.mock_optimize!(mock, [1.0; zeros(10)]), + MOIU.mock_optimize!(mock, [T(1); zeros(T, 10)]), ) return end """ - test_linear_integer_knapsack(model::MOI.ModelLike, config::Config) + test_linear_integer_knapsack( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Test the integer knapsack problem ``` @@ -3280,18 +3102,21 @@ st 2a + 8b + 4c + 2d + 5e <= 10 a, b, c, d, e ∈ binary ``` """ -function test_linear_integer_knapsack(model::MOI.ModelLike, config::Config) +function test_linear_integer_knapsack( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports_incremental_interface(model) @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) @requires MOI.supports_constraint( model, - MOI.ScalarAffineFunction{Float64}, - MOI.LessThan{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.LessThan{T}, ) v = MOI.add_variables(model, 5) @test MOI.get(model, MOI.NumberOfVariables()) == 5 @@ -3308,31 +3133,31 @@ function test_linear_integer_knapsack(model::MOI.ModelLike, config::Config) c = MOI.add_constraint( model, MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([2.0, 8.0, 4.0, 2.0, 5.0], v), - 0.0, + MOI.ScalarAffineTerm.(T[2, 8, 4, 2, 5], v), + T(0), ), - MOI.LessThan(10.0), + MOI.LessThan(T(10)), ) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, MOI.NumberOfConstraints{ - MOI.ScalarAffineFunction{Float64}, - MOI.LessThan{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.LessThan{T}, }(), ) == 1 end MOI.set( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([5.0, 3.0, 2.0, 7.0, 4.0], v), - 0.0, + MOI.ScalarAffineTerm.(T[5, 3, 2, 7, 4], v), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) if MOI.supports(model, MOI.VariablePrimalStart(), MOI.VariableIndex) - MOI.set(model, MOI.VariablePrimalStart(), v, [0.0, 0.0, 0.0, 0.0, 0.0]) + MOI.set(model, MOI.VariablePrimalStart(), v, zeros(T, 5)) end if _supports(config, MOI.optimize!) @test MOI.get(model, MOI.TerminationStatus()) == MOI.OPTIMIZE_NOT_CALLED @@ -3340,10 +3165,10 @@ function test_linear_integer_knapsack(model::MOI.ModelLike, config::Config) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) in [MOI.FEASIBLE_POINT, MOI.NEARLY_FEASIBLE_POINT] - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 16, config) - @test isapprox( + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(16), config) + @test ≈( MOI.get(model, MOI.VariablePrimal(), v), - [1, 0, 0, 1, 1], + T[1, 0, 0, 1, 1], config, ) end @@ -3353,18 +3178,21 @@ end function setup_test( ::typeof(test_linear_integer_knapsack), model::MOI.Utilities.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> - MOIU.mock_optimize!(mock, [1, 0, 0, 1, 1]), + MOIU.mock_optimize!(mock, T[1, 0, 0, 1, 1]), ) return end """ - test_linear_Indicator_integration(model::MOI.ModelLike, config::Config) + test_linear_Indicator_integration( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Test the problem: ``` @@ -3375,27 +3203,26 @@ s.t. x1 + x2 <= 10 z1 + z2 >= 1 ``` """ -function test_linear_Indicator_integration(model::MOI.ModelLike, config::Config) +function test_linear_Indicator_integration( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) + @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.Interval{T}) @requires MOI.supports_constraint( model, - MOI.VariableIndex, - MOI.Interval{Float64}, - ) - @requires MOI.supports_constraint( - model, - MOI.ScalarAffineFunction{Float64}, - MOI.Interval{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.Interval{T}, ) @requires MOI.supports_constraint( model, - MOI.VectorAffineFunction{Float64}, - MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{Float64}}, + MOI.VectorAffineFunction{T}, + MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{T}}, ) x1 = MOI.add_variable(model) x2 = MOI.add_variable(model) @@ -3405,47 +3232,47 @@ function test_linear_Indicator_integration(model::MOI.ModelLike, config::Config) MOI.add_constraint(model, z2, MOI.ZeroOne()) f1 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 0.0], + T[0, 0], ) - iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(8.0)) + iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(8))) MOI.add_constraint(model, f1, iset1) f2 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z2)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(0.2, x1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z2)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1 // 5), x1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 0.0], + T[0, 0], ) - iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(9.0)) + iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(9))) MOI.add_constraint(model, f2, iset2) # Additional regular constraint. MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, x1), MOI.ScalarAffineTerm(1.0, x2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), x1), MOI.ScalarAffineTerm(T(1), x2)], + T(0), ), - MOI.LessThan(10.0), + MOI.LessThan(T(10)), ) # Disjunction z1 ⋁ z2 MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, z1), MOI.ScalarAffineTerm(1.0, z2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), z1), MOI.ScalarAffineTerm(T(1), z2)], + T(0), ), - MOI.GreaterThan(1.0), + MOI.GreaterThan(T(1)), ) MOI.set( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([2.0, 3.0], [x1, x2]), - 0.0, + MOI.ScalarAffineTerm.(T[2, 3], [x1, x2]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -3454,11 +3281,11 @@ function test_linear_Indicator_integration(model::MOI.ModelLike, config::Config) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 28.75, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x1), 1.25, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x2), 8.75, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z1), 0.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z2), 1.0, config) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(115 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x1), T(5 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x2), T(35 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z1), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z2), T(1), config) end return end @@ -3466,18 +3293,21 @@ end function setup_test( ::typeof(test_linear_Indicator_integration), model::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> - MOIU.mock_optimize!(mock, [1.25, 8.75, 0.0, 1.0]), + MOIU.mock_optimize!(mock, T[5//4, 35//4, 0, 1]), ) return end """ - test_linear_Indicator_ON_ONE(model::MOI.ModelLike, config::Config) + test_linear_Indicator_ON_ONE( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Test the problem: ``` @@ -3488,7 +3318,10 @@ s.t. x1 + x2 <= 10 z1 + z2 >= 1 ``` """ -function test_linear_Indicator_ON_ONE(model::MOI.ModelLike, config::Config) +function test_linear_Indicator_ON_ONE( + model::MOI.ModelLike, + config::Config{T}, +) where {T} x1 = MOI.add_variable(model) x2 = MOI.add_variable(model) z1 = MOI.add_variable(model) @@ -3497,48 +3330,48 @@ function test_linear_Indicator_ON_ONE(model::MOI.ModelLike, config::Config) MOI.add_constraint(model, z2, MOI.ZeroOne()) f1 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 0.0], + T[0, 0], ) - iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(8.0)) + iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(8))) MOI.add_constraint(model, f1, iset1) f2 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z2)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(0.2, x1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z2)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1 // 5), x1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 0.0], + T[0, 0], ) - iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(9.0)) + iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(9))) MOI.add_constraint(model, f2, iset2) # additional regular constraint MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, x1), MOI.ScalarAffineTerm(1.0, x2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), x1), MOI.ScalarAffineTerm(T(1), x2)], + T(0), ), - MOI.LessThan(10.0), + MOI.LessThan(T(10)), ) # disjunction z1 ⋁ z2 MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, z1), MOI.ScalarAffineTerm(1.0, z2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), z1), MOI.ScalarAffineTerm(T(1), z2)], + T(0), ), - MOI.GreaterThan(1.0), + MOI.GreaterThan(T(1)), ) # objective penalized on z2 MOI.set( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([2.0, 3.0, -30.0], [x1, x2, z2]), - 0.0, + MOI.ScalarAffineTerm.(T[2, 3, -30], [x1, x2, z2]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -3547,11 +3380,11 @@ function test_linear_Indicator_ON_ONE(model::MOI.ModelLike, config::Config) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 28.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x1), 2.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x2), 8.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z1), 1.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z2), 0.0, config) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(28), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x1), T(2), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x2), T(8), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z1), T(1), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z2), T(0), config) end return end @@ -3559,18 +3392,20 @@ end function setup_test( ::typeof(test_linear_Indicator_ON_ONE), model::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, - (mock::MOIU.MockOptimizer) -> - MOIU.mock_optimize!(mock, [2.0, 8.0, 1.0, 0.0]), + (mock::MOIU.MockOptimizer) -> MOIU.mock_optimize!(mock, T[2, 8, 1, 0]), ) return end """ - test_linear_Indicator_ON_ZERO(model::MOI.ModelLike, config::Config) + test_linear_Indicator_ON_ZERO( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Test the problem: ``` @@ -3581,27 +3416,26 @@ s.t. x1 + x2 <= 10 (1-z1) + z2 >= 1 <=> z2 - z1 >= 0 ``` """ -function test_linear_Indicator_ON_ZERO(model::MOI.ModelLike, config::Config) +function test_linear_Indicator_ON_ZERO( + model::MOI.ModelLike, + config::Config{T}, +) where {T} @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) + @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.Interval{T}) @requires MOI.supports_constraint( model, - MOI.VariableIndex, - MOI.Interval{Float64}, - ) - @requires MOI.supports_constraint( - model, - MOI.ScalarAffineFunction{Float64}, - MOI.Interval{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.Interval{T}, ) @requires MOI.supports_constraint( model, - MOI.VectorAffineFunction{Float64}, - MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{Float64}}, + MOI.VectorAffineFunction{T}, + MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{T}}, ) x1 = MOI.add_variable(model) x2 = MOI.add_variable(model) @@ -3613,47 +3447,47 @@ function test_linear_Indicator_ON_ZERO(model::MOI.ModelLike, config::Config) @test vc2.value == z2.value f1 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 0.0], + T[0, 0], ) - iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.LessThan(8.0)) + iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ZERO}(MOI.LessThan(T(8))) MOI.add_constraint(model, f1, iset1) f2 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z2)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(0.2, x1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z2)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1 // 5), x1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 0.0], + T[0, 0], ) - iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(9.0)) + iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(9))) MOI.add_constraint(model, f2, iset2) # Additional regular constraint. MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, x1), MOI.ScalarAffineTerm(1.0, x2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), x1), MOI.ScalarAffineTerm(T(1), x2)], + T(0), ), - MOI.LessThan(10.0), + MOI.LessThan(T(10)), ) # Disjunction (1-z1) ⋁ z2 MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(-1.0, z1), MOI.ScalarAffineTerm(1.0, z2)], - 0.0, + [MOI.ScalarAffineTerm(T(-1), z1), MOI.ScalarAffineTerm(T(1), z2)], + T(0), ), - MOI.GreaterThan(0.0), + MOI.GreaterThan(T(0)), ) MOI.set( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([2.0, 3.0], [x1, x2]), - 0.0, + MOI.ScalarAffineTerm.(T[2, 3], [x1, x2]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -3662,11 +3496,11 @@ function test_linear_Indicator_ON_ZERO(model::MOI.ModelLike, config::Config) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 28.75, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x1), 1.25, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x2), 8.75, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z1), 1.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z2), 1.0, config) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(115 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x1), T(5 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x2), T(35 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z1), T(1), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z2), T(1), config) end return end @@ -3674,18 +3508,21 @@ end function setup_test( ::typeof(test_linear_Indicator_ON_ZERO), model::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> - MOIU.mock_optimize!(mock, [1.25, 8.75, 1.0, 1.0]), + MOIU.mock_optimize!(mock, T[5//4, 35//4, 1, 1]), ) return end """ - test_linear_Indicator_constant_term(model::MOI.ModelLike, config::Config) + test_linear_Indicator_constant_term( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Test Indicator constraints with a constant term on the left-hand side. The problem is: @@ -3699,28 +3536,24 @@ s.t. x1 + x2 <= 10 """ function test_linear_Indicator_constant_term( model::MOI.ModelLike, - config::Config, -) + config::Config{T}, +) where {T} @requires MOI.supports( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), ) @requires MOI.supports(model, MOI.ObjectiveSense()) @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.ZeroOne) + @requires MOI.supports_constraint(model, MOI.VariableIndex, MOI.Interval{T}) @requires MOI.supports_constraint( model, - MOI.VariableIndex, - MOI.Interval{Float64}, - ) - @requires MOI.supports_constraint( - model, - MOI.ScalarAffineFunction{Float64}, - MOI.Interval{Float64}, + MOI.ScalarAffineFunction{T}, + MOI.Interval{T}, ) @requires MOI.supports_constraint( model, - MOI.VectorAffineFunction{Float64}, - MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{Float64}}, + MOI.VectorAffineFunction{T}, + MOI.Indicator{MOI.ACTIVATE_ON_ONE,MOI.LessThan{T}}, ) x1 = MOI.add_variable(model) x2 = MOI.add_variable(model) @@ -3730,47 +3563,47 @@ function test_linear_Indicator_constant_term( MOI.add_constraint(model, z2, MOI.ZeroOne()) f1 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, -1.0], + T[0, -1], ) - iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(7.0)) + iset1 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(7))) MOI.add_constraint(model, f1, iset1) f2 = MOI.VectorAffineFunction( [ - MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(1.0, z2)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(0.2, x1)), - MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(1.0, x2)), + MOI.VectorAffineTerm(1, MOI.ScalarAffineTerm(T(1), z2)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1 // 5), x1)), + MOI.VectorAffineTerm(2, MOI.ScalarAffineTerm(T(1), x2)), ], - [0.0, 1.0], + T[0, 1], ) - iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(10.0)) + iset2 = MOI.Indicator{MOI.ACTIVATE_ON_ONE}(MOI.LessThan(T(10))) MOI.add_constraint(model, f2, iset2) # Additional regular constraint. MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, x1), MOI.ScalarAffineTerm(1.0, x2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), x1), MOI.ScalarAffineTerm(T(1), x2)], + T(0), ), - MOI.LessThan(10.0), + MOI.LessThan(T(10)), ) # Disjunction z1 ⋁ z2 MOI.add_constraint( model, MOI.ScalarAffineFunction( - [MOI.ScalarAffineTerm(1.0, z1), MOI.ScalarAffineTerm(1.0, z2)], - 0.0, + [MOI.ScalarAffineTerm(T(1), z1), MOI.ScalarAffineTerm(T(1), z2)], + T(0), ), - MOI.GreaterThan(1.0), + MOI.GreaterThan(T(1)), ) MOI.set( model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), + MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), MOI.ScalarAffineFunction( - MOI.ScalarAffineTerm.([2.0, 3.0], [x1, x2]), - 0.0, + MOI.ScalarAffineTerm.(T[2, 3], [x1, x2]), + T(0), ), ) MOI.set(model, MOI.ObjectiveSense(), MOI.MAX_SENSE) @@ -3779,11 +3612,11 @@ function test_linear_Indicator_constant_term( MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 28.75, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x1), 1.25, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), x2), 8.75, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z1), 0.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), z2), 1.0, config) + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(115 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x1), T(5 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), x2), T(35 // 4), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z1), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), z2), T(1), config) end return end @@ -3791,12 +3624,12 @@ end function setup_test( ::typeof(test_linear_Indicator_constant_term), model::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> - MOIU.mock_optimize!(mock, [1.25, 8.75, 0.0, 1.0]), + MOIU.mock_optimize!(mock, T[5//4, 35//4, 0, 1]), ) return end @@ -3858,18 +3691,16 @@ function _test_linear_SemiXXX_integration( ) == 1 end end - vc2 = MOI.add_constraint(model, v[2], MOI.EqualTo(zero(T))) + vc2 = MOI.add_constraint(model, v[2], MOI.EqualTo(T(0))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, MOI.NumberOfConstraints{MOI.VariableIndex,MOI.EqualTo{T}}(), ) == 1 end - cf = MOI.ScalarAffineFunction{T}( - MOI.ScalarAffineTerm{T}.([one(T), -one(T)], v), - zero(T), - ) - c = MOI.add_constraint(model, cf, MOI.GreaterThan(zero(T))) + cf = + MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}.(T[1, -1], v), T(0)) + c = MOI.add_constraint(model, cf, MOI.GreaterThan(T(0))) if _supports(config, MOI.NumberOfConstraints) @test MOI.get( model, @@ -3879,12 +3710,8 @@ function _test_linear_SemiXXX_integration( }(), ) == 1 end - objf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.([1.0, 0.0], v), 0.0) - MOI.set( - model, - MOI.ObjectiveFunction{MOI.ScalarAffineFunction{Float64}}(), - objf, - ) + objf = MOI.ScalarAffineFunction(MOI.ScalarAffineTerm.(T[1, 0], v), T(0)) + MOI.set(model, MOI.ObjectiveFunction{MOI.ScalarAffineFunction{T}}(), objf) MOI.set(model, MOI.ObjectiveSense(), MOI.MIN_SENSE) @test MOI.get(model, MOI.ObjectiveSense()) == MOI.MIN_SENSE if _supports(config, MOI.optimize!) @@ -3894,26 +3721,22 @@ function _test_linear_SemiXXX_integration( @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) in [MOI.FEASIBLE_POINT, MOI.NEARLY_FEASIBLE_POINT] - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 0.0, config) - @test isapprox(MOI.get(model, MOI.VariablePrimal(), v), [0, 0], config) - @test isapprox(MOI.get(model, MOI.ConstraintPrimal(), c), 0.0, config) - @test MOI.get(model, MOI.ObjectiveBound()) <= 0.0 + config.atol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(0), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[0, 0], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(0), config) + @test MOI.get(model, MOI.ObjectiveBound()) <= T(0) + config.atol end # Change y fixed value - MOI.set(model, MOI.ConstraintSet(), vc2, MOI.EqualTo(one(T))) + MOI.set(model, MOI.ConstraintSet(), vc2, MOI.EqualTo(T(1))) if _supports(config, MOI.optimize!) MOI.optimize!(model) @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 2.0, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [2.0, 1.0], - config, - ) - @test isapprox(MOI.get(model, MOI.ConstraintPrimal(), c), 1.0, config) - @test MOI.get(model, MOI.ObjectiveBound()) <= 2.0 + config.atol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(2), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[2, 1], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(1), config) + @test MOI.get(model, MOI.ObjectiveBound()) <= T(2) + config.atol end MOI.set(model, MOI.ConstraintSet(), vc2, MOI.EqualTo(T(2))) if _supports(config, MOI.optimize!) @@ -3921,14 +3744,10 @@ function _test_linear_SemiXXX_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 2.0, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [2.0, 2.0], - config, - ) - @test isapprox(MOI.get(model, MOI.ConstraintPrimal(), c), 0.0, config) - @test MOI.get(model, MOI.ObjectiveBound()) <= 2.0 + config.atol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(2), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[2, 2], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(0), config) + @test MOI.get(model, MOI.ObjectiveBound()) <= T(2) + config.atol end MOI.set(model, MOI.ConstraintSet(), vc2, MOI.EqualTo(T(5 // 2))) if _supports(config, MOI.optimize!) @@ -3937,31 +3756,24 @@ function _test_linear_SemiXXX_integration( @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT if !use_semiinteger - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 2.5, config) - @test isapprox( + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(5 // 2), config) + @test ≈( MOI.get(model, MOI.VariablePrimal(), v), - [2.5, 2.5], + T[5//2, 5//2], config, ) - @test isapprox( - MOI.get(model, MOI.ConstraintPrimal(), c), - 0.0, - config, - ) - @test MOI.get(model, MOI.ObjectiveBound()) <= 2.5 + config.atol + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(0), config) + @test MOI.get(model, MOI.ObjectiveBound()) <= + T(5 // 2) + config.atol else - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 3.0, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [3.0, 2.5], - config, - ) - @test isapprox( + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(3), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[3, 5//2], config) + @test ≈( MOI.get(model, MOI.ConstraintPrimal(), c), - 0.5, + T(1 // 2), config, ) - @test MOI.get(model, MOI.ObjectiveBound()) <= 3.0 + config.atol + @test MOI.get(model, MOI.ObjectiveBound()) <= T(3) + config.atol end end MOI.set(model, MOI.ConstraintSet(), vc2, MOI.EqualTo(T(3))) @@ -3970,14 +3782,10 @@ function _test_linear_SemiXXX_integration( @test MOI.get(model, MOI.TerminationStatus()) == config.optimal_status @test MOI.get(model, MOI.ResultCount()) >= 1 @test MOI.get(model, MOI.PrimalStatus()) == MOI.FEASIBLE_POINT - @test isapprox(MOI.get(model, MOI.ObjectiveValue()), 3.0, config) - @test isapprox( - MOI.get(model, MOI.VariablePrimal(), v), - [3.0, 3.0], - config, - ) - @test isapprox(MOI.get(model, MOI.ConstraintPrimal(), c), 0.0, config) - @test MOI.get(model, MOI.ObjectiveBound()) <= 3.0 + config.atol + @test ≈(MOI.get(model, MOI.ObjectiveValue()), T(3), config) + @test ≈(MOI.get(model, MOI.VariablePrimal(), v), T[3, 3], config) + @test ≈(MOI.get(model, MOI.ConstraintPrimal(), c), T(0), config) + @test MOI.get(model, MOI.ObjectiveBound()) <= T(3) + config.atol end MOI.set(model, MOI.ConstraintSet(), vc2, MOI.EqualTo(T(4))) if _supports(config, MOI.optimize!) @@ -3990,14 +3798,17 @@ function _test_linear_SemiXXX_integration( end """ - test_linear_Semicontinuous_integration(model::MOI.ModelLike, config::Config) + test_linear_Semicontinuous_integration( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Run an integration test on Semicontinuous constraints. """ function test_linear_Semicontinuous_integration( model::MOI.ModelLike, - config::Config, -) + config::Config{T}, +) where {T} _test_linear_SemiXXX_integration(model, config, false) return end @@ -4005,29 +3816,29 @@ end function setup_test( ::typeof(test_linear_Semicontinuous_integration), model::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 0.0) - MOIU.mock_optimize!(mock, [0.0, 0.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(0)) + MOIU.mock_optimize!(mock, T[0, 0]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 2.0) - MOIU.mock_optimize!(mock, [2.0, 1.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(2)) + MOIU.mock_optimize!(mock, T[2, 1]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 2.0) - MOIU.mock_optimize!(mock, [2.0, 2.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(2)) + MOIU.mock_optimize!(mock, T[2, 2]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 2.5) - MOIU.mock_optimize!(mock, [2.5, 2.5]) + MOI.set(mock, MOI.ObjectiveBound(), T(5 // 2)) + MOIU.mock_optimize!(mock, T[5//2, 5//2]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 3.0) - MOIU.mock_optimize!(mock, [3.0, 3.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(3)) + MOIU.mock_optimize!(mock, T[3, 3]) end, (mock::MOIU.MockOptimizer) -> MOI.set(mock, MOI.TerminationStatus(), MOI.INFEASIBLE), @@ -4036,14 +3847,17 @@ function setup_test( end """ - test_linear_Semiinteger_integration(model::MOI.ModelLike, config::Config) + test_linear_Semiinteger_integration( + model::MOI.ModelLike, + config::Config{T}, + ) where {T} Run an integration test on Semiinteger constraints. """ function test_linear_Semiinteger_integration( model::MOI.ModelLike, - config::Config, -) + config::Config{T}, +) where {T} _test_linear_SemiXXX_integration(model, config, true) return end @@ -4051,29 +3865,29 @@ end function setup_test( ::typeof(test_linear_Semiinteger_integration), model::MOIU.MockOptimizer, - ::Config, -) + ::Config{T}, +) where {T} MOIU.set_mock_optimize!( model, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 0.0) - MOIU.mock_optimize!(mock, [0.0, 0.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(0)) + MOIU.mock_optimize!(mock, T[0, 0]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 2.0) - MOIU.mock_optimize!(mock, [2.0, 1.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(2)) + MOIU.mock_optimize!(mock, T[2, 1]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 2.0) - MOIU.mock_optimize!(mock, [2.0, 2.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(2)) + MOIU.mock_optimize!(mock, T[2, 2]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 3.0) - MOIU.mock_optimize!(mock, [3.0, 2.5]) + MOI.set(mock, MOI.ObjectiveBound(), T(3)) + MOIU.mock_optimize!(mock, T[3, 5//2]) end, (mock::MOIU.MockOptimizer) -> begin - MOI.set(mock, MOI.ObjectiveBound(), 3.0) - MOIU.mock_optimize!(mock, [3.0, 3.0]) + MOI.set(mock, MOI.ObjectiveBound(), T(3)) + MOIU.mock_optimize!(mock, T[3, 3]) end, (mock::MOIU.MockOptimizer) -> MOI.set(mock, MOI.TerminationStatus(), MOI.INFEASIBLE), diff --git a/test/Test/Test.jl b/test/Test/Test.jl index c477ce187f..4b37d84b24 100644 --- a/test/Test/Test.jl +++ b/test/Test/Test.jl @@ -48,3 +48,21 @@ MOI.Test.runtests( MOI.Test.Config(); exclude_tests_after = v"0.0.1", ) + +# Non-Float64 tests + +# TODO(odow): fix excluded tests + +MOI.Test.runtests( + MOI.Utilities.MockOptimizer( + MOI.Utilities.UniversalFallback(MOI.Utilities.Model{BigFloat}()), + ), + MOI.Test.Config(BigFloat), + include = ["test_linear_"], + exclude = String[ + "test_linear_VectorAffineFunction_empty_row", + "test_linear_add_constraints", + "test_linear_integer_integration", + "test_linear_integration", + ], +)