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.