# Question about Nonlinear expressions in jump

**URL:** <https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353>\
**Category:** Optimization (Mathematical)\
**Tags:** question\
**Created:** [October 15, 2024, 10:06pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353 "2024-10-15T22:06:58Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![lukebhan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lukebhan/32/212671_2.png) [@lukebhan](https://discourse.julialang.org/u/lukebhan)\
**Post date:** [October 15, 2024, 10:06pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353/1 "2024-10-15T22:06:59Z")

</div>

Hi, I am trying to use Jump (v 1.23.2) with Julia (1.11.0) with nonlinear constraints where I essential invert a constructed matrix depending on the variable x.  
Namely, something like

```julia
m = Model(optimizer_with_attributes(Ipopt.Optimizer))
@variable(m, x[1:4*N])
@NLobjective(m, Min, sum(x)^2)
aVal(x::vector) = [x[1], x[2]; x[3], x[4]] # construct 2x2 matrix depending on variable x. Simplified in this example. 
@constraint(m, eqconsc[i=1:N], blah = inv(aVal(x[(i-1)*4+1:4*i]))*x[(i-1)*4+1:4*i]) # compute blah = (A(x))^{-1} x

```

and it appears I am unable to have a nonlinear expression inside a nonlinear expression (ie inv, a nonlinear expression takes in another nonlinear expression aVal)). Is there anyway around this or am I making a mistake in the syntax?

---

<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 15, 2024, 10:19pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353/2 "2024-10-15T22:19:49Z")

</div>

Hi @lukebhan, welcome to the forum 😄

There are a couple of things going on:

1. You’re mixing the old `@NL` nonlinear syntax with the new
2. `aVal(x::vector) = [x[1], x[2]; x[3], x[4]]` should be `aVal(x::Vector) = [x[1] x[2]; x[3] x[4]]`
3. Is this the error you’re talking about?

```Julia
julia> aVal(x[(i-1)*4+1:4*I])
2×2 Matrix{VariableRef}:
 x[1] x[2]
 x[3] x[4]

julia> inv(aVal(x[(i-1)*4+1:4*I]))
ERROR: MethodError: no method matching NonlinearExpr(::NonlinearExpr)

Closest candidates are:
  GenericNonlinearExpr{V}(::Symbol, ::Vector{Any}) where V<:AbstractVariableRef
   @ JuMP ~/.julia/packages/JuMP/6RAQ9/src/nlp_expr.jl:95
  GenericNonlinearExpr{V}(::Symbol, Any...) where V<:AbstractVariableRef
   @ JuMP ~/.julia/packages/JuMP/6RAQ9/src/nlp_expr.jl:84

Stacktrace:
 [1] oneunit(::Type{NonlinearExpr})
   @ Base ./number.jl:372
 [2] lutype(T::Type)
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/lu.jl:210
 [3] lu(A::Matrix{VariableRef}, pivot::LinearAlgebra.RowMaximum; check::Bool)
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/lu.jl:300
 [4] lu(A::Matrix{VariableRef}, pivot::LinearAlgebra.RowMaximum)
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/lu.jl:299
 [5] lu(A::Matrix{VariableRef})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/lu.jl:299
 [6] inv(A::Matrix{VariableRef})
   @ LinearAlgebra ~/.julia/juliaup/julia-1.10.5+0.x64.apple.darwin14/share/julia/stdlib/v1.10/LinearAlgebra/src/dense.jl:917
 [7] top-level scope
   @ REPL[22]:1

julia> oneunit(NonlinearExpr)
ERROR: MethodError: no method matching NonlinearExpr(::NonlinearExpr)

Closest candidates are:
  GenericNonlinearExpr{V}(::Symbol, ::Vector{Any}) where V<:AbstractVariableRef
   @ JuMP ~/.julia/packages/JuMP/6RAQ9/src/nlp_expr.jl:95
  GenericNonlinearExpr{V}(::Symbol, Any...) where V<:AbstractVariableRef
   @ JuMP ~/.julia/packages/JuMP/6RAQ9/src/nlp_expr.jl:84

Stacktrace:
 [1] oneunit(::Type{NonlinearExpr})
   @ Base ./number.jl:372
 [2] top-level scope
   @ REPL[23]:1

```

This happens because you can’t call `inv` on a matrix of nonlinear expressions, but we don’t catch this particular error so bad things happen. I’ll see if we can fix this.

There’s an easy fix for your problem. Instead of writing `inv(A) * x = blah`, do `A * blah = x`:

```julia
N = 3
using JuMP
model = Model()
@variable(model, x[1:4N])
@objective(model, Min, sum(x)^2)
aVal(x::Vector) = [x[1] x[2]; x[3] x[4]]
@variable(model, blah[1:2, 1:N])
for i in 1:N
    @constraint(model, aVal(x[(i-1)*4+1:4*i]) * blah .== x[(i-1)*4+1:4*i])
end

```

Note that in most cases, whether you use JuMP or regular Julia, you almost _never_ want to call `inv(::Matrix)`. There is almost always a better way of solving the problem.

---

<div class="post-metadata">

**Author:** ![lukebhan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lukebhan/32/212671_2.png) [@lukebhan](https://discourse.julialang.org/u/lukebhan)\
**Post date:** [October 15, 2024, 10:30pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353/3 "2024-10-15T22:30:01Z")

</div>

Hi @odow  
Thanks so much for your help and that is the exact error I am getting! So the issue is not that simple (sorry for not being clear). Namely, my expression is of the form x\_{k+1} = A(x\_k) \* x\_k + B(x\_k) \* x\_k + C(x\_k) where A, B have different types of inversion calls in them. Is there anyway to handle this? IE, my syntax really is something like:

```julia
for i in 1:N
    @constraint(model, x[i*4+1:4*i] = inv(aVal( x[(i-1)*4+1:4*i)])) * x[(i-1)*4+1:4*i)] +inv(bVal( x[(i-1)*4+1:4*i)]))* x[(i-1)*4+1:4*i)] + C(x[(i-1)*4+1:4*i)])])
end

```

I know this is a challenging expression, but I don’t think there is an easy way to fully write it out. Perhaps I can just write out the inverse operation myself since the dimension is static? Any other ideas?

---

<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 15, 2024, 10:40pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353/4 "2024-10-15T22:40:10Z")

</div>

Add more temporary variables:

```Julia
@variable(model, a_inv_x[1:2, 1:N])
@variable(model, b_inv_x[1:2, 1:N])
for i in 1:N
    x_i = x[4(i-1).+(1:4)]
    @constraint(model, aVal(x_i) * a_inv_x .== x_i)
    @constraint(model, bVal(x_i) * b_inv_x .== x_i)
    @constraint(model, x[4(i).+(1:4)] .== a_inv_x + b_inv_x + C(x_i))
end

```

---

<div class="post-metadata">

**Author:** ![lukebhan](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/lukebhan/32/212671_2.png) [@lukebhan](https://discourse.julialang.org/u/lukebhan)\
**Post date:** [October 15, 2024, 10:46pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353/5 "2024-10-15T22:46:15Z")

</div>

Ah, I see this is a nice trick, I did not realized. Thank you for your help!

---

<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 15, 2024, 11:17pm UTC](https://discourse.julialang.org/t/question-about-nonlinear-expressions-in-jump/121353/6 "2024-10-15T23:17:21Z")

</div>

No worries. Let me know if you have other questions
