Skip to content

Commit ecac62f

Browse files
committed
Fix added_constraint_types of Constraint.SlackBridge
1 parent 448617c commit ecac62f

File tree

5 files changed

+140
-55
lines changed

5 files changed

+140
-55
lines changed

src/Bridges/Constraint/slack.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ function MOIB.added_constrained_variable_types(::Type{<:ScalarSlackBridge{T, F,
3939
return [(S,)]
4040
end
4141
function MOIB.added_constraint_types(::Type{ScalarSlackBridge{T, F, S}}) where {T, F, S}
42-
return [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)]
42+
return [(F, MOI.EqualTo{T})]
4343
end
4444
function concrete_bridge_type(::Type{<:ScalarSlackBridge{T}},
4545
F::Type{<:MOI.AbstractScalarFunction},
@@ -142,7 +142,7 @@ function MOIB.added_constrained_variable_types(::Type{<:VectorSlackBridge{T, F,
142142
return [(S,)]
143143
end
144144
function MOIB.added_constraint_types(::Type{VectorSlackBridge{T, F, S}}) where {T, F<:MOI.AbstractVectorFunction, S}
145-
return [(F, MOI.Zeros), (MOI.VectorOfVariables, S)]
145+
return [(F, MOI.Zeros)]
146146
end
147147
function concrete_bridge_type(::Type{<:VectorSlackBridge{T}},
148148
F::Type{<:MOI.AbstractVectorFunction},

src/Bridges/Variable/vectorize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ function MOI.set(model::MOI.ModelLike, attr::MOI.ConstraintSet,
6565
# This would require modifing any constraint which uses the bridged
6666
# variable.
6767
throw(MOI.SetAttributeNotAllowed(attr,
68-
"The variable $(bridge.variable) is bridged by the `VectorizeBridge`."))
68+
"The variable `$(bridge.variable)` is bridged by the `VectorizeBridge`."))
6969
end
7070

7171
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal,

src/Bridges/lazy_bridge_optimizer.jl

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -210,6 +210,44 @@ function add_bridge(b::LazyBridgeOptimizer, BT::Type{<:Constraint.AbstractBridge
210210
update_dist!(b, keys(b.variable_best), keys(b.constraint_best))
211211
end
212212

213+
function _remove_bridge(bridge_types::Vector, BT::Type)
214+
i = findfirst(isequal(BT), bridge_types)
215+
if i === nothing
216+
error("Cannot remove bridge `BT` as it was never added or was already",
217+
" removed.")
218+
else
219+
deleteat!(bridge_types, i)
220+
end
221+
return
222+
end
223+
function _reset_dist(b::LazyBridgeOptimizer)
224+
empty!(b.variable_dist)
225+
empty!(b.variable_best)
226+
empty!(b.constraint_dist)
227+
empty!(b.constraint_best)
228+
end
229+
230+
"""
231+
remove_bridge(b::LazyBridgeOptimizer, BT::Type{<:Variable.AbstractBridge})
232+
233+
Disable the use of the variable bridges of type `BT` by `b`.
234+
"""
235+
function remove_bridge(b::LazyBridgeOptimizer, BT::Type{<:Variable.AbstractBridge})
236+
_remove_bridge(b.variable_bridge_types, BT)
237+
_reset_dist(b)
238+
end
239+
240+
"""
241+
remove_bridge(b::LazyBridgeOptimizer, BT::Type{<:Constraint.AbstractBridge})
242+
243+
Disable the use of the constraint bridges of type `BT` by `b`.
244+
"""
245+
function remove_bridge(b::LazyBridgeOptimizer, BT::Type{<:Constraint.AbstractBridge})
246+
_remove_bridge(b.constraint_bridge_types, BT)
247+
_reset_dist(b)
248+
end
249+
250+
213251
# It only bridges when the constraint is not supporting, hence the name "Lazy"
214252
function is_bridged(b::LazyBridgeOptimizer, S::Type{<:MOI.AbstractSet})
215253
return !MOI.supports_constraint(b.model, variable_function_type(S), S)

test/Bridges/Variable/vectorize.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ end
4444
ci = MOI.ConstraintIndex{MOI.SingleVariable, MOI.LessThan{Float64}}(y.value)
4545
attr = MOI.ConstraintSet()
4646
err = MOI.SetAttributeNotAllowed(attr,
47-
"The variable MathOptInterface.VariableIndex(12345676) is bridged by the `VectorizeBridge`.")
47+
"The variable `MathOptInterface.VariableIndex(12345676)` is bridged by the `VectorizeBridge`.")
4848
@test_throws err MOI.set(bridged_mock, attr, ci, MOI.LessThan(4.0))
4949
end
5050

test/Bridges/lazy_bridge_optimizer.jl

Lines changed: 98 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -29,73 +29,120 @@ MOI.supports_constraint(::SDPAModel{T}, ::Type{MOI.SingleVariable}, ::Type{MOI.G
2929
MOI.supports_constraint(::SDPAModel{T}, ::Type{MOI.SingleVariable}, ::Type{MOI.LessThan{T}}) where {T} = false
3030
MOI.supports_constraint(::SDPAModel{T}, ::Type{MOI.SingleVariable}, ::Type{MOI.EqualTo{T}}) where {T} = false
3131
MOI.supports_constraint(::SDPAModel, ::Type{MOI.VectorOfVariables}, ::Type{MOI.Reals}) = false
32+
MOI.supports(::SDPAModel{T}, ::MOI.ObjectiveFunction{MOI.ScalarQuadraticFunction{T}}) where {T} = false
33+
MOI.supports(::SDPAModel, ::MOI.ObjectiveFunction{MOI.SingleVariable}) = false
3234

3335
@testset "Name test" begin
3436
model = SDPAModel{Float64}()
3537
bridged = MOIB.full_bridge_optimizer(model, Float64)
3638
MOIT.nametest(bridged)
3739
end
38-
3940
@testset "SDPA format with $T" for T in [Float64, Int]
4041
model = SDPAModel{T}()
4142
bridged = MOIB.LazyBridgeOptimizer(model)
42-
@testset "Nonpositives" begin
43-
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Nonpositives)
44-
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Nonpositives)
45-
MOIB.add_bridge(bridged, MOIB.Variable.NonposToNonnegBridge{T})
46-
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Nonpositives)
47-
@test MOIB.bridge_type(bridged, MOI.Nonpositives) == MOIB.Variable.NonposToNonnegBridge{T}
48-
end
49-
@testset "Zeros" begin
50-
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Zeros)
51-
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Zeros)
52-
MOIB.add_bridge(bridged, MOIB.Variable.ZerosBridge{T})
53-
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Zeros)
54-
@test MOIB.bridge_type(bridged, MOI.Zeros) == MOIB.Variable.ZerosBridge{T}
55-
end
56-
@testset "Free" begin
57-
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Reals)
58-
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Reals)
59-
MOIB.add_bridge(bridged, MOIB.Variable.FreeBridge{T})
60-
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Reals)
61-
@test MOIB.bridge_type(bridged, MOI.Reals) == MOIB.Variable.FreeBridge{T}
62-
end
63-
@testset "Vectorize" begin
64-
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.GreaterThan{T})
65-
@test !MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.GreaterThan{T})
66-
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.LessThan{T})
67-
@test !MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.LessThan{T})
68-
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.EqualTo{T})
69-
@test !MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.EqualTo{T})
70-
MOIB.add_bridge(bridged, MOIB.Variable.VectorizeBridge{T})
71-
@test MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.GreaterThan{T})
72-
@test MOIB.bridge_type(bridged, MOI.GreaterThan{T}) == MOIB.Variable.VectorizeBridge{T, MOI.Nonnegatives}
73-
@test MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.LessThan{T})
74-
@test MOIB.bridge_type(bridged, MOI.LessThan{T}) == MOIB.Variable.VectorizeBridge{T, MOI.Nonpositives}
75-
@test MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.EqualTo{T})
76-
@test MOIB.bridge_type(bridged, MOI.EqualTo{T}) == MOIB.Variable.VectorizeBridge{T, MOI.Zeros}
77-
end
78-
@testset "RSOCtoPSD" begin
79-
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
80-
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
81-
MOIB.add_bridge(bridged, MOIB.Variable.RSOCtoPSDBridge{T})
82-
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
83-
MOIB.add_bridge(bridged, MOIB.Constraint.ScalarFunctionizeBridge{T})
84-
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
85-
@test MOIB.bridge_type(bridged, MOI.RotatedSecondOrderCone) == MOIB.Variable.RSOCtoPSDBridge{T}
43+
@testset "Variable" begin
44+
@testset "Nonpositives" begin
45+
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Nonpositives)
46+
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Nonpositives)
47+
MOIB.add_bridge(bridged, MOIB.Variable.NonposToNonnegBridge{T})
48+
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Nonpositives)
49+
@test MOIB.bridge_type(bridged, MOI.Nonpositives) == MOIB.Variable.NonposToNonnegBridge{T}
50+
end
51+
@testset "Zeros" begin
52+
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Zeros)
53+
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Zeros)
54+
MOIB.add_bridge(bridged, MOIB.Variable.ZerosBridge{T})
55+
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Zeros)
56+
@test MOIB.bridge_type(bridged, MOI.Zeros) == MOIB.Variable.ZerosBridge{T}
57+
end
58+
@testset "Free" begin
59+
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.Reals)
60+
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Reals)
61+
MOIB.add_bridge(bridged, MOIB.Variable.FreeBridge{T})
62+
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.Reals)
63+
@test MOIB.bridge_type(bridged, MOI.Reals) == MOIB.Variable.FreeBridge{T}
64+
end
65+
@testset "Vectorize" begin
66+
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.GreaterThan{T})
67+
@test !MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.GreaterThan{T})
68+
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.LessThan{T})
69+
@test !MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.LessThan{T})
70+
@test !MOI.supports_constraint(model, MOI.SingleVariable, MOI.EqualTo{T})
71+
@test !MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.EqualTo{T})
72+
MOIB.add_bridge(bridged, MOIB.Variable.VectorizeBridge{T})
73+
@test MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.GreaterThan{T})
74+
@test MOIB.bridge_type(bridged, MOI.GreaterThan{T}) == MOIB.Variable.VectorizeBridge{T, MOI.Nonnegatives}
75+
@test MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.LessThan{T})
76+
@test MOIB.bridge_type(bridged, MOI.LessThan{T}) == MOIB.Variable.VectorizeBridge{T, MOI.Nonpositives}
77+
@test MOI.supports_constraint(bridged, MOI.SingleVariable, MOI.EqualTo{T})
78+
@test MOIB.bridge_type(bridged, MOI.EqualTo{T}) == MOIB.Variable.VectorizeBridge{T, MOI.Zeros}
79+
end
80+
@testset "RSOCtoPSD" begin
81+
@test !MOI.supports_constraint(model, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
82+
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
83+
MOIB.add_bridge(bridged, MOIB.Variable.RSOCtoPSDBridge{T})
84+
@test !MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
85+
MOIB.add_bridge(bridged, MOIB.Constraint.ScalarFunctionizeBridge{T})
86+
@test MOI.supports_constraint(bridged, MOI.VectorOfVariables, MOI.RotatedSecondOrderCone)
87+
@test MOIB.bridge_type(bridged, MOI.RotatedSecondOrderCone) == MOIB.Variable.RSOCtoPSDBridge{T}
88+
end
89+
@testset "Combining two briges" begin
90+
xy = MOI.add_variables(bridged, 2)
91+
test_delete_bridged_variables(bridged, xy, MOI.Reals, 2, (
92+
(MOI.VectorOfVariables, MOI.Nonnegatives, 0),
93+
(MOI.VectorOfVariables, MOI.Nonpositives, 0)),
94+
used_bridges = 2)
95+
end
8696
end
87-
@testset "Combining two briges" begin
88-
xy = MOI.add_variables(bridged, 2)
89-
test_delete_bridged_variables(bridged, xy, MOI.Reals, 2, (
90-
(MOI.VectorOfVariables, MOI.Nonnegatives, 0),
91-
(MOI.VectorOfVariables, MOI.Nonpositives, 0)),
92-
used_bridges = 2)
97+
@testset "Constraint" begin
98+
@testset "Slack" begin
99+
@test !MOI.supports_constraint(bridged, MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone)
100+
MOIB.add_bridge(bridged, MOIB.Constraint.VectorSlackBridge{T})
101+
@test !MOI.supports_constraint(bridged, MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone)
102+
MOIB.add_bridge(bridged, MOIB.Constraint.ScalarizeBridge{T})
103+
@test MOI.supports_constraint(bridged, MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone)
104+
@test MOIB.bridge_type(bridged, MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone) ==
105+
MOIB.Constraint.VectorSlackBridge{T, MOI.VectorAffineFunction{T}, MOI.RotatedSecondOrderCone}
106+
@test MOI.supports_constraint(bridged, MOI.VectorAffineFunction{T}, MOI.Zeros)
107+
@test MOIB.bridge_type(bridged, MOI.VectorAffineFunction{T}, MOI.Zeros) ==
108+
MOIB.Constraint.ScalarizeBridge{T, MOI.ScalarAffineFunction{T}, MOI.EqualTo{T}}
109+
end
110+
@testset "Vectorize" begin
111+
@test !MOI.supports_constraint(bridged, MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T})
112+
MOIB.add_bridge(bridged, MOIB.Constraint.VectorizeBridge{T})
113+
@test MOI.supports_constraint(bridged, MOI.ScalarAffineFunction{T}, MOI.GreaterThan{T})
114+
@test MOIB.bridge_type(bridged, MOI.ScalarAffineFunction{T},
115+
MOI.GreaterThan{T}) ==
116+
MOIB.Constraint.VectorizeBridge{
117+
T, MOI.VectorAffineFunction{T}, MOI.Nonnegatives,
118+
MOI.ScalarAffineFunction{T}
119+
}
120+
121+
end
122+
@testset "Quadratic" begin
123+
@test !MOI.supports_constraint(bridged, MOI.ScalarQuadraticFunction{T}, MOI.GreaterThan{T})
124+
@test !MOI.supports_constraint(bridged, MOI.ScalarQuadraticFunction{T}, MOI.LessThan{T})
125+
MOIB.add_bridge(bridged, MOIB.Constraint.QuadtoSOCBridge{T})
126+
@test MOI.supports_constraint(bridged, MOI.ScalarQuadraticFunction{T}, MOI.GreaterThan{T})
127+
@test MOIB.bridge_type(bridged, MOI.ScalarQuadraticFunction{T},
128+
MOI.GreaterThan{T}) == MOIB.Constraint.QuadtoSOCBridge{T}
129+
@test MOI.supports_constraint(bridged, MOI.ScalarQuadraticFunction{T}, MOI.LessThan{T})
130+
@test MOIB.bridge_type(bridged, MOI.ScalarQuadraticFunction{T},
131+
MOI.LessThan{T}) == MOIB.Constraint.QuadtoSOCBridge{T}
132+
end
93133
end
94134
end
95135

96136
@testset "Continuous Linear" begin
97137
model = SDPAModel{Float64}()
98138
bridged = MOIB.full_bridge_optimizer(model, Float64)
139+
# For `ScalarAffineFunction`-in-`GreaterThan`,
140+
# `Constraint.ScalarSlackBridge` -> `Variable.VectorizeBridge`
141+
# is equivalent to
142+
# `Constraint.VectorizeBridge` -> `Constraint.VectorSlackBridge`
143+
# however, `Variable.VectorizeBridge` do not support modification of the
144+
# set hence it makes some tests of `contlineartest` fail so we disable it.
145+
MOIB.remove_bridge(bridged, MOIB.Constraint.ScalarSlackBridge{Float64})
99146
exclude = ["partial_start"] # `VariablePrimalStart` not supported.
100147
MOIT.contlineartest(bridged, MOIT.TestConfig(solve=false), exclude)
101148
end

0 commit comments

Comments
 (0)