Gurobi's tolerance on convexity in QCP is about `1e-13`

Following this topic

I do the following test to verify the title

using JuMP, Gurobi

function test_convexity(d) # if it ain't Error, the model is deemed convex (by Gurobi)
    model = Model(Gurobi.Optimizer)
    @variable(model, 1 - d <= x <= 1 + d)
    @variable(model, y)
    @constraint(model, x * y <= 1)
    set_attribute(model, "QCPDual", 1)
    optimize!(model)
end

test_convexity((1e-13 + 1e-14) / 2) # non convex
test_convexity(1e-13 / 2) # convex

Coefficients less than 1e-13 are regarded as zero.

Could you leave a pointer to the Gurobi doc? :slightly_smiling_face: I haven’t found that.

In this case it’s more that a variable is resolved to a constant if the bounds differ by less than 1e-13. I don’t know if this is explicitly documented anywhere (I couldn’t find it).

I don’t think this variable (in my first post, x), is simply deemed a constant.
∵ if this is the case, Gurobi should solve it as an LP with the simplex log.
If we inspect Gurobi’s logging, we find it being barrier.
∴ Gurobi does not reduce x to 1, but indeed solve it as a convex QCP (which is also easy via the barrier algorithm).

You can verify my point using this 5-line program, via inspecting the logging:

using JuMP, Gurobi
model = Model(Gurobi.Optimizer)
@variable(model, x == 1); @variable(model, y)
@constraint(model, x * y <= 1)
optimize!(model)

Simply speaking, Gurobi is not intelligent enough to identify it as an LP.