@NLexpression with JuMP 0.21

I tried to use an old JuMP model that was working with JuMP 0.18. But the behaviour of @NLexpression changed with JuMP 0.19 /0.20 / 0.21.

Is it a bug or I need to modify how the expression is written?

Thank you in advance for your reply!

n = m = 10
if m < n
  @warn(": number of function must be ≥ number of variables. Adjusting to m = n")
  m = n
end

nls  = Model()
x0   = collect(1:n)/(n+1)
@variable(nls, x[i=1:n], start = x0[i])

function Tsim(x, n)
  if n == 0
    return 1
  elseif n == 1
    return x
  else
    return 2*x*Tsim(x,n-1) - Tsim(x,n-2)
  end
end

Ts = Vector{Function}(undef, n)
Tnames = Vector{Symbol}(undef, n)
for i = 1:n
  Ts[i] = x -> Tsim(2*x-1, i)
  Tnames[i] = gensym()
  JuMP.register(nls, Tnames[i], 1, Ts[i], autodiff=true)
end

I = [i%2 == 0 ? -1/(i^2-1) : 0 for i = 1:n]
@NLexpression(nls, F[i=1:n], sum($(Tnames[i])(x[j]) for j = 1:n)/n - I[i])

See the documentation for how to use the raw expression format:
https://www.juliaopt.org/JuMP.jl/stable/nlp/#Raw-expression-input-1

Note that when building the expression, you need to splice in the actual variables, e.g., :($(x[j])).

@odow It seems that we can only use the raw expression format with set_NL_objective and add_NL_constraint?

Example :

@NLexpression(nls, F1, :($(x[1]) * $(x[2])))
ERROR: Unexpected object x[1] * x[2] (of type Expr in nonlinear expression.

It seems that we can only use the raw expression format with set_NL_objective and add_NL_constraint ?

Yes. You need to use the functional form.

See also Procedural Nonlinear Constaint Generation - String to NLconstraint - #4 by odow