Nonlinear expressions may contain only scalar

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

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)

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.
  • 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

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.

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?

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

See Installation Guide · JuMP

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

Should be for i in 1:n I think!