 # Non-linear expressions in optimization

Hi!
I use the version JuMP v0.21.4 and Julia v1.4.2 and I optimizing with Ipopt
I ve been working in a non-linear optimization model. Sorry for not presenting a MWE but my code is full of things.
I have a problems with an exponential expression that I would like to use afterwards in an `@NLconstraint`. In the following piece of code S is my array of variables.
I originally created this code without the `convert(Array{Any}...` but I got an error and I coudn’t even calculate the array Sd. Now the problem is that when including Sd in a non-linear expression I get the error copied at the end. I also tried to build this into an `@NLexpression` but that didn’t work either.

``````for e in 1:E
for i in 2:K*T
Sd[i,1,e]=S[i,1,e]-S[i-1,1,e]
end
end
Sd
exp(ϵ*Sd)/(1+exp(ϵ*Sd))```

MethodError: no method matching exp(::Array{Any,3})
Closest candidates are:
exp(!Matched::Float16) at math.jl:1114
exp(!Matched::Complex{Float16}) at math.jl:1115
exp(!Matched::Missing) at math.jl:1167``````
1 Like

I never used JuMP and I don’t know exactly what you want to achieve.
If you want to calculate the exponential elementwise, you have to sprinkle some dots here and there:

``````exp.(e*Sd) ./ (1 .+ exp.(e*Sd))
``````

The above snippet assumes that e is a scalar. This is called broadcasting and allows any function that operates on a single element to be called on the whole collection.

Thanks a lot for your answer. The piece of code I showed is part of a non-linear optimization problem I’m building with JUMP. The exponential function I wrote will be used to create some of the no-linear constraints in my problem.
Yes you are right, in fact I have tried with this expression before `exp.(ϵ*Sd)./(1+exp.(ϵ*Sd)) `. With the dots the expression is correct but I still recieve the following error message:
exp is not defined for type GenericAffExpr. Are you trying to build a nonlinear problem? Make sure you use @NLconstraint/@NLobjective.

You cannot use broadcasting within @NLconstraint/@NLobjective in JuMP. You need to have a loop in the constraint/objective. JuMP’s documentation specifies:

" With the exception of the splatting syntax discussed below, all expressions must be simple scalar operations. You cannot use `dot` , matrix-vector products, vector slices, etc."

There are some examples here: Nonlinear Modeling · JuMP

1 Like

Since your S is a variable, your Sd by default will be an affine expression. As far as I know, it is not possible to mix affine expressions and nonlinear expressions in JuMP. To avoid that mix, you should define your Sd as a nonlinear expression, something like:
`@NLexpression(model, Sd[e=1:K,1,i=2:K*T], S[i,1,e]-S[i-1,1,e]) `
where `model` is your JuMP model. Then you should be able to do:

``````for e in 1:E
for i in 2:K*T
@NLexpression(model, expExpr[e,i], exp(ϵ*Sd[e,1,i])/(1.0+exp(ϵ*Sd[e,1,i])))
end
end
``````

and use `expExpr` later in your model. The `@NLexpression` cannot take arrays, that’s why the two loops are necessary.

Disclaimer: I have not tested this solution (it would be easier with an MWE). There may be troubles with the middle indicator in Sd - if it is only 1, then you could remove it.

1 Like

Hello blob and thanks for your reply, by following the code you suggested, I was able to create a new loop that seems ok. The non-linear expression must be anonymous for it to work.

``````for e in 1:E
for i in 2:K*T
Sd[i-1,1,e]=@NLexpression(m, exp(ϵ*(Sd[i,1,e]-S[i-1,1,e]))/(1.0+exp(ϵ*(Sd[i,1,e]-S[i-1,1,e]))))
end
end
Sd`````````
1 Like