# Nonconvex and Matrix Variables

**URL:** https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056
**Category:** Optimization (Mathematical)
**Tags:** matrices, nonlinear
**Created:** [June 1, 2022, 1:29pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056 "2022-06-01T13:29:39Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![chupin](https://avatars.discourse-cdn.com/v4/letter/c/f07891/32.png) [@chupin](https://discourse.julialang.org/u/chupin)
#### Post date: [June 1, 2022, 1:29pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/1 "2022-06-01T13:29:39Z")

</div>

Is there any way to deal with matrix variables with Nonconvex lib ?  
I tried something like:

```julia
using Nonconvex
Nonconvex.@load Ipopt

f(x) = sqrt(x[2,2])
g(x, a, b) = (a*x[1,2] + b)^3 - x[2,1]

model = Model(f)
addvar!(model, [[0.0, 0.0],[0.0,0.0]], [[10.0, 10.0],[10.0,10.0]])
add_ineq_constraint!(model, x -> g(x, 2, 0))
add_ineq_constraint!(model, x -> g(x, -1, 1))

alg = IpoptAlg()
options = IpoptOptions(first_order = true, tol = 1e-7)
r = optimize(model, alg, [[1.0,1.0],[1.0, 1.0]], options = options)

```

but I got the following error:

```julia
Stacktrace:
 [1] getindex
   @ ./array.jl:862 [inlined]
 [2] g(x::Vector{Vector{Float64}}, a::Int64, b::Int64)
   @ Main ~/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:5
 [3] (::var"#1#2")(x::Vector{Vector{Float64}})
   @ Main ~/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:9
 [4] add_ineq_constraint!(m::Model{Vector{Any}}, f::var"#1#2", s::Float64) (repeats 2 times)
   @ NonconvexCore ~/.julia/packages/NonconvexCore/uZAVo/src/models/model.jl:160
 [5] top-level scope
   @ ~/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:9

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [June 1, 2022, 3:53pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/2 "2022-06-01T15:53:41Z")

</div>

> [@chupin](#):
>
> Is there any way to deal with matrix variables with Nonconvex lib ?

Just reshape them to/from vectors passing them as optimization parameters to/from Nonconvex.

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [June 1, 2022, 5:11pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/3 "2022-06-01T17:11:22Z")

</div>

> [@chupin](#):
>
> ```julia
> f(x) = sqrt(x[2,2])
> g(x, a, b) = (a*x[1,2] + b)^3 - x[2,1]
> 
> ```

Your decision variables are a vector of vectors so you need `x[1][2]` not `x[1,2]`. Nonconvex supports vectors of mostly arbitrary data structures as decision variables.

```julia
using Nonconvex
Nonconvex.@load Ipopt

f(x) = sqrt(x[2][2])
g(x, a, b) = (a*x[1][2] + b)^3 - x[2][1]

model = Model(f)
addvar!(model, [[1e-4, 1e-4],[1e-4,1e-4]], [[10.0, 10.0],[10.0,10.0]])
add_ineq_constraint!(model, x -> g(x, 2, 0))
add_ineq_constraint!(model, x -> g(x, -1, 1))

alg = IpoptAlg()
options = IpoptOptions(first_order = true, tol = 1e-7)
r = optimize(model, alg, [[1.0,1.0],[1.0, 1.0]], options = options)

```

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [June 1, 2022, 5:15pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/4 "2022-06-01T17:15:47Z")

</div>

> [@mohamed82008](#):
>
> Your decision variables are a vector of vectors

Oh, I didn’t notice this.

If @chupin actually wants a “matrix” variable, then I should remind them that Julia has actual 2d arrays — you don’t need `[[0.0, 0.0],[0.0,0.0]]` arrays-of-arrays as you would in Python.

---

<div class="post-metadata">

### Author: ![chupin](https://avatars.discourse-cdn.com/v4/letter/c/f07891/32.png) [@chupin](https://discourse.julialang.org/u/chupin)
#### Post date: [June 1, 2022, 7:25pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/5 "2022-06-01T19:25:35Z")

</div>

Thank you for your quick answers.  
In fact, I want Matrix variables because in my more complex code, I use the very usefull `ones`, `zeros`, `rand`, etc., that produce matrices.  
I tried to convert the toy example:

```julia
using Nonconvex
Nonconvex.@load Ipopt
f(x) = sqrt(x[2,2])
g(x, a, b) = (a*x[1,2] + b)^3 - x[2,1]

model = Model(f)
addvar!(model, [1e-4 1e-4 ; 1e-4 1e-4], [10.0 10.0 ; 10.0 10.0])
add_ineq_constraint!(model, x -> g(x, 2, 0))
add_ineq_constraint!(model, x -> g(x, -1, 1))

alg = IpoptAlg()
options = IpoptOptions(first_order = true, tol = 1e-7)
r = optimize(model, alg, [1.0 1.0 ; 1.0 1.0], options = options

```

but I got the error:

```julia
ERROR: LoadError: BoundsError: attempt to access 1-element Vector{Matrix{Float64}} at index [1, 2]
Stacktrace:
 [1] getindex
   @ ./array.jl:862 [inlined]
 [2] g(x::Vector{Matrix{Float64}}, a::Int64, b::Int64)
   @ Main ~/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:18
 [3] (::var"#1#2")(x::Vector{Matrix{Float64}})
   @ Main ~/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:22
 [4] add_ineq_constraint!(m::Model{Vector{Any}}, f::var"#1#2", s::Float64) (repeats 2 times)
   @ NonconvexCore ~/.julia/packages/NonconvexCore/uZAVo/src/models/model.jl:160
 [5] top-level scope
   @ ~/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:22
in expression starting at /home/mc/Nextcloud/Dauphine/OptiForm/Julia/Nonconvex/test.jl:22

```

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [June 2, 2022, 6:35am UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/6 "2022-06-02T06:35:37Z")

</div>

The decision variables `x` is always a vector of things. In your case, you are adding a single matrix decision variable. So to get it in the function you should use `x[1]`.

```julia
add_ineq_constraint!(model, x -> g(x[1], 2, 0))
add_ineq_constraint!(model, x -> g(x[1], -1, 1))

```

---

<div class="post-metadata">

### Author: ![chupin](https://avatars.discourse-cdn.com/v4/letter/c/f07891/32.png) [@chupin](https://discourse.julialang.org/u/chupin)
#### Post date: [June 2, 2022, 9:47am UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/7 "2022-06-02T09:47:12Z")

</div>

Thanks, but unfortunately, the following code gives a lot of errors (beginning with Zigote)

```julia
using Nonconvex
Nonconvex.@load Ipopt

f(x) = sqrt(x[2,2])
g(x, a, b) = (a*x[1,2] + b)^3 - x[2,1]

model = Model(f)
addvar!(model, [1e-4 1e-4 ; 1e-4 1e-4], [10.0 10.0 ; 10.0 10.0])
add_ineq_constraint!(model, x -> g(x[1], 2, 0))
add_ineq_constraint!(model, x -> g(x[1], -1, 1))

alg = IpoptAlg()
options = IpoptOptions(first_order = true, tol = 1e-7)
r = optimize(model, alg, [1.0 1.0 ; 1.0 1.0], options = options)

```

---

<div class="post-metadata">

### Author: ![chupin](https://avatars.discourse-cdn.com/v4/letter/c/f07891/32.png) [@chupin](https://discourse.julialang.org/u/chupin)
#### Post date: [June 2, 2022, 2:03pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/8 "2022-06-02T14:03:31Z")

</div>

That seems to be the best way. Thanks

---

<div class="post-metadata">

### Author: ![rtapia](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/rtapia/32/207390_2.png) [@rtapia](https://discourse.julialang.org/u/rtapia)
#### Post date: [March 11, 2024, 9:39pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/9 "2024-03-11T21:39:00Z")

</div>

were you able to find a working configuration? Would you mind posting as example?

---

<div class="post-metadata">

### Author: ![mohamed82008](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mohamed82008/32/18171_2.png) [@mohamed82008](https://discourse.julialang.org/u/mohamed82008)
#### Post date: [March 11, 2024, 11:20pm UTC](https://discourse.julialang.org/t/nonconvex-and-matrix-variables/82056/10 "2024-03-11T23:20:01Z")

</div>

This should work. Sorry for the late response!

```julia
using Nonconvex
Nonconvex.@load Ipopt

f(x) = sqrt(x[1][2,2])
g(x, a, b) = (a*x[1,2] + b)^3 - x[2,1]

model = Model(f)
addvar!(model, [1e-4 1e-4 ; 1e-4 1e-4], [10.0 10.0 ; 10.0 10.0])
add_ineq_constraint!(model, x -> g(x[1], 2, 0))
add_ineq_constraint!(model, x -> g(x[1], -1, 1))

alg = IpoptAlg()
options = IpoptOptions(first_order = true, tol = 1e-7)
r = optimize(model, alg, [[1.0 1.0 ; 1.0 1.0]], options = options)

```

The 2 changes I made were

```julia
f(x) = sqrt(x[1][2,2])

```

and

```julia
r = optimize(model, alg, [[1.0 1.0 ; 1.0 1.0]], options = options)

```
