# Non-linear expressions in optimization

**URL:** <https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969>\
**Category:** Optimization (Mathematical)\
**Tags:** question, jump\
**Created:** [July 20, 2021, 7:46am UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969 "2021-07-20T07:46:55Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Daniel\_Villamar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daniel_villamar/32/27229_2.png) [@Daniel\_Villamar](https://discourse.julialang.org/u/Daniel_Villamar)\
**Post date:** [July 20, 2021, 7:46am UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969/1 "2021-07-20T07:46:55Z")

</div>

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.

````nohighlight
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
````

---

<div class="post-metadata">

**Author:** ![Rudi79](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rudi79/32/3884_2.png) [@Rudi79](https://discourse.julialang.org/u/Rudi79)\
**Post date:** [July 20, 2021, 9:37am UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969/2 "2021-07-20T09:37:14Z")

</div>

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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![Daniel\_Villamar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daniel_villamar/32/27229_2.png) [@Daniel\_Villamar](https://discourse.julialang.org/u/Daniel_Villamar)\
**Post date:** [July 20, 2021, 10:06am UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969/3 "2021-07-20T10:06:22Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![jairorua](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/jairorua/32/24109_2.png) [@jairorua](https://discourse.julialang.org/u/jairorua)\
**Post date:** [July 20, 2021, 10:48am UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969/4 "2021-07-20T10:48:27Z")

</div>

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](https://jump.dev/JuMP.jl/stable/manual/nlp/)

---

<div class="post-metadata">

**Author:** ![blob](https://avatars.discourse-cdn.com/v4/letter/b/ebca7d/32.png) [@blob](https://discourse.julialang.org/u/blob)\
**Post date:** [July 20, 2021, 10:51am UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969/5 "2021-07-20T10:51:39Z")

</div>

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:

```julia
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.

---

<div class="post-metadata">

**Author:** ![Daniel\_Villamar](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/daniel_villamar/32/27229_2.png) [@Daniel\_Villamar](https://discourse.julialang.org/u/Daniel_Villamar)\
**Post date:** [July 20, 2021, 4:33pm UTC](https://discourse.julialang.org/t/non-linear-expressions-in-optimization/64969/6 "2021-07-20T16:33:51Z")

</div>

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.

````nohighlight
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```
````
