Using Second-Order Cone Constraints with Logarithms in JuMP and Gurobi's C API

Hello,
I am using JuMP with the Gurobi optimizer to solve a problem involving both second-order cone constraints and logarithmic constraints. I want to model the constraint ||x||_1 >= K*||x||_2
which I coded as:
constraint(model, [sum(p ./ alp) / K; p ./ alp] in SecondOrderCone())

This works fine in one optimization problem. However, in another problem where I use Gurobi’s C API to introduce logarithmic constraints, I get the following error when trying to include the SOC constraint:

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

snippet of my model is:

using JuMP
import Gurobi

n = 3
model = direct_model(Gurobi.Optimizer())
@variable(model, p[i in 1:n] == i)
@variable(model, log_p[1:n])
grb = backend(model)
column(x::VariableRef) = Gurobi.c_column(grb, index(x))
for i in 1:n
    Gurobi.GRBaddgenconstrLog(grb, "log(p[$i])", column(p[i]), column(log_p[i]), "")
end

alp = ones(n)
K = sqrt(n)
@constraint(model, [sum(p ./ alp) / K; p ./ alp] in SecondOrderCone()) # Error here
@objective(model, Max, sum(log_p))
optimize!(model)

I think the issue arises because Gurobi’s C API might interfere with JuMP’s SOC constraint handling. I attempted to use GRBaddgenconstrNorm directly for the SOC constraint, but couldn’t get it to work.

Is there a way to use SOC constraints with logarithms in JuMP when using Gurobi’s C API?

Thanks!

The error is because you are using direct_model, and this constraint requires a bridge. Read Models · JuMP

Note that Gurobi 12 now supports nonlinear functions, so you can do:

julia> using JuMP

julia> import Gurobi

julia> begin
           n = 3
           alp, K = ones(n), sqrt(n) / 10
           model = Model(Gurobi.Optimizer)
           set_silent(model)
           @variable(model, p[i in 1:n] == i)
           @constraint(model, [sum(p ./ alp) / K; p ./ alp] in SecondOrderCone())
           @objective(model, Max, sum(log.(p)))
           optimize!(model)
           @assert is_solved_and_feasible(model)
           @show value.(p)
           @show objective_value(model)
           @show sum(log.(1:n))
       end
Set parameter LicenseID to value 890341
value.(p) = [1.0, 2.0, 3.0]
objective_value(model) = 1.791759469228055
sum(log.(1:n)) = 1.791759469228055

Also note that I had to change K; your current value is infeasible.

1 Like

Thank you! after updating Gurobi I can now use log in my objective.

1 Like

Hi,
When I try to save the MPS file using: write_to_file(model, "mps_out.mps") I am getting the following error:

ERROR: Unable to write problem to file because the chosen file format doesn't support constraints of the type MathOptInterface.VectorAffineFunction{Float64}-in-MathOptInterface.SecondOrderCone.

Is there a way to resolve this or an alternative file format that supports such constraints?

Thank you!

Currently our MPS file format does not support second order cone constraints.

You can use "model.mof.json". See MathOptFormat | Specification and description of the MathOptFormat file format

Why do you want to write the problem to a file?

Thank you for the clarification.

I actually have a larger optimization problem with a log objective function and I am using Gurobi 12. Even though the problem is convex, the terminal output says:
Solving non-convex MINLP.

I reached out to Gurobi support for help, and they requested the MPS file of the problem. That’s why I was trying to write it to a file.

You can do:

using JuMP, Gurobi
model = Model(Gurobi.Optimizer)
# ...
optimize!(model)
GRBwrite(unsafe_backend(model), "model.mps")
1 Like

Thank you it worked :slight_smile: