Skip to content
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

Add support for quadratic objective functions #384

Open
tpunnoose opened this issue Apr 9, 2020 · 6 comments
Open

Add support for quadratic objective functions #384

tpunnoose opened this issue Apr 9, 2020 · 6 comments

Comments

@tpunnoose
Copy link

I am trying to use Convex.jl to interface with the OSQP solver. However, for some reason I am unable to use quadform in the objective and still have it link to the OSQP optimizer.

using Convex
using LinearAlgebra
using OSQP

x = Variable(5)
P = Diagonal(ones(5))

problem = minimize(quadform(x, P))

solve!(problem, OSQP.Optimizer)

When this code runs I get the following error:

LoadError: MathOptInterface.UnsupportedConstraint{MathOptInterface.VectorAffineFunction{Float64},MathOptInterface.SecondOrderCone}("")

I don't understand why it throws an unsupported constraint error as there are no constraints.

@ericphanson
Copy link
Collaborator

ericphanson commented Apr 9, 2020

Thanks for bringing this to my attention. This currently doesn’t work in Convex because Convex rewrites the problem to have a linear objective function subject to “second order cone constraints”. This transformation makes solving such a problem easy for solvers that support such constraints but not quadratic objectives (ECOS, SCS, etc), but makes it unable to work with OSQP that does want this specific form. The long term fix is to only do this transformation as necessary, instead of always doing it as Convex does now. I hope to move to that approach (by delegating these transformations to MathOptInterface which only applies them when necessary) at some point but it might take some time.

In the meantime, I’d suggest using JuMP.jl or maybe Parametron.jl, depending on your use case.

I’ll mark this as a feature request to be closed whenever the right behavior is implemented.

@odow
Copy link
Member

odow commented Apr 10, 2020

You should be able to do (I haven't tested though)

using Convex
using LinearAlgebra
using OSQP
using MathOptInterface

x = Variable(5)
P = Diagonal(ones(5))

problem = minimize(quadform(x, P))

solve!(problem, () -> MOI.Bridges.full_bridge_optimizer(OSQP.Optimizer(), Float64))

@blegat
Copy link
Member

blegat commented Apr 10, 2020

@odow Convex transmit the problem as a SOC constraint and we don't have any bridge to transform this SOC constraint back to a quadratic objective as OSQP requires (and it does not seem to be something feasible via bridges) so I don't think that this will work.

The long term fix is to only do this transformation was necessary, instead of always doing it as Convex does now. I hope to move to that approach (by delegating these transformations to MathOptInterface which only applies them when necessary) at some point but it might take some time.

I agree that this would be the ideal long term fix.

@lrnv
Copy link
Contributor

lrnv commented Sep 19, 2021

I just noticed that for other solvers like COSMO that allows quadrative objectives, Convex also uses this trick and does not pass along a quadratic objective.

What is the current status on this ? Will it be possible soeday to pass along quadratic objectives to solvers ?

@ericphanson
Copy link
Collaborator

What is the current status on this ?

same as before- Convex reformulates all problems with extended formulations (always) and passes a single variable objective.

Will it be possible soeday to pass along quadratic objectives to solvers ?

Just depends if someone implements it or not :). AFAIK no one is actively developing Convex.jl right now, but anyone who wants to can!

I used Convex a little bit in my PhD so I tried to help develop it further for a year or two (and mostly just fixed bugs)- happy to try to help and provide code review for any PRs (but I don’t really see myself doing much development myself any time soon- I don’t use Convex anymore, so it’s hard to be motivated for it).

@odow odow changed the title Unable to use OSQP Add support for quadratic objective functions Jan 19, 2024
@odow
Copy link
Member

odow commented Jan 22, 2024

So there's a path forward here:

If the objective is a quadratic atom, then instead of calling conic_form! on it, we could convert into a ScalarQuadraticFunction if supported.

Here's the bits that would need changed:

Convex.jl/src/problems.jl

Lines 136 to 171 in 946d18d

function new_conic_form!(context::Context, p::Problem)
for c in p.constraints
add_constraint!(context, c)
end
if p.head == :satisfy
return
end
return conic_form!(context, p.objective)
end
function _to_scalar_moi(::Type{T}, x) where {T}
return _to_scalar_moi(T, only(MOI.Utilities.scalarize(x)))
end
function _to_scalar_moi(::Type{T}, x::SparseTape) where {T}
return _to_scalar_moi(T, to_vaf(x))
end
function _to_scalar_moi(::Type{T}, x::Number) where {T<:Real}
return MOI.ScalarAffineFunction{T}(MOI.ScalarAffineTerm{T}[], x)
end
_to_scalar_moi(::Type{T}, f::MOI.AbstractScalarFunction) where {T} = f
function Context(p::Problem{T}, optimizer_factory) where {T}
context = Context{T}(optimizer_factory)
cfp = conic_form!(context, p)
# Save some memory before the solve;
# we don't need these anymore,
# since we don't re-use contexts between solves currently
empty!(context.conic_form_cache)
if p.head == :satisfy
MOI.set(context.model, MOI.ObjectiveSense(), MOI.FEASIBILITY_SENSE)
else
obj = _to_scalar_moi(T, cfp)
MOI.set(context.model, MOI.ObjectiveFunction{typeof(obj)}(), obj)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

No branches or pull requests

5 participants