# Nonlinear expressions may contain only scalar

**URL:** <https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [May 8, 2022, 8:35pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721 "2022-05-08T20:35:59Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Tri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tri/32/36918_2.png) [@Tri](https://discourse.julialang.org/u/Tri)\
**Post date:** [May 8, 2022, 8:35pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721/1 "2022-05-08T20:35:59Z")

</div>

Totally new to Julia. I tried to look up a solution to this error message but couldn’t find a helpful answer  
“Nonlinear expressions may contain only scalar expressions”

What exactly should I do to circumvent this error message and pass a nonlinear vector constraint?  
Here is the the optimization problem that I am trying to set up, but the error message concerns constraints c3, c4,c5

```julia
using Ipopt
model = Model(Ipopt.Optimizer)
s = 2
e = [1,1]
@objective(model, Min, 0)
@variable(model, a[1:s, 1:s]>=0)
@variable(model, r[1:s, 1:s],Symmetric)
@variable(model, b[1:s]>=0)
@constraint(model, c1, b'*e == 1)
@NLconstraint(model, c2, b' * c == 1/2)
@NLconstraint(model, c3, b' * (a*e).^2 == 1/3)
@NLconstraint(model, c4, b' * a * (a*e) ==1/6)
@NLconstraint(model, c5, r*a + a'*r -b*b',PSD)

print(model)

```

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [May 8, 2022, 9:05pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721/2 "2022-05-08T21:05:16Z")

</div>

Welcome to JuMP!

Quite a few things:

- You can use linear algebra (e.g., `b' * e`) in `@constraint`, but not `@NLconstraint`. It’s annoying, but we’re [working on fixing it](https://jump.dev/announcements/2022/02/21/lanl/).
- If the terms are linear or quadratic, you can use `@constraint`. You only need `@NLconstraint` for things other than linear and quadratic.
- Your syntax for PSD constraints is slightly wrong
- Ipopt doesn’t support PSD constraints

Here’s how I would re-write your constraints

```julia
using JuMP
s, e = 2, [1, 1]
model = Model()
@variable(model, a[1:s, 1:s] >= 0)
@variable(model, r[1:s, 1:s], Symmetric)
@variable(model, b[1:s] >= 0)

# You can use linear algebra in `@constraint`
@constraint(model, c1, b' * e == 1)
# but not in `@NLconstraint`
# @NLconstraint(model, c2, b' * c == 1/2)
# What is c???
# @NLconstraint(model, c2, sum(b[i] * c[i] for i in 1:s) == 1/2)

# @NLconstraint(model, c3, b' * (a*e).^2 == 1/3)
a_e = @expression(model, a * e)
@NLconstraint(model, c3, sum(b[i] * a_e[i]^2 for i in 1:s) == 1 / 3)

# @NLconstraint(model, c4, b' * a * (a*e) ==1/6)
a_a_e = @expression(model, a * a * e)
@NLconstraint(model, c4, sum(b[i] * a_a_e[i] for i in 1:s) == 1 / 6)

# @NLconstraint(model, c5, r*a + a'*r -b*b',PSD)
X = r * a + a' * r - b * b'
@constraint(model, c5, Symmetric(X) >= 0, PSDCone())

```

The `c5` constraint is going to become a problem. I don’t know a solver which would support quadratic in PSD cone. and especially when it isn’t positive semidefinite.

---

<div class="post-metadata">

**Author:** ![ccoffrin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/ccoffrin/32/400_2.png) [@ccoffrin](https://discourse.julialang.org/u/ccoffrin)\
**Post date:** [May 8, 2022, 9:11pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721/3 "2022-05-08T21:11:30Z")

</div>

Hi Tri, welcome to Julia and JuMP!

If your functions are conic, quadratic or linear you will want to use `@constraint` instead of `@NLconstraint` and when using `@constraint` you can use vectorized and broadcasting Julia syntax as you have done here.

When you are using `@NLconstraint` you currently can’t do things like `b' * c` or `(a*e).^2`. You have to unroll the vector operations explicitly like `for i in 1..n @NLconstraint(model, b[i] * c[i] == 1/2) end`.

Adding better vectorized support in `@NLconstraint` is a known issue that is in the JuMP’s development roadmap.

As a side note, this model looks to me to include both high order polynomials and PSD constraints. JuMP will let you build a model like this but I am not sure of any solver that support both of these constraints. Maybe KNITRO does? @odow do you know of one?

---

<div class="post-metadata">

**Author:** ![Tri](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tri/32/36918_2.png) [@Tri](https://discourse.julialang.org/u/Tri)\
**Post date:** [May 8, 2022, 10:07pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721/4 "2022-05-08T22:07:04Z")

</div>

Thanks @odow. Do you have any suggestion of what solvers to try for SDP in general?

---

<div class="post-metadata">

**Author:** ![odow](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/odow/32/28685_2.png) [@odow](https://discourse.julialang.org/u/odow)\
**Post date:** [May 8, 2022, 10:24pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721/5 "2022-05-08T22:24:43Z")

</div>

See [Installation Guide · JuMP](https://jump.dev/JuMP.jl/stable/installation/#Supported-solvers)

But SCS.jl is a good starting point. It doesn’t do quadratic though (except as second order comes).

---

<div class="post-metadata">

**Author:** ![maxkapur](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/maxkapur/32/21208_2.png) [@maxkapur](https://discourse.julialang.org/u/maxkapur)\
**Post date:** [May 9, 2022, 10:16am UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar/80721/6 "2022-05-09T10:16:08Z")

</div>

Should be `for i in 1:n` I think!
