Quick question (it is quite likely this question has a simple solution), but I’m working on doing a quick overhaul of some code for a paper. The original code was written on JuMP .17/.18, but with some of the breaking changes in .19, I’m having a hard time fixing stuff up.

In particular, in the original case, I had an affine expression which needed to belong to the second-order cone, but doing the replacements mentioned in the NEWS.md file and suggested by the errors yields the following statement:

ERROR: Constraints of type MathOptInterface.VectorAffineFunction{Float64}-in-MathOptInterface.SecondOrderCone are not supported by the solver and there are no bridges that can reformulate it into supported constraints.

It seems that having an affine expression is (now) not supported(?) unless I’m missing something simple, so I’m wondering if there is a straightforward way of rephrasing this constraint in a way that JuMP will generate the corresponding conic program?

It is possibly quite simple to do directly (by adding a new dummy variable constrained to be equal to the affine expression), but—considering the current size of the program—I don’t want to double the number of variables.

A simple MWE:

using JuMP
import Gurobi
A = randn(2, 2)
m = Model(with_optimizer(Gurobi.Optimizer))
@variable(m, v[1:2])
@constraint(m, A*v ∈ SecondOrderCone())
@objective(m, Max, sum(v))
solve!(m)

Ah, interesting. I guess this makes sense: I always thought Gurobi solved general SOCPs (or conic programs), rather than doing a QCQP reduction. In either case, it’s very easy to rewrite this problem as a QCQP, so I’ll just go ahead and do that. Thanks!

Maybe I should refine my statement a little bit: Gurobi does have specialized handling of SOC constraints if it recognizes that that’s what you’re trying to specify using its generic quadratic constraint interface.

Hm, I’m not quite sure what you mean here, then… so Gurobi will detect if the construction is of a specific form (say x' * x ≤ y^2) and then perform the appropriate reduction? I see something like what you reference in the accepted forms for quadratic constraints—pg. 582 of the reference manual—but it’s absolutely unclear to me what is happening under the hood.

In either case, it seems difficult to pin down the performance tradeoffs (e.g., when Gurobi’s preserve does or doesn’t actually change the quadratic constraint to a rotated SOC, for example), but this is all independent of JuMP