Skip to content

WIP: VectorAffineBridge #413

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

Closed
wants to merge 4 commits into from
Closed

WIP: VectorAffineBridge #413

wants to merge 4 commits into from

Conversation

odow
Copy link
Member

@odow odow commented Jun 30, 2018

This PR adds a bridge between VectorAffineFunction-in-{Zeros, Nonnegatives, Nonpositives} and multiple ScalarAffineFunction-in-{EqualTo, LessThan, GreaterThan}.

The biggest target for this is LQOI. We should be able to remove a large chunk of code which effectively implements this bridge anyway. I commented out all of the VectorAffineFunction code in LQOI, and then ran the GLPK tests with MOIB.VectorToScalar{Float64}(GLPK.Optimizer()) and everything passed!

  • I'm not sure what the best way to test this is. @blegat?

Just playing around trying to understand the bridge code.

Untested atm.

@blegat is this how it should be?

saf = functions[term.output_index]
push!(saf.terms, term.scalar_term)
end
ci = CI{MOI.ScalarAffineFunction{T}, S}[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

could be preallocated

getscalarset(T, ::Type{MOI.Nonnegatives}) = MOI.GreaterThan{T}


MOI.supportsconstraint(::Type{VectorAffineBridge{T,S}}, ::Type{MOI.VectorAffineFunction{T}}, ::Type{S}) where {T,S<:VectorAffineBridgeSets} = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

S is different here. The first S is the scalar set and the second is the vector set

@blegat
Copy link
Member

blegat commented Jun 30, 2018

Looks good ! We might wonder whether we should add the bridge with or without the type S specified in the LazyBridge. If we decide to add VectorAffineBridge{T} in the lazy bridge optimizer, then it would say that it supports the three sets but when you create it you see which set it is and you create a bridge of concrete type.

end
ci = CI{MOI.ScalarAffineFunction{T}, S}[]
for (func, set) in zip(functions, sets)
push!(ci, MOI.addconstraint!(model, func, set))
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should use MOI.add_constraints! so that solvers can provide an efficient implementation. @joaquimg

@codecov-io
Copy link

codecov-io commented Aug 7, 2018

Codecov Report

Merging #413 into master will decrease coverage by 0.94%.
The diff coverage is 1.92%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #413      +/-   ##
==========================================
- Coverage   95.26%   94.31%   -0.95%     
==========================================
  Files          42       43       +1     
  Lines        4962     5013      +51     
==========================================
+ Hits         4727     4728       +1     
- Misses        235      285      +50
Impacted Files Coverage Δ
src/Bridges/vaftosafbridge.jl 0% <0%> (ø)
src/Bridges/Bridges.jl 100% <100%> (ø) ⬆️
src/Bridges/detbridge.jl 100% <0%> (+1.2%) ⬆️

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update 84efa5f...e88bc1d. Read the comment docs.

sets = [ScalarSet(-constant) for constant in func.constants]
@assert MOI.dimension(set) == length(sets)
functions = [MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}[], zero(T))
for i in 1:MOI.dimension(set)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cosmetic/Subjective: I would indent to start for just past the [

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ha ... if it was up to me, anything other than 4 space indents would be a jailable offense

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

indenting is where coder can express their artistic inner-self :D
More seriously, I was confused when reading the line as I thought it was a block (e.g. like for, begin, if, ...) instead of a line-break.
I usually do 4-spaces for blocks and for line-breaks I align with parentheses, brackets, ...

for term in func.terms
scalar_function = functions[term.output_index]
push!(scalar_function.terms, term.scalar_term)
end
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These lines are equivalent to functions = MOIU.eachscalar(func)[1:MOI.dimension(set)]. The advantage of this is that it could also work with VectorQuadraticFunction without the need to do any change in the bridge

MOI.canget(model, MOI.ConstraintSet(), CI{MOI.ScalarAffineFunction{T}, S})
end
function MOI.get(model::MOI.ModelLike, ::MOI.ConstraintPrimal, bridge::VectorToScalarBridge)
primals = fill(0.0, length(bridge.constraints))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

zeros(T, length(bridge.constraints))

MOI.canget(::MOI.ModelLike, ::MOI.ConstraintFunction, ::Type{<:VectorToScalarBridge}) = true
function MOI.get(model::MOI.ModelLike, ::MOI.ConstraintFunction,
bridge::VectorToScalarBridge{T, S}) where {T, S}
terms = VectorAffineTerm{T}[]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

moivcat can be helpful here. Using moivcat will help adding support for quadratic functions

- `MOI.Nonnegatives` =>`MOI.GreaterThan{T}`
- `MOI.Nonpositives` =>`MOI.LessThan{T}`
"""
struct VectorToScalarBridge{T, S} <: AbstractBridge
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would be nice to have

struct VectorToScalarBridge{T, F, S} <: AbstractBridge
    constriants::Vector{CI{F, S}}
end

where F can also be, e.g. SingleVariable and ScalarQuadraticFunction.
You can leave it for future work as the tools needed are being added in #455

@blegat
Copy link
Member

blegat commented Aug 7, 2018

Looks good ! Just missing a few tests :)

@blegat
Copy link
Member

blegat commented Mar 11, 2019

@odow This PR has been superseeded by #664

@odow odow closed this Mar 12, 2019
@odow odow deleted the odow/vafbridge branch March 12, 2019 14:15
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

Successfully merging this pull request may close these issues.

4 participants