JuMP new nonlinear interface: adding constraint programatically

ModelPredictiveControl.jl is still using the legacy syntax for NLP, but I’m starting the migration right now. The nonlinear inequality constraints are currently added programmatically with (simplified for the purpose of the explanation):

using JuMP, Ipopt
model = Model(Ipopt.Optimizer)
nx = 2
@variable(model, x[1:nx])
gfunc_i(i, x) = 10x[i]^2 - 10
gfunc = [(x...) -> gfunc_i(i, x) for i in 1:nx]
ymin, ymax = [-1, -1], [1, 1]
for i in eachindex(ymin)
    sym = Symbol("g_ymin_$i")
    register(model, sym, nx, gfunc[i], autodiff=true)
    add_nonlinear_constraint(model, :(-$(sym)($(x...)) <= -$(ymin[i])))
end
for i in eachindex(ymax)
    sym = Symbol("g_ymax_$i")
    register(model, sym, nx, gfunc[i], autodiff=true)
    add_nonlinear_constraint(model, :(+$(sym)($(x...)) <= +$(ymax[i])))
end

is there an equivalent for the add_nonlinear_constraint method in the new NLP syntax? I’ve tried add_constraint but I’m not sure how to use it since the docstring is not very detailed:

help?> add_constraint
search: add_constraint add_nonlinear_constraint

  add_constraint(model::GenericModel, con::AbstractConstraint, name::String="")

  Add a constraint con to Model model and sets its name.

Thanks for the help :slight_smile:

1 Like
using JuMP
gfunc_i(i, x) = 10x[i]^2 - 10
ymin, ymax = [-1, -1], [1, 1]
nx = length(ymin)
model = Model()
@variable(model, x[1:nx])
# Option 1: function tracing
@constraint(model, [i in 1:nx], ymin[i] <= gfunc_i(i, x) <= ymax[i])

# Option 2: operator
for i in 1:nx
    g = (x...) -> g_func_i(i, x)
    op = add_nonlinear_operator(model, nx, g; name = Symbol("gfunc_$i"))
    @constraint(model, ymin[i] <= op(x...) <= ymax[i])
end

For option 1, see: Nonlinear Modeling · JuMP

For options 2, see: Nonlinear Modeling · JuMP

1 Like

Wow, it is way cleaner like that haha. The operator option works well, thanks!

1 Like

Wow, it is way cleaner like that haha

Yip! I put a bit of thought into making sure things like this were now well supported :smile:

1 Like

It shows, I really like the new syntax.

1 Like