Skip to content

Commit 3b4479b

Browse files
authored
Merge pull request #826 from JuliaOpt/bl/constraint_slack
Update Constraint.SlackBridge and add variable bridges in full_bridge_optimizer
2 parents 86335c5 + 7ce2702 commit 3b4479b

File tree

7 files changed

+224
-62
lines changed

7 files changed

+224
-62
lines changed

src/Bridges/Bridges.jl

Lines changed: 3 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -22,28 +22,10 @@ include("lazy_bridge_optimizer.jl")
2222
Returns a `LazyBridgeOptimizer` bridging `model` for every bridge defined in
2323
this package and for the coefficient type `T`.
2424
"""
25-
function full_bridge_optimizer(model::MOI.ModelLike, ::Type{T}) where T
25+
function full_bridge_optimizer(model::MOI.ModelLike, T::Type)
2626
bridged_model = LazyBridgeOptimizer(model)
27-
add_bridge(bridged_model, Constraint.GreaterToLessBridge{T})
28-
add_bridge(bridged_model, Constraint.LessToGreaterBridge{T})
29-
add_bridge(bridged_model, Constraint.NonnegToNonposBridge{T})
30-
add_bridge(bridged_model, Constraint.NonposToNonnegBridge{T})
31-
add_bridge(bridged_model, Constraint.ScalarizeBridge{T})
32-
add_bridge(bridged_model, Constraint.VectorizeBridge{T})
33-
add_bridge(bridged_model, Constraint.ScalarSlackBridge{T})
34-
add_bridge(bridged_model, Constraint.VectorSlackBridge{T})
35-
add_bridge(bridged_model, Constraint.ScalarFunctionizeBridge{T})
36-
add_bridge(bridged_model, Constraint.VectorFunctionizeBridge{T})
37-
add_bridge(bridged_model, Constraint.SplitIntervalBridge{T})
38-
add_bridge(bridged_model, Constraint.QuadtoSOCBridge{T})
39-
add_bridge(bridged_model, Constraint.GeoMeanBridge{T})
40-
add_bridge(bridged_model, Constraint.SquareBridge{T})
41-
add_bridge(bridged_model, Constraint.LogDetBridge{T})
42-
add_bridge(bridged_model, Constraint.RootDetBridge{T})
43-
add_bridge(bridged_model, Constraint.RSOCBridge{T})
44-
add_bridge(bridged_model, Constraint.RSOCtoPSDBridge{T})
45-
add_bridge(bridged_model, Constraint.SOCtoPSDBridge{T})
46-
add_bridge(bridged_model, Constraint.IndicatorActiveOnFalseBridge{T})
27+
Variable.add_all_bridges(bridged_model, T)
28+
Constraint.add_all_bridges(bridged_model, T)
4729
return bridged_model
4830
end
4931

src/Bridges/Constraint/Constraint.jl

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,4 +50,34 @@ const SOCtoPSD{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{SOCtoPSDBridge{T},
5050
const RSOCtoPSD{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{RSOCtoPSDBridge{T}, OT}
5151
include("indicator.jl")
5252

53+
"""
54+
add_all_bridges(bridged_model, T::Type)
55+
56+
Add all bridges defined in the `Bridges.Constraint` submodule to
57+
`bridged_model`. The coefficient type used is `T`.
58+
"""
59+
function add_all_bridges(bridged_model, T::Type)
60+
MOIB.add_bridge(bridged_model, GreaterToLessBridge{T})
61+
MOIB.add_bridge(bridged_model, LessToGreaterBridge{T})
62+
MOIB.add_bridge(bridged_model, NonnegToNonposBridge{T})
63+
MOIB.add_bridge(bridged_model, NonposToNonnegBridge{T})
64+
MOIB.add_bridge(bridged_model, ScalarizeBridge{T})
65+
MOIB.add_bridge(bridged_model, VectorizeBridge{T})
66+
MOIB.add_bridge(bridged_model, ScalarSlackBridge{T})
67+
MOIB.add_bridge(bridged_model, VectorSlackBridge{T})
68+
MOIB.add_bridge(bridged_model, ScalarFunctionizeBridge{T})
69+
MOIB.add_bridge(bridged_model, VectorFunctionizeBridge{T})
70+
MOIB.add_bridge(bridged_model, SplitIntervalBridge{T})
71+
MOIB.add_bridge(bridged_model, QuadtoSOCBridge{T})
72+
MOIB.add_bridge(bridged_model, GeoMeanBridge{T})
73+
MOIB.add_bridge(bridged_model, SquareBridge{T})
74+
MOIB.add_bridge(bridged_model, LogDetBridge{T})
75+
MOIB.add_bridge(bridged_model, RootDetBridge{T})
76+
MOIB.add_bridge(bridged_model, RSOCBridge{T})
77+
MOIB.add_bridge(bridged_model, RSOCtoPSDBridge{T})
78+
MOIB.add_bridge(bridged_model, SOCtoPSDBridge{T})
79+
MOIB.add_bridge(bridged_model, IndicatorActiveOnFalseBridge{T})
80+
return
81+
end
82+
5383
end

src/Bridges/Constraint/slack.jl

Lines changed: 18 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,8 @@ struct ScalarSlackBridge{T, F, S} <: AbstractBridge
1515
end
1616
function bridge_constraint(::Type{ScalarSlackBridge{T, F, S}}, model,
1717
f::MOI.AbstractScalarFunction, s::S) where {T, F, S}
18-
slack = MOI.add_variable(model)
18+
slack, slack_in_set = MOI.add_constrained_variable(model, s)
1919
new_f = MOIU.operate(-, T, f, MOI.SingleVariable(slack))
20-
slack_in_set = MOI.add_constraint(model, MOI.SingleVariable(slack), s)
2120
equality = MOI.add_constraint(model, new_f, MOI.EqualTo(0.0))
2221
return ScalarSlackBridge{T, F, S}(slack, slack_in_set, equality)
2322
end
@@ -36,9 +35,11 @@ MOI.supports_constraint(::Type{ScalarSlackBridge{T}},
3635
MOI.supports_constraint(::Type{ScalarSlackBridge{T}},
3736
::Type{<:MOI.AbstractScalarFunction},
3837
::Type{<:MOI.EqualTo}) where {T} = false
39-
MOIB.added_constrained_variable_types(::Type{<:ScalarSlackBridge}) = Tuple{DataType}[]
38+
function MOIB.added_constrained_variable_types(::Type{<:ScalarSlackBridge{T, F, S}}) where {T, F, S}
39+
return [(S,)]
40+
end
4041
function MOIB.added_constraint_types(::Type{ScalarSlackBridge{T, F, S}}) where {T, F, S}
41-
return [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)]
42+
return [(F, MOI.EqualTo{T})]
4243
end
4344
function concrete_bridge_type(::Type{<:ScalarSlackBridge{T}},
4445
F::Type{<:MOI.AbstractScalarFunction},
@@ -48,16 +49,16 @@ function concrete_bridge_type(::Type{<:ScalarSlackBridge{T}},
4849
end
4950

5051
# Attributes, Bridge acting as a model
51-
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.NumberOfVariables) where {T, F, S} = 1
52-
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{F, MOI.EqualTo{T}}) where {T, F, S} = 1
52+
MOI.get(b::ScalarSlackBridge, ::MOI.NumberOfVariables) = 1
53+
MOI.get(b::ScalarSlackBridge, ::MOI.ListOfVariableIndices) = [b.slack]
54+
MOI.get(b::ScalarSlackBridge{T, F}, ::MOI.NumberOfConstraints{F, MOI.EqualTo{T}}) where {T, F} = 1
5355
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{MOI.SingleVariable, S}) where {T, F, S} = 1
54-
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{F, MOI.EqualTo{T}}) where {T, F, S} = [b.equality]
56+
MOI.get(b::ScalarSlackBridge{T, F}, ::MOI.ListOfConstraintIndices{F, MOI.EqualTo{T}}) where {T, F} = [b.equality]
5557
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{MOI.SingleVariable, S}) where {T, F, S} = [b.slack_in_set]
5658

5759
# Indices
5860
function MOI.delete(model::MOI.ModelLike, c::ScalarSlackBridge)
5961
MOI.delete(model, c.equality)
60-
MOI.delete(model, c.slack_in_set)
6162
MOI.delete(model, c.slack)
6263
return
6364
end
@@ -119,9 +120,8 @@ end
119120
function bridge_constraint(::Type{VectorSlackBridge{T, F, S}}, model,
120121
f::MOI.AbstractVectorFunction, s::S) where {T, F, S}
121122
d = MOI.dimension(s)
122-
slacks = MOI.add_variables(model, d)
123+
slacks, slacks_in_set = MOI.add_constrained_variables(model, s)
123124
new_f = MOIU.operate(-, T, f, MOI.VectorOfVariables(slacks))
124-
slacks_in_set = MOI.add_constraint(model, MOI.VectorOfVariables(slacks), s)
125125
equality = MOI.add_constraint(model, new_f, MOI.Zeros(d))
126126
return VectorSlackBridge{T, F, S}(slacks, slacks_in_set, equality)
127127
end
@@ -138,9 +138,11 @@ MOI.supports_constraint(::Type{VectorSlackBridge{T}},
138138
MOI.supports_constraint(::Type{VectorSlackBridge{T}},
139139
::Type{<:MOI.VectorOfVariables},
140140
::Type{<:MOI.AbstractVectorSet}) where {T} = false
141-
MOIB.added_constrained_variable_types(::Type{<:VectorSlackBridge}) = Tuple{DataType}[]
141+
function MOIB.added_constrained_variable_types(::Type{<:VectorSlackBridge{T, F, S}}) where {T, F, S}
142+
return [(S,)]
143+
end
142144
function MOIB.added_constraint_types(::Type{VectorSlackBridge{T, F, S}}) where {T, F<:MOI.AbstractVectorFunction, S}
143-
return [(F, MOI.Zeros), (MOI.VectorOfVariables, S)]
145+
return [(F, MOI.Zeros)]
144146
end
145147
function concrete_bridge_type(::Type{<:VectorSlackBridge{T}},
146148
F::Type{<:MOI.AbstractVectorFunction},
@@ -150,16 +152,16 @@ function concrete_bridge_type(::Type{<:VectorSlackBridge{T}},
150152
end
151153

152154
# Attributes, Bridge acting as a model
153-
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.NumberOfVariables) where {T, F, S} = length(b.slacks)
154-
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{F, MOI.Zeros}) where {T, F, S} = 1
155+
MOI.get(b::VectorSlackBridge, ::MOI.NumberOfVariables) = length(b.slacks)
156+
MOI.get(b::VectorSlackBridge, ::MOI.ListOfVariableIndices) = b.slacks
157+
MOI.get(b::VectorSlackBridge{T, F}, ::MOI.NumberOfConstraints{F, MOI.Zeros}) where {T, F} = 1
155158
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{MOI.VectorOfVariables, S}) where {T, F, S} = 1
156-
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{F, MOI.Zeros}) where {T, F, S} = [b.equality]
159+
MOI.get(b::VectorSlackBridge{T, F}, ::MOI.ListOfConstraintIndices{F, MOI.Zeros}) where {T, F} = [b.equality]
157160
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{MOI.VectorOfVariables, S}) where {T, F, S} = [b.slacks_in_set]
158161

159162
# Indices
160163
function MOI.delete(model::MOI.ModelLike, c::VectorSlackBridge)
161164
MOI.delete(model, c.equality)
162-
MOI.delete(model, c.slacks_in_set)
163165
MOI.delete(model, c.slacks)
164166
return
165167
end

src/Bridges/Variable/Variable.jl

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,19 @@ const Vectorize{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{VectorizeBridge{T}
2626
include("rsoc_to_psd.jl")
2727
const RSOCtoPSD{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{RSOCtoPSDBridge{T}, OT}
2828

29+
"""
30+
add_all_bridges(bridged_model, T::Type)
31+
32+
Add all bridges defined in the `Bridges.Variable` submodule to `bridged_model`.
33+
The coefficient type used is `T`.
34+
"""
35+
function add_all_bridges(bridged_model, T::Type)
36+
MOIB.add_bridge(bridged_model, ZerosBridge{T})
37+
MOIB.add_bridge(bridged_model, FreeBridge{T})
38+
MOIB.add_bridge(bridged_model, NonposToNonnegBridge{T})
39+
MOIB.add_bridge(bridged_model, VectorizeBridge{T})
40+
MOIB.add_bridge(bridged_model, RSOCtoPSDBridge{T})
41+
return
42+
end
43+
2944
end

test/Bridges/Constraint/slack.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ config = MOIT.TestConfig()
7878

7979
for T in [Int, Float64], S in [MOI.GreaterThan{T}, MOI.GreaterThan{T}]
8080
for F in [MOI.ScalarAffineFunction{T}, MOI.ScalarQuadraticFunction{T}]
81-
@test MOIB.added_constraint_types(MOIB.Constraint.ScalarSlackBridge{T, F, S}) == [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)]
81+
@test MOIB.added_constraint_types(MOIB.Constraint.ScalarSlackBridge{T, F, S}) == [(F, MOI.EqualTo{T})]
8282
end
8383
end
8484
end
@@ -146,7 +146,7 @@ end
146146

147147
for T in [Int, Float64], S in [MOI.Nonnegatives, MOI.Nonpositives]
148148
for F in [MOI.VectorAffineFunction{T}, MOI.VectorQuadraticFunction{T}]
149-
@test MOIB.added_constraint_types(MOIB.Constraint.VectorSlackBridge{T, F, S}) == [(F, MOI.Zeros), (MOI.VectorOfVariables, S)]
149+
@test MOIB.added_constraint_types(MOIB.Constraint.VectorSlackBridge{T, F, S}) == [(F, MOI.Zeros)]
150150
end
151151
end
152152
end

0 commit comments

Comments
 (0)