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.

2 Likes

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?

1 Like

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

1 Like

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!