jump-dev / Pajarito.jl

A solver for mixed-integer convex optimization
Mozilla Public License 2.0
129 stars 22 forks source link

Hypatia supports cone constraint but Pajarito does not? #444

Closed dhendryc closed 1 year ago

dhendryc commented 1 year ago

Hi all,

I am trying to solve following problem with Pajarito

Min Tr( (A^T diag(x) A) ^{-1}) s.t sum(x) == s 0 <= x <= u x is an integer vector

For the SDP formulation I used the suggestion here: https://discourse.julialang.org/t/how-to-optimize-trace-of-matrix-inverse-with-jump-or-convex/94167/2 .

You can find the sample code in the attachments. issue_pajarito.txt

Solving the continuous problem with Hypatia works without problems. However, if I try to solve the integer problem with Pajarito, I get the following error:

ERROR: LoadError: Constraints of type MathOptInterface.VectorAffineFunction{Float64}-in-EpiPerSepSpectralCone{Float64} are not supported by the solver.

If you expected the solver to support your problem, you may have an error in your formulation. Otherwise, consider using a different solver.

The list of available solvers, along with the problem types they support, is available at https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:35
 [2] _moi_add_constraint(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{Pajarito.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, f::MathOptInterface.VectorAffineFunction{Float64}, s::EpiPerSepSpectralCone{Float64})
   @ JuMP ~/.julia/packages/JuMP/9CBpS/src/constraints.jl:645
 [3] add_constraint(model::Model, con::VectorConstraint{AffExpr, EpiPerSepSpectralCone{Float64}, VectorShape}, name::String)
   @ JuMP ~/.julia/packages/JuMP/9CBpS/src/constraints.jl:671
 [4] macro expansion
   @ ~/.julia/packages/JuMP/9CBpS/src/macros.jl:833 [inlined]
 [5] top-level scope
   @ ~/Dokumente/MasterThesis/optDesign/pajarito_issue.jl:59

Which I find curious since Hypatia can definitely deal with this type of constraint.

Am I missing some restrictions Pajarito places on Hypatia? Or is this bug?

Thank you very much for your support!

odow commented 1 year ago

Reproducible example is

using JuMP
import Hypatia
import HiGHS
import Pajarito 

model = Model(Pajarito.Optimizer)
set_attribute(model, "oa_solver", optimizer_with_attributes(HiGHS.Optimizer))
set_attribute(model, "conic_solver", optimizer_with_attributes(Hypatia.Optimizer))
@variable(model, x)
K = Hypatia.EpiPerSepSpectralCone{Float64}(
    Hypatia.Cones.NegSqrtSSF(),
    Hypatia.Cones.MatrixCSqr{Float64, Float64}, 
    2, 
    true,
)
@constraint(model, [1, x, x, x, x] in K)
optimize!(model)
julia> @constraint(model, [1, x, x, x, x] in K)
ERROR: Constraints of type MathOptInterface.VectorAffineFunction{Float64}-in-Hypatia.EpiPerSepSpectralCone{Float64} are not supported by the solver.

If you expected the solver to support your problem, you may have an error in your formulation. Otherwise, consider using a different solver.

The list of available solvers, along with the problem types they support, is available at https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers.
Stacktrace:
 [1] error(s::String)
   @ Base ./error.jl:33
 [2] _moi_add_constraint(model::MathOptInterface.Utilities.CachingOptimizer{MathOptInterface.Bridges.LazyBridgeOptimizer{MathOptInterface.Utilities.CachingOptimizer{Pajarito.Optimizer, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}}, MathOptInterface.Utilities.UniversalFallback{MathOptInterface.Utilities.Model{Float64}}}, f::MathOptInterface.VectorAffineFunction{Float64}, s::Hypatia.EpiPerSepSpectralCone{Float64})
   @ JuMP ~/.julia/packages/JuMP/9CBpS/src/constraints.jl:645
 [3] add_constraint(model::Model, con::VectorConstraint{AffExpr, Hypatia.EpiPerSepSpectralCone{Float64}, VectorShape}, name::String)
   @ JuMP ~/.julia/packages/JuMP/9CBpS/src/constraints.jl:671
 [4] macro expansion
   @ ~/.julia/packages/JuMP/9CBpS/src/macros.jl:833 [inlined]
 [5] top-level scope
   @ REPL[133]:1
odow commented 1 year ago

I guess this is actually intended. For Pajarito to form the outer approximation it needs to support the set?

@chriscoey can confirm that this is intended behavior.

matbesancon commented 1 year ago

should there be an example using a bridged optimizer then?

odow commented 1 year ago

The bridge won't work, because the set is Hypatia-specific. It also explains why Pajarito doesn't support it, because it doesn't know how to compute a supporting hyperplane for the MILP model.

chriscoey commented 1 year ago

Hi @dhendryc - so indeed @odow is correct, this is a hypatia-specific set that is not supported here, BUT... it is supported over here! So if you use that package as well, you get access to a bunch more hypatia-specific cones. Indeed, your example is similar to a special case of: https://github.com/chriscoey/PajaritoExtras.jl/blob/main/examples/experimentdesign/model.jl

chriscoey commented 1 year ago

I mention that here in the readme, so I'll close this issue. Hope that works for you.

dhendryc commented 1 year ago

@chriscoey Thank you for the suggestion! I do think this works for my case! Two question:

If I understand correctly, my f here https://github.com/chriscoey/PajaritoExtras.jl/blob/main/examples/experimentdesign/model.jl would be MatNegSqrt(). Or is it NegSqrtSSF()?

Also I tried running the code with PajaritoExtras as dependency but the add_homog_spectral is not defined. Could you tell me in which package this is defined?

Thank you so much for your support!

chriscoey commented 1 year ago

@dhendryc no problem! So add_homog_spectral is defined in Hypatia's examples folder here: https://github.com/chriscoey/Hypatia.jl/blob/master/examples/spectral_functions_JuMP.jl

since you ultimately want trace of inverse, you can use MatNegSqrtConj as the formulation selector (this gives 1/4 * tr(inv(X))). this uses the dual cone of the NegSqrtSSF case (which is trace of negative sqrt) - it looks like that's what you were trying to use. you can see more info about the separable spectral functions here: https://github.com/chriscoey/Hypatia.jl/blob/master/src/Cones/epipersepspectral/sepspectralfun.jl#L68

dhendryc commented 1 year ago

Thank you! This works!

I found a tiny issue on the PajaritoExtras: https://github.com/chriscoey/PajaritoExtras.jl/issues/4 I deved the package and just used dot. The results look good.