How to define this expression?

Hello there

I want to solve the following model

using JuMP, Ipopt
model = Model(Ipopt.Optimizer)
n = 5
@variable(model, X[1:n, 1:n])
@variable(model, y[1:n])

u = ones(n)
z = @expression(model, X * u)

expr = (1/factorial(n))*z.^4 - (1/factorial(n+1)) * X * (z.^4)

@NLconstraint(model, sum(y[i]*expr[i] for i in 1:n) == 1 )

JuMP did not like the expr vector. So I wrapped it into @expression as

expr = @expression(model, expr[i=1:n] ,(1/factorial(n))*z[i]^4 - (1/factorial(n+1)) * sum(X[i,j]*z[j]^4 for j in 1:i) for i in 1:n)

But I got the following error

Unexpected object Base.Generator{UnitRange{Int64}, var"#620#623"}(var"#620#623"(), 1:5) (of type Base.Generator{UnitRange{Int64}, var"#620#623"} in nonlinear expression.

[1] error(s::String)
@ Base ./error.jl:33
[2] _parse_NL_expr_runtime(m::Model, x::Base.Generator{UnitRange{Int64}, var"#620#623"}, tape::Vector{JuMP._Derivatives.NodeData}, parent::Int64, values::Vector{Float64})
@ JuMP ~/.julia/packages/JuMP/0C6kd/src/parse_nlp.jl:510
[3] macro expansion
@ ~/.julia/packages/JuMP/0C6kd/src/parse_nlp.jl:544 [inlined]
[4] macro expansion
@ ~/.julia/packages/JuMP/0C6kd/src/macros.jl:2121 [inlined]
[5] top-level scope
@ ./In[44]:14
[6] eval
@ ./boot.jl:373 [inlined]
[7] include_string(mapexpr::typeof(REPL.softscope), mod::Module, code::String, filename::String)
@ Base ./loading.jl:1196

Is there any way to define expr vector needed for the constraint?

1 Like

One approach is this:

using JuMP, Ipopt
n = 5
n! = factorial(n)
model = Model(Ipopt.Optimizer)
@variable(model, X[1:n, 1:n])
@variable(model, y[1:n])
@expression(model, z[i=1:n], sum(X[i, :]))
    z[i]^4 / n! - sum(X[i, j] * z[j]^4 for j in 1:n) / (n! * (n + 1)),
@NLconstraint(model, sum(y[i] * expr[i] for i in 1:n) == 1)

The trick is to realize that you can’t construct nonlinear expressions outside the macros, you can’t use linear algebra like X * z, and you can’t use function calls like factorial(n) inside the macro.