Skip to content

Commit

Permalink
Merge pull request #826 from JuliaOpt/bl/constraint_slack
Browse files Browse the repository at this point in the history
Update Constraint.SlackBridge and add variable bridges in full_bridge_optimizer
  • Loading branch information
blegat authored Aug 9, 2019
2 parents 86335c5 + 7ce2702 commit 3b4479b
Show file tree
Hide file tree
Showing 7 changed files with 224 additions and 62 deletions.
24 changes: 3 additions & 21 deletions src/Bridges/Bridges.jl
Original file line number Diff line number Diff line change
Expand Up @@ -22,28 +22,10 @@ include("lazy_bridge_optimizer.jl")
Returns a `LazyBridgeOptimizer` bridging `model` for every bridge defined in
this package and for the coefficient type `T`.
"""
function full_bridge_optimizer(model::MOI.ModelLike, ::Type{T}) where T
function full_bridge_optimizer(model::MOI.ModelLike, T::Type)
bridged_model = LazyBridgeOptimizer(model)
add_bridge(bridged_model, Constraint.GreaterToLessBridge{T})
add_bridge(bridged_model, Constraint.LessToGreaterBridge{T})
add_bridge(bridged_model, Constraint.NonnegToNonposBridge{T})
add_bridge(bridged_model, Constraint.NonposToNonnegBridge{T})
add_bridge(bridged_model, Constraint.ScalarizeBridge{T})
add_bridge(bridged_model, Constraint.VectorizeBridge{T})
add_bridge(bridged_model, Constraint.ScalarSlackBridge{T})
add_bridge(bridged_model, Constraint.VectorSlackBridge{T})
add_bridge(bridged_model, Constraint.ScalarFunctionizeBridge{T})
add_bridge(bridged_model, Constraint.VectorFunctionizeBridge{T})
add_bridge(bridged_model, Constraint.SplitIntervalBridge{T})
add_bridge(bridged_model, Constraint.QuadtoSOCBridge{T})
add_bridge(bridged_model, Constraint.GeoMeanBridge{T})
add_bridge(bridged_model, Constraint.SquareBridge{T})
add_bridge(bridged_model, Constraint.LogDetBridge{T})
add_bridge(bridged_model, Constraint.RootDetBridge{T})
add_bridge(bridged_model, Constraint.RSOCBridge{T})
add_bridge(bridged_model, Constraint.RSOCtoPSDBridge{T})
add_bridge(bridged_model, Constraint.SOCtoPSDBridge{T})
add_bridge(bridged_model, Constraint.IndicatorActiveOnFalseBridge{T})
Variable.add_all_bridges(bridged_model, T)
Constraint.add_all_bridges(bridged_model, T)
return bridged_model
end

Expand Down
30 changes: 30 additions & 0 deletions src/Bridges/Constraint/Constraint.jl
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,34 @@ const SOCtoPSD{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{SOCtoPSDBridge{T},
const RSOCtoPSD{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{RSOCtoPSDBridge{T}, OT}
include("indicator.jl")

"""
add_all_bridges(bridged_model, T::Type)
Add all bridges defined in the `Bridges.Constraint` submodule to
`bridged_model`. The coefficient type used is `T`.
"""
function add_all_bridges(bridged_model, T::Type)
MOIB.add_bridge(bridged_model, GreaterToLessBridge{T})
MOIB.add_bridge(bridged_model, LessToGreaterBridge{T})
MOIB.add_bridge(bridged_model, NonnegToNonposBridge{T})
MOIB.add_bridge(bridged_model, NonposToNonnegBridge{T})
MOIB.add_bridge(bridged_model, ScalarizeBridge{T})
MOIB.add_bridge(bridged_model, VectorizeBridge{T})
MOIB.add_bridge(bridged_model, ScalarSlackBridge{T})
MOIB.add_bridge(bridged_model, VectorSlackBridge{T})
MOIB.add_bridge(bridged_model, ScalarFunctionizeBridge{T})
MOIB.add_bridge(bridged_model, VectorFunctionizeBridge{T})
MOIB.add_bridge(bridged_model, SplitIntervalBridge{T})
MOIB.add_bridge(bridged_model, QuadtoSOCBridge{T})
MOIB.add_bridge(bridged_model, GeoMeanBridge{T})
MOIB.add_bridge(bridged_model, SquareBridge{T})
MOIB.add_bridge(bridged_model, LogDetBridge{T})
MOIB.add_bridge(bridged_model, RootDetBridge{T})
MOIB.add_bridge(bridged_model, RSOCBridge{T})
MOIB.add_bridge(bridged_model, RSOCtoPSDBridge{T})
MOIB.add_bridge(bridged_model, SOCtoPSDBridge{T})
MOIB.add_bridge(bridged_model, IndicatorActiveOnFalseBridge{T})
return
end

end
34 changes: 18 additions & 16 deletions src/Bridges/Constraint/slack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,8 @@ struct ScalarSlackBridge{T, F, S} <: AbstractBridge
end
function bridge_constraint(::Type{ScalarSlackBridge{T, F, S}}, model,
f::MOI.AbstractScalarFunction, s::S) where {T, F, S}
slack = MOI.add_variable(model)
slack, slack_in_set = MOI.add_constrained_variable(model, s)
new_f = MOIU.operate(-, T, f, MOI.SingleVariable(slack))
slack_in_set = MOI.add_constraint(model, MOI.SingleVariable(slack), s)
equality = MOI.add_constraint(model, new_f, MOI.EqualTo(0.0))
return ScalarSlackBridge{T, F, S}(slack, slack_in_set, equality)
end
Expand All @@ -36,9 +35,11 @@ MOI.supports_constraint(::Type{ScalarSlackBridge{T}},
MOI.supports_constraint(::Type{ScalarSlackBridge{T}},
::Type{<:MOI.AbstractScalarFunction},
::Type{<:MOI.EqualTo}) where {T} = false
MOIB.added_constrained_variable_types(::Type{<:ScalarSlackBridge}) = Tuple{DataType}[]
function MOIB.added_constrained_variable_types(::Type{<:ScalarSlackBridge{T, F, S}}) where {T, F, S}
return [(S,)]
end
function MOIB.added_constraint_types(::Type{ScalarSlackBridge{T, F, S}}) where {T, F, S}
return [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)]
return [(F, MOI.EqualTo{T})]
end
function concrete_bridge_type(::Type{<:ScalarSlackBridge{T}},
F::Type{<:MOI.AbstractScalarFunction},
Expand All @@ -48,16 +49,16 @@ function concrete_bridge_type(::Type{<:ScalarSlackBridge{T}},
end

# Attributes, Bridge acting as a model
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.NumberOfVariables) where {T, F, S} = 1
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{F, MOI.EqualTo{T}}) where {T, F, S} = 1
MOI.get(b::ScalarSlackBridge, ::MOI.NumberOfVariables) = 1
MOI.get(b::ScalarSlackBridge, ::MOI.ListOfVariableIndices) = [b.slack]
MOI.get(b::ScalarSlackBridge{T, F}, ::MOI.NumberOfConstraints{F, MOI.EqualTo{T}}) where {T, F} = 1
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{MOI.SingleVariable, S}) where {T, F, S} = 1
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{F, MOI.EqualTo{T}}) where {T, F, S} = [b.equality]
MOI.get(b::ScalarSlackBridge{T, F}, ::MOI.ListOfConstraintIndices{F, MOI.EqualTo{T}}) where {T, F} = [b.equality]
MOI.get(b::ScalarSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{MOI.SingleVariable, S}) where {T, F, S} = [b.slack_in_set]

# Indices
function MOI.delete(model::MOI.ModelLike, c::ScalarSlackBridge)
MOI.delete(model, c.equality)
MOI.delete(model, c.slack_in_set)
MOI.delete(model, c.slack)
return
end
Expand Down Expand Up @@ -119,9 +120,8 @@ end
function bridge_constraint(::Type{VectorSlackBridge{T, F, S}}, model,
f::MOI.AbstractVectorFunction, s::S) where {T, F, S}
d = MOI.dimension(s)
slacks = MOI.add_variables(model, d)
slacks, slacks_in_set = MOI.add_constrained_variables(model, s)
new_f = MOIU.operate(-, T, f, MOI.VectorOfVariables(slacks))
slacks_in_set = MOI.add_constraint(model, MOI.VectorOfVariables(slacks), s)
equality = MOI.add_constraint(model, new_f, MOI.Zeros(d))
return VectorSlackBridge{T, F, S}(slacks, slacks_in_set, equality)
end
Expand All @@ -138,9 +138,11 @@ MOI.supports_constraint(::Type{VectorSlackBridge{T}},
MOI.supports_constraint(::Type{VectorSlackBridge{T}},
::Type{<:MOI.VectorOfVariables},
::Type{<:MOI.AbstractVectorSet}) where {T} = false
MOIB.added_constrained_variable_types(::Type{<:VectorSlackBridge}) = Tuple{DataType}[]
function MOIB.added_constrained_variable_types(::Type{<:VectorSlackBridge{T, F, S}}) where {T, F, S}
return [(S,)]
end
function MOIB.added_constraint_types(::Type{VectorSlackBridge{T, F, S}}) where {T, F<:MOI.AbstractVectorFunction, S}
return [(F, MOI.Zeros), (MOI.VectorOfVariables, S)]
return [(F, MOI.Zeros)]
end
function concrete_bridge_type(::Type{<:VectorSlackBridge{T}},
F::Type{<:MOI.AbstractVectorFunction},
Expand All @@ -150,16 +152,16 @@ function concrete_bridge_type(::Type{<:VectorSlackBridge{T}},
end

# Attributes, Bridge acting as a model
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.NumberOfVariables) where {T, F, S} = length(b.slacks)
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{F, MOI.Zeros}) where {T, F, S} = 1
MOI.get(b::VectorSlackBridge, ::MOI.NumberOfVariables) = length(b.slacks)
MOI.get(b::VectorSlackBridge, ::MOI.ListOfVariableIndices) = b.slacks
MOI.get(b::VectorSlackBridge{T, F}, ::MOI.NumberOfConstraints{F, MOI.Zeros}) where {T, F} = 1
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.NumberOfConstraints{MOI.VectorOfVariables, S}) where {T, F, S} = 1
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{F, MOI.Zeros}) where {T, F, S} = [b.equality]
MOI.get(b::VectorSlackBridge{T, F}, ::MOI.ListOfConstraintIndices{F, MOI.Zeros}) where {T, F} = [b.equality]
MOI.get(b::VectorSlackBridge{T, F, S}, ::MOI.ListOfConstraintIndices{MOI.VectorOfVariables, S}) where {T, F, S} = [b.slacks_in_set]

# Indices
function MOI.delete(model::MOI.ModelLike, c::VectorSlackBridge)
MOI.delete(model, c.equality)
MOI.delete(model, c.slacks_in_set)
MOI.delete(model, c.slacks)
return
end
Expand Down
15 changes: 15 additions & 0 deletions src/Bridges/Variable/Variable.jl
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,19 @@ const Vectorize{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{VectorizeBridge{T}
include("rsoc_to_psd.jl")
const RSOCtoPSD{T, OT<:MOI.ModelLike} = SingleBridgeOptimizer{RSOCtoPSDBridge{T}, OT}

"""
add_all_bridges(bridged_model, T::Type)
Add all bridges defined in the `Bridges.Variable` submodule to `bridged_model`.
The coefficient type used is `T`.
"""
function add_all_bridges(bridged_model, T::Type)
MOIB.add_bridge(bridged_model, ZerosBridge{T})
MOIB.add_bridge(bridged_model, FreeBridge{T})
MOIB.add_bridge(bridged_model, NonposToNonnegBridge{T})
MOIB.add_bridge(bridged_model, VectorizeBridge{T})
MOIB.add_bridge(bridged_model, RSOCtoPSDBridge{T})
return
end

end
4 changes: 2 additions & 2 deletions test/Bridges/Constraint/slack.jl
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ config = MOIT.TestConfig()

for T in [Int, Float64], S in [MOI.GreaterThan{T}, MOI.GreaterThan{T}]
for F in [MOI.ScalarAffineFunction{T}, MOI.ScalarQuadraticFunction{T}]
@test MOIB.added_constraint_types(MOIB.Constraint.ScalarSlackBridge{T, F, S}) == [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)]
@test MOIB.added_constraint_types(MOIB.Constraint.ScalarSlackBridge{T, F, S}) == [(F, MOI.EqualTo{T})]
end
end
end
Expand Down Expand Up @@ -146,7 +146,7 @@ end

for T in [Int, Float64], S in [MOI.Nonnegatives, MOI.Nonpositives]
for F in [MOI.VectorAffineFunction{T}, MOI.VectorQuadraticFunction{T}]
@test MOIB.added_constraint_types(MOIB.Constraint.VectorSlackBridge{T, F, S}) == [(F, MOI.Zeros), (MOI.VectorOfVariables, S)]
@test MOIB.added_constraint_types(MOIB.Constraint.VectorSlackBridge{T, F, S}) == [(F, MOI.Zeros)]
end
end
end
Loading

0 comments on commit 3b4479b

Please sign in to comment.