-
Notifications
You must be signed in to change notification settings - Fork 94
Add Slack bridges #610
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Add Slack bridges #610
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
dc0c420
add slack bridge file
joaquimg b35e15f
fixes for slack bridge
joaquimg 89be811
Add slack to main file
joaquimg f319839
add to full b opt
joaquimg edc720a
list acceptes function
joaquimg a90ed34
add basic bridge tests
joaquimg 9defdef
add vector slack
joaquimg 861806e
add operate methods for vector functions
joaquimg 8972a33
🎨 Remove whitespace
blegat e17f9db
Fix bridges and add tests
joaquimg 0880c9e
remove debug check
joaquimg dd32f7a
fixes and tests for operate
joaquimg ccf8e13
add tests and small fixes
joaquimg f4c124a
add more function tests
joaquimg fdb8b7d
fix function identation
joaquimg 6accda6
fix powercone
joaquimg 27b95cf
improve comments in slack bridge
joaquimg e25a306
improve comments in conlinear
joaquimg e9af2bd
fix slack bridge tests and add more tests
joaquimg 6895aa1
add more vector function tests and fix operations
joaquimg d6788e4
add number of variables and bridge tests
joaquimg File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,176 @@ | ||
# scalar version | ||
|
||
""" | ||
ScalarSlackBridge{T, F, S} | ||
|
||
The `ScalarSlackBridge` converts a constraint `G`-in-`S` where `G` is a function different | ||
from `SingleVariable` into the constraints `F`-in-`EqualTo{T}` and `SingleVariable`-in-`S`. | ||
`F` is the result of subtracting a `SingleVariable` from `G`. | ||
Tipically `G` is the same as `F`, but that is not mandatory. | ||
""" | ||
struct ScalarSlackBridge{T, F, S} <: AbstractBridge | ||
slack::MOI.VariableIndex | ||
slack_in_set::CI{MOI.SingleVariable, S} | ||
equality::CI{F, MOI.EqualTo{T}} | ||
end | ||
function ScalarSlackBridge{T, F, S}(model, f::MOI.AbstractScalarFunction, s::S) where {T, F, S} | ||
slack = MOI.add_variable(model) | ||
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 | ||
|
||
# start allowing everything (scalar) | ||
MOI.supports_constraint(::Type{ScalarSlackBridge{T, F, S}}, | ||
::Type{<:MOI.AbstractScalarFunction}, | ||
::Type{<:MOI.AbstractScalarSet}) where {T, F, S} = true | ||
# then restrict (careful with ambiguity) | ||
MOI.supports_constraint(::Type{ScalarSlackBridge{T, F, S}}, | ||
::Type{<:MOI.SingleVariable}, | ||
::Type{<:MOI.EqualTo}) where {T, F, S} = false | ||
MOI.supports_constraint(::Type{ScalarSlackBridge{T, F, S}}, | ||
::Type{<:MOI.SingleVariable}, | ||
::Type{<:MOI.AbstractScalarSet}) where {T, F, S} = false | ||
MOI.supports_constraint(::Type{ScalarSlackBridge{T, F, S}}, | ||
::Type{<:MOI.AbstractScalarFunction}, | ||
::Type{<:MOI.EqualTo}) where {T, F, S} = false | ||
function added_constraint_types(::Type{ScalarSlackBridge{T, F, S}}) where {T, F, S} | ||
return [(F, MOI.EqualTo{T}), (MOI.SingleVariable, S)] | ||
end | ||
function concrete_bridge_type(::Type{<:ScalarSlackBridge{T}}, | ||
F::Type{<:MOI.AbstractScalarFunction}, | ||
S::Type{<:MOI.AbstractScalarSet}) where T | ||
F2 = MOIU.promote_operation(-, T, F, MOI.SingleVariable) | ||
return ScalarSlackBridge{T, F2, S} | ||
end | ||
|
||
# Attributes, Bridge acting as an 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{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, 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 | ||
|
||
# Attributes, Bridge acting as a constraint | ||
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal, c::ScalarSlackBridge) | ||
# due to equality, slack should have the same value as original affine function | ||
return MOI.get(model, attr, c.slack_in_set) | ||
end | ||
function MOI.get(model::MOI.ModelLike, a::MOI.ConstraintDual, c::ScalarSlackBridge) | ||
# The dual constraint on slack (since it is free) is | ||
# -dual_slack_in_set + dual_equality = 0 so the two duals are | ||
# equal and we can return either one of them. | ||
return MOI.get(model, a, c.slack_in_set) | ||
end | ||
|
||
# Constraints | ||
function MOI.modify(model::MOI.ModelLike, c::ScalarSlackBridge, change::MOI.AbstractFunctionModification) | ||
MOI.modify(model, c.equality, change) | ||
end | ||
|
||
function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintFunction, | ||
c::ScalarSlackBridge{T, F, S}, func::F) where {T, F, S} | ||
new_func = MOIU.operate(-, T, func, MOI.SingleVariable(c.slack)) | ||
MOI.set(model, MOI.ConstraintFunction(), c.equality, new_func) | ||
end | ||
|
||
function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintSet, c::ScalarSlackBridge{T, F, S}, change::S) where {T, F, S} | ||
MOI.set(model, MOI.ConstraintSet(), c.slack_in_set, change) | ||
end | ||
|
||
# vector version | ||
|
||
""" | ||
VectorSlackBridge{T, F, S} | ||
|
||
The `VectorSlackBridge` converts a constraint `G`-in-`S` where `G` is a function different | ||
from `VectorOfVariables` into the constraints `F`in-`Zeros` and `VectorOfVariables`-in-`S`. | ||
`F` is the result of subtracting a `VectorOfVariables` from `G`. | ||
Tipically `G` is the same as `F`, but that is not mandatory. | ||
""" | ||
struct VectorSlackBridge{T, F, S} <: AbstractBridge | ||
slacks::Vector{MOI.VariableIndex} | ||
slacks_in_set::CI{MOI.VectorOfVariables, S} | ||
equality::CI{F, MOI.Zeros} | ||
end | ||
function VectorSlackBridge{T, F, S}(model, f::MOI.AbstractVectorFunction, s::S) where {T, F, S} | ||
d = MOI.dimension(s) | ||
slacks = MOI.add_variables(model, d) | ||
new_f = MOIU.operate(-, T, f, MOI.VectorAffineFunction{T}(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 | ||
|
||
MOI.supports_constraint(::Type{VectorSlackBridge{T, F, S}}, | ||
::Type{<:MOI.AbstractVectorFunction}, | ||
::Type{<:MOI.AbstractVectorSet}) where {T, F, S} = true | ||
MOI.supports_constraint(::Type{VectorSlackBridge{T, F, S}}, | ||
::Type{<:MOI.VectorOfVariables}, | ||
::Type{<:MOI.Zeros}) where {T, F, S} = false | ||
MOI.supports_constraint(::Type{VectorSlackBridge{T, F, S}}, | ||
::Type{<:MOI.AbstractVectorFunction}, | ||
::Type{<:MOI.Zeros}) where {T, F, S} = false | ||
MOI.supports_constraint(::Type{VectorSlackBridge{T, F, S}}, | ||
::Type{<:MOI.VectorOfVariables}, | ||
::Type{<:MOI.AbstractVectorSet}) where {T, F, S} = false | ||
function added_constraint_types(::Type{VectorSlackBridge{T, F, S}}) where {T, F<:MOI.AbstractVectorFunction, S} | ||
return [(F, MOI.Zeros), (MOI.VectorOfVariables, S)] | ||
blegat marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
function concrete_bridge_type(::Type{<:VectorSlackBridge{T}}, | ||
F::Type{<:MOI.AbstractVectorFunction}, | ||
S::Type{<:MOI.AbstractVectorSet}) where T | ||
F2 = MOIU.promote_operation(-, T, F, MOI.VectorOfVariables) | ||
return VectorSlackBridge{T, F2, S} | ||
end | ||
|
||
# Attributes, Bridge acting as an 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{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, 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 | ||
|
||
# Attributes, Bridge acting as a constraint | ||
function MOI.get(model::MOI.ModelLike, attr::MOI.ConstraintPrimal, c::VectorSlackBridge) | ||
# due to equality, slacks should have the same value as original affine function | ||
return MOI.get(model, attr, c.slacks_in_set) | ||
end | ||
function MOI.get(model::MOI.ModelLike, a::MOI.ConstraintDual, c::VectorSlackBridge) | ||
# The dual constraint on slack (since it is free) is | ||
# -dual_slack_in_set + dual_equality = 0 so the two duals are | ||
# equal and we can return either one of them. | ||
return MOI.get(model, a, c.slacks_in_set) | ||
end | ||
|
||
# Constraints | ||
function MOI.modify(model::MOI.ModelLike, c::VectorSlackBridge, change::MOI.AbstractFunctionModification) | ||
MOI.modify(model, c.equality, change) | ||
end | ||
|
||
function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintFunction, | ||
c::VectorSlackBridge{T, F, S}, func::F) where {T, F, S} | ||
new_func = MOIU.operate(-, T, func, MOI.VectorAffineFunction{T}(MOI.VectorOfVariables(c.slacks))) | ||
MOI.set(model, MOI.ConstraintFunction(), c.equality, new_func) | ||
end | ||
|
||
function MOI.set(model::MOI.ModelLike, ::MOI.ConstraintSet, c::VectorSlackBridge{T,F,S}, change::S) where {T, F, S} | ||
MOI.set(model, MOI.ConstraintSet(), c.slacks_in_set, change) | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.