Can JuMP.jl create a sparse array variable that can be used as a full matrix?

Hi all
Recently, I have encountered some problems in optimizing code speed. I guess it is because I always create dense array variables

I want to create a 4x4 array variables, but it only has a value at the index (1, 2), (2, 1), (2, 3), (3, 2) and the rest is 0. The current practice is to use the following code:

model = Model(Gurobi.Optimizer)
@variable(model, x[1:4, 1:4])
@constraints(model, begin
    x[1, 2] == 0
    x[2, 1] == 0
    x[2, 3] == 0
    x[3, 2] == 0
end)

When the array size is very small, this will not have any adverse impact, but when the array size is very large, many unnecessary variables and constraints will be created. I guess this reduces the speed of model construction and solver solving

What I want to achieve is to create a sparse array variable, but it can be used as a full matrix, including index, matrix multiplication and so on. It is as natural and convenient as MATLAB.

Thanks a lot !

1 Like

One option would be as follows:

julia> using JuMP

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 = zeros(AffExpr, 3, 3)
3×3 Matrix{AffExpr}:
 0  0  0
 0  0  0
 0  0  0

julia> x[1, 1] = @variable(model, base_name = "x[1, 1]")
x[1, 1]

julia> x[2, 2] = @variable(model, base_name = "x[2, 2]")
x[2, 2]

julia> x[1, 3] = @variable(model, base_name = "x[1, 3]")
x[1, 3]

julia> x[3, 1] = @variable(model, base_name = "x[3, 1]")
x[3, 1]

julia> x[3, 3] = @variable(model, base_name = "x[3, 3]")
x[3, 3]

julia> x
3×3 Matrix{AffExpr}:
 x[1, 1]  0        x[1, 3]
 0        x[2, 2]  0
 x[3, 1]  0        x[3, 3]

Another option is as follows

julia> using SparseArrays

julia> s = sparse([1, 3, 2, 1, 3], [1, 1, 2, 3, 3], @variable(model, y[1:5]))
3×3 SparseMatrixCSC{VariableRef, Int64} with 5 stored entries:
 y[1]  ⋅     y[4]
 ⋅     y[3]  ⋅
 y[2]  ⋅     y[5]

julia> Matrix(s)
3×3 Matrix{AffExpr}:
 y[1]  0     y[4]
 0     y[3]  0
 y[2]  0     y[5]
2 Likes

Thank you very much for your reply! The code you provided is very helpful.

On the basis of the solution you provided, I raised a new question. If you have time, I’d like to ask you for help!