Optimize many non linear functions

I’m tying optimize the sum of series objective functions in funcs using the Ipot optimizer

A minimal example shown below show result in an optimal objective value of 5.
However it current returns objective_value(model) = 2.0

using JuMP, Ipopt
f1(δ) = -(δ - 2) ^ 2 + 1
f2(δ) = -(δ - 7) ^ 2 + 4
funcs = [f1, f2]
model = Model(Ipopt.Optimizer)
@variable(model, x[1:length(funcs)] >= 0)
@constraint(model, sum(x) <= 10)
@NLobjective(model, Max, sum(f(x) for (f,x) in zip(funcs, x)))
optimize!(model)
@show objective_value(model);

My understanding is that the @NLobjectives is parsing the actual code so the f(x) in the sum gets interpreted as repeats of the same function. so it is just optimizing f1 + f1 instead of f1 + f2.
Is it possible to make @NLobjectives parse the correct target function without doing a lot of metaprogramming?
Thanks in advance for the help!

No need for metaprogramming, but after registering the functions you’ll likely need to construct the objective expression data structure programmatically: Nonlinear Modeling · JuMP.

@miles.lubin thanks so much for the quick reply!!
The code below now now works as intended.

using JuMP, Ipopt
f1(δ) = -(δ - 2) ^ 2 + 1
f2(δ) = -(δ - 7) ^ 2 + 4
funcs = [f1, f2]
model = Model(Ipopt.Optimizer)
@variable(model, x[1:length(funcs)] >= 0)
@constraint(model, sum(x) <= 10)
expr = Expr(:call, :+)
for (i, (f, x)) in enumerate(zip(funcs, x))
    f_sym = Symbol("f_$(i)")
    register(model, f_sym, 1, f; autodiff = true)
    push!(expr.args, :($(f_sym)($(x))))
end
set_NL_objective(model, MAX_SENSE, :($(expr))) 

optimize!(model)
@show objective_value(model);

Thanks again!


One minor bug to report: once you start optimizing many functions, there is visual bug in latex_formulation where f_10 is rendered as f_10 and not f_{10} in latex.

2 Likes

Just on the minor bug: are you not defining the Symbol f_10 yourself with the line

f_sym = Symbol("f_$(i)")

or am I missing something?

We should probably escape this as f\_10, so yes, this is a bug in the latex printing.