# 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.