How to produce sparse array with conditional array comprehension

When creating variable or constraint containers in JuMP, one can use conditionals and a sparse array is produced, where the entries that do not met the conditions are left empty. For example:

typeof(@variable(model, [i in 1:10, j in 1:10; i != j]))
# JuMP.Containers.SparseAxisArray{VariableRef, 2, Tuple{Int64, Int64}}

Nevertheless, in base Julia:

typeof([(i, j) for i in 1:10, j in 1:10 if i != j])
# Vector{Tuple{Int64, Int64}} instead of sparse matrix

Is there a way to create sparse arrays using conditionals as above?

Your example is not particularly sparse, but a hacky solution could be:

sparse((getindex.(d,i) for i in 1:3 for d in [[(i,j, 2.0*i) for i in 1:100 for j in 1:100 if i==2j]])...)

I changed everything slightly here to get something sparse and not all Int.

2 Likes

Hi @juan_hb, welcome to the forum.

The JuMP.Containers.SparseAxisArray is a type specific to JuMP, but it isn’t restricted to holding variables. You can do:

julia> using JuMP

julia> Containers.@container([i in 1:10, j in 1:10; i != j], (i, j))
JuMP.Containers.SparseAxisArray{Tuple{Int64, Int64}, 2, Tuple{Int64, Int64}} with 90 entries:
  [1, 2 ]  =  (1, 2)

What are you trying to achieve? Do you mean you want a SparseArrays.SparseMatrixCSC instead?

1 Like

I do not particularly want to store the values efficiently, what I want is to create a structure that reminds entries where there shouldn’t be any values. Maybe something like Matrix{Union(MyType, Nothing)} and storing nothing in those entries would be more adequate?

Thank you! I was thinking of something similar to that but that’s more concise

what I want is to create a structure that reminds entries where there shouldn’t be any values

Why do you need this, specifically? What are you trying to achieve?

See also: Containers · JuMP

I wanted to create containers of variables and constraints capable of being appended rows to iteratively solve a problem increasing one by one the units of time.

I was considering

l = [s != k ? @variable(model, Bin) : nothing for s in 1:S, k in 1:S, _ in 1:T-1]

l = cat(l, [s != k ? @variable(model, Bin) : nothing for s in 1:S, k in 1:S], dims=3)

but I found it not very elegant