Creating an array of symmetric matrix variables in `JuMP`

Dear All,

I am trying to create an array of symmetric matrix variables in JuMP, i.e., an array of matrix variables X_i\in\mathbf{S}^n for i\in\{1,2,\ldots,N\}. If I had only one symmetric matrix variable X\in\mathbf{S}^n, I could create it in JuMP using

method 1: @variable(model, X[1:n, 1:n], Symmetric)

and if I had regular matrix variables X_i\in\mathbf{R}^{n \times n} for i\in\{1,2,\ldots,N\}, then I could do:

method 2: @variable(model, X[1:n, 1:n, 1:N]).

Is there any command where I can enforce symmetry on each X[:,:,i] in method 2, or any way to extend method 1 to an array of matrices? I could individually impose the symmetry constraint X_i[j,k]=X_i[k,j] for matrix indices j,k for every X_i, but I am wondering if there is any other way.

I will very much appreciate any tips/suggestion!

2 Likes

Is there any command

Not directly. See Broadcasting variables constrained on creation · Issue #2148 · jump-dev/JuMP.jl · GitHub

A good thing to remember is that you aren’t limited by the available JuMP syntax. You can create new data structures using Julia:

julia> using JuMP

julia> n, N = 2, 3
(2, 3)

julia> model = Model()
A JuMP Model
Feasibility problem with:
Variables: 0
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.

julia> X = model[:X] = reshape(
           hcat([
               @variable(model, [1:n, 1:n], Symmetric, base_name = "X$(i)")
               for i in 1:N
           ]...),
           n, n, N,
       )
2×2×3 Array{VariableRef, 3}:
[:, :, 1] =
 X1[1,1]  X1[1,2]
 X1[1,2]  X1[2,2]

[:, :, 2] =
 X2[1,1]  X2[1,2]
 X2[1,2]  X2[2,2]

[:, :, 3] =
 X3[1,1]  X3[1,2]
 X3[1,2]  X3[2,2]

julia> model
A JuMP Model
Feasibility problem with:
Variables: 9
Model mode: AUTOMATIC
CachingOptimizer state: NO_OPTIMIZER
Solver name: No optimizer attached.
Names registered in the model: X

julia> model[:X]
2×2×3 Array{VariableRef, 3}:
[:, :, 1] =
 X1[1,1]  X1[1,2]
 X1[1,2]  X1[2,2]

[:, :, 2] =
 X2[1,1]  X2[1,2]
 X2[1,2]  X2[2,2]

[:, :, 3] =
 X3[1,1]  X3[1,2]
 X3[1,2]  X3[2,2]
1 Like

This is a great solution, thanks so much @odow !