-
Notifications
You must be signed in to change notification settings - Fork 18
Open
jump-dev/MathOptInterface.jl
#2808Description
@objective and @constraint seem to be reformulating x^2 to x*x in nonlinear expressions, which leads to poorer McCormick relaxations. This isn't an issue when using the legacy macros of @NLobjective and @NLconstraint. I suspect this happens somewhere in
EAGO.jl/src/eago_optimizer/moi_wrapper.jl
Lines 74 to 100 in 15bb6cb
| function MOI.add_constraint(m::Optimizer, f::F, s::S) where {F<:Union{SAF,SQF,MOI.ScalarNonlinearFunction},S<:INEQ_SETS} | |
| check_inbounds!(m, f) | |
| ci = CI{F, S}(m._input_problem._constraint_count += 1) | |
| if f isa MOI.ScalarNonlinearFunction | |
| if isnothing(m._input_problem._nlp_data) | |
| model = MOI.Nonlinear.Model() | |
| backend = MOI.Nonlinear.SparseReverseMode() | |
| vars = MOI.get(m, MOI.ListOfVariableIndices()) | |
| evaluator = MOI.Nonlinear.Evaluator(model, backend, vars) | |
| m._input_problem._nlp_data = MOI.NLPBlockData(evaluator) | |
| end | |
| MOI.Nonlinear.add_constraint(m._input_problem._nlp_data.evaluator.model, f, s) | |
| constraint_bounds = m._input_problem._nlp_data.constraint_bounds | |
| has_objective = m._input_problem._nlp_data.has_objective | |
| if s isa MOI.LessThan | |
| push!(constraint_bounds, MOI.NLPBoundsPair(-Inf, s.upper)) | |
| elseif s isa MOI.GreaterThan | |
| push!(constraint_bounds, MOI.NLPBoundsPair(s.lower, Inf)) | |
| else | |
| push!(constraint_bounds, MOI.NLPBoundsPair(s.value, s.value)) | |
| end | |
| m._input_problem._nlp_data = MOI.NLPBlockData(constraint_bounds, m._input_problem._nlp_data.evaluator, has_objective) | |
| else | |
| _constraints(m, F, S)[ci] = (f, s) | |
| end | |
| return ci | |
| end |
EAGO.jl/src/eago_optimizer/moi_wrapper.jl
Lines 277 to 294 in 15bb6cb
| function MOI.set(m::Optimizer, ::MOI.ObjectiveFunction{T}, f::T) where T <: Union{VI,SAF,SQF,MOI.ScalarNonlinearFunction} | |
| check_inbounds!(m, f) | |
| if f isa MOI.ScalarNonlinearFunction | |
| if isnothing(m._input_problem._nlp_data) | |
| model = MOI.Nonlinear.Model() | |
| MOI.Nonlinear.set_objective(model, f) | |
| backend = MOI.Nonlinear.SparseReverseMode() | |
| vars = MOI.get(m, MOI.ListOfVariableIndices()) | |
| evaluator = MOI.Nonlinear.Evaluator(model, backend, vars) | |
| m._input_problem._nlp_data = MOI.NLPBlockData(evaluator) | |
| else | |
| MOI.Nonlinear.set_objective(m._input_problem._nlp_data.evaluator.model, f) | |
| m._input_problem._nlp_data = MOI.NLPBlockData(m._input_problem._nlp_data.evaluator) | |
| end | |
| else | |
| m._input_problem._objective = f | |
| end | |
| end |
Example:
model = JuMP.Model(EAGO.Optimizer)
@variable(model, x[1:2])
@objective(model, Min, x[1]^2 + x[2]^3)
JuMP.optimize!(model)returns
MathOptInterface.Nonlinear.Expression(
MathOptInterface.Nonlinear.Node[
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 2, -1),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 1, 1),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 3, 2),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 1, 3),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 1, 3),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 4, 2),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 2, 6),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_VALUE, 1, 6),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 3, 1)
],
[3.0]
)
model = JuMP.Model(EAGO.Optimizer)
@variable(model, x[1:2])
@NLobjective(model, Min, x[1]^2 + x[2]^3)
JuMP.optimize!(model)returns
MathOptInterface.Nonlinear.Expression(
MathOptInterface.Nonlinear.Node[
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 2, -1),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 1, 1),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 4, 2),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 1, 3),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_VALUE, 1, 3),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_CALL_MULTIVARIATE, 4, 2),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 2, 6),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_VALUE, 2, 6),
MathOptInterface.Nonlinear.Node(MathOptInterface.Nonlinear.NODE_MOI_VARIABLE, 3, 1)
],
[2.0, 3.0]
)
(i.e., x^2 + x^3, as expected).
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels