# Nonlinear expressions may contain only scalar expressions

**URL:** https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar-expressions/45147
**Category:** Optimization (Mathematical)
**Tags:** question
**Created:** [August 18, 2020, 8:57am UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar-expressions/45147 "2020-08-18T08:57:50Z")
**Posts on this page:** 4
**Page:** 1

<div class="post-metadata">

### Author: ![zlq178](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/zlq178/32/17952_2.png) [@zlq178](https://discourse.julialang.org/u/zlq178)
#### Post date: [August 18, 2020, 8:57am UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar-expressions/45147/1 "2020-08-18T08:57:50Z")

</div>

```julia
using JuMP,Gurobi
 n=4
PL=[0.3;0.55;0;0]
model=Model(Gurobi.Optimizer)
G=[1.04209 -0.588235 -0.0 -0.453858;-0.588235 1.069 0 -0.480769;-0 0 0 0;-0.453858 -0.480769 0 0.934627]
Q=[-8.24288 2.35294 3.66667 1.89107; 2.35294 -4.72738 0.0 2.40385;3.66667 0.0 -3.33333 0.0; 1.89107 2.40385 0.0 -4.26159]
@variable(model, U[1:n])
@variable(model, P[1:n])
@variable(model, Ang[1:n])
@variable(model, Angle[1:n,1:n])
@constraint(model, con5[i = 1:n, j = 1:n], Angle[i,j]==Ang[i] .-Ang[j])
@expression(model, my_expr, P-PL)
@NLconstraint(model,co1,my_expr==U.*((G.*cos.(Angle)+Q.*sin.(Angle))*U))

```

error:

 ![image](https://global.discourse-cdn.com/julialang/original/3X/1/0/100eb5586d6e2272bbf8d3eb2d9f5af57412a383.png)  
Is P-PL wrong? How could I solve it?

---

<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: [August 18, 2020, 8:17pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar-expressions/45147/2 "2020-08-18T20:17:41Z")

</div>

Two issues.

1. As stated in the error, you can only use scalar expressions. That means no vectors, and no broadcasting. Here is the documentation: [Nonlinear Modeling · JuMP](https://jump.dev/JuMP.jl/v0.21.1/nlp/#Syntax-notes-1)

2. Gurobi doesn’t support nonlinear. Use Ipopt instead.

---

<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: [October 2, 2023, 2:20pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar-expressions/45147/3 "2023-10-02T14:20:49Z")

</div>

@Shayan (and anyone else coming across this post): with version v1.15 of JuMP you can use `@constraint` instead of `@NLconstraint` and everything works:

```julia
julia> using JuMP, Ipopt

julia> n = 4
4

julia> PL = [0.3, 0.55, 0.0, 0.0]
4-element Vector{Float64}:
 0.3
 0.55
 0.0
 0.0

julia> model=Model(Ipopt.Optimizer)
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: EMPTY_OPTIMIZER
Solver name: Ipopt

julia> G = [
            1.04209 -0.588235 0.0 -0.453858
           -0.588235 1.069 0.0 -0.480769
            0.0 0.0 0.0 0
           -0.453858 -0.480769 0.0 0.934627
       ]
4×4 Matrix{Float64}:
  1.04209 -0.588235 0.0 -0.453858
 -0.588235 1.069 0.0 -0.480769
  0.0 0.0 0.0 0.0
 -0.453858 -0.480769 0.0 0.934627

julia> Q = [
           -8.24288 2.35294 3.66667 1.89107
            2.35294 -4.72738 0.0 2.40385
            3.66667 0.0 -3.33333 0.0
            1.89107 2.40385 0.0 -4.26159
       ]
4×4 Matrix{Float64}:
 -8.24288 2.35294 3.66667 1.89107
  2.35294 -4.72738 0.0 2.40385
  3.66667 0.0 -3.33333 0.0
  1.89107 2.40385 0.0 -4.26159

julia> @variable(model, U[1:n])
4-element Vector{VariableRef}:
 U[1]
 U[2]
 U[3]
 U[4]

julia> @variable(model, P[1:n])
4-element Vector{VariableRef}:
 P[1]
 P[2]
 P[3]
 P[4]

julia> @variable(model, Ang[1:n])
4-element Vector{VariableRef}:
 Ang[1]
 Ang[2]
 Ang[3]
 Ang[4]

julia> @variable(model, Angle[1:n,1:n])
4×4 Matrix{VariableRef}:
 Angle[1,1] Angle[1,2] Angle[1,3] Angle[1,4]
 Angle[2,1] Angle[2,2] Angle[2,3] Angle[2,4]
 Angle[3,1] Angle[3,2] Angle[3,3] Angle[3,4]
 Angle[4,1] Angle[4,2] Angle[4,3] Angle[4,4]

julia> @constraint(model, con5[i = 1:n, j = 1:n], Angle[i,j] == Ang[i] .- Ang[j])
4×4 Matrix{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarAffineFunction{Float64}, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
 con5[1,1] : Angle[1,1] = 0 … con5[1,4] : -Ang[1] + Ang[4] + Angle[1,4] = 0
 con5[2,1] : Ang[1] - Ang[2] + Angle[2,1] = 0 con5[2,4] : -Ang[2] + Ang[4] + Angle[2,4] = 0
 con5[3,1] : Ang[1] - Ang[3] + Angle[3,1] = 0 con5[3,4] : -Ang[3] + Ang[4] + Angle[3,4] = 0
 con5[4,1] : Ang[1] - Ang[4] + Angle[4,1] = 0 con5[4,4] : Angle[4,4] = 0

julia> @expression(model, my_expr, P - PL)
4-element Vector{AffExpr}:
 P[1] - 0.3
 P[2] - 0.55
 P[3]
 P[4]

julia> @constraint(model, my_expr .== U .* ((G .* cos.(Angle) + Q .* sin.(Angle)) * U))
4-element Vector{ConstraintRef{Model, MathOptInterface.ConstraintIndex{MathOptInterface.ScalarNonlinearFunction, MathOptInterface.EqualTo{Float64}}, ScalarShape}}:
 (P[1] - 0.3) - (U[1] * ((((+(0.0) + (((1.04209 * cos(Angle[1,1])) + (-8.24288 * sin(Angle[1,1]))) * U[1])) + (((-0.588235 * cos(Angle[1,2])) + (2.35294 * sin(Angle[1,2]))) * U[2])) + (((0.0 * cos(Angle[1,3])) + (3.66667 * sin(Angle[1,3]))) * U[3])) + (((-0.453858 * cos(Angle[1,4])) + (1.89107 * sin(Angle[1,4]))) * U[4]))) = 0
 (P[2] - 0.55) - (U[2] * ((((+(0.0) + (((-0.588235 * cos(Angle[2,1])) + (2.35294 * sin(Angle[2,1]))) * U[1])) + (((1.069 * cos(Angle[2,2])) + (-4.72738 * sin(Angle[2,2]))) * U[2])) + (((0.0 * cos(Angle[2,3])) + (0.0 * sin(Angle[2,3]))) * U[3])) + (((-0.480769 * cos(Angle[2,4])) + (2.40385 * sin(Angle[2,4]))) * U[4]))) = 0
 (P[3]) - (U[3] * ((((+(0.0) + (((0.0 * cos(Angle[3,1])) + (3.66667 * sin(Angle[3,1]))) * U[1])) + (((0.0 * cos(Angle[3,2])) + (0.0 * sin(Angle[3,2]))) * U[2])) + (((0.0 * cos(Angle[3,3])) + (-3.33333 * sin(Angle[3,3]))) * U[3])) + (((0.0 * cos(Angle[3,4])) + (0.0 * sin(Angle[3,4]))) * U[4]))) = 0
 (P[4]) - (U[4] * ((((+(0.0) + (((-0.453858 * cos(Angle[4,1])) + (1.89107 * sin(Angle[4,1]))) * U[1])) + (((-0.480769 * cos(Angle[4,2])) + (2.40385 * sin(Angle[4,2]))) * U[2])) + (((0.0 * cos(Angle[4,3])) + (0.0 * sin(Angle[4,3]))) * U[3])) + (((0.934627 * cos(Angle[4,4])) + (-4.26159 * sin(Angle[4,4]))) * U[4]))) = 0

```

---

<div class="post-metadata">

### Author: ![Shayan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/shayan/32/33025_2.png) [@Shayan](https://discourse.julialang.org/u/Shayan)
#### Post date: [October 2, 2023, 2:27pm UTC](https://discourse.julialang.org/t/nonlinear-expressions-may-contain-only-scalar-expressions/45147/4 "2023-10-02T14:27:51Z")

</div>

Dear @odow, Hi  
My case is a bit different, and [this topic](https://jump.dev/JuMP.jl/stable/manual/nlp/#Scalar-operations-only) helped me tackle the problem. I’m super grateful for the tremendous support and time that you put into assisting Julia users and devs.  
But, great to know that in this case using `@constraint` is all we need.
