Search code examples
juliasparse-matrix

Is it possible to reshape a sparse array in Julia?


I'm attempting to reshape a sparse array in Julia, but get errors while doing so. Is it even possible? And if so, how?

Some snapshots of frustration:

julia> A = sparse([1, 2, 3], [1, 2, 3], [1, 2, 3])
3×3 SparseMatrixCSC{Int64,Int64} with 3 stored entries:
  [1, 1]  =  1
  [2, 2]  =  2
  [3, 3]  =  3

julia> reshape(A, (5, 5))
ERROR: DimensionMismatch("parent has 9 elements, which is incompatible with size (5, 5)")
Stacktrace:
julia> A.m
3

julia> A.m = 4
ERROR: setfield! immutable struct of type SparseMatrixCSC cannot be changed
Stacktrace:
julia> J = Base.ReshapedArray(A, (4, 4), ())
4×4 reshape(::SparseMatrixCSC{Int64,Int64}, 4, 4) with eltype Int64:
 1  2    3     #undef
 0  0  #undef  #undef
 0  0  #undef  #undef
 0  0  #undef  #undef

julia> J[4, 4] = 4
ERROR: BoundsError: attempt to access 3×3 SparseMatrixCSC{Int64,Int64} at index [1, 6]
Stacktrace:

I also tried resize!(A, 4*4), but nothing seems to work. Again, any help would be hugely appreciated.

Edit: I should've been more clear, I want to resize the array specifically to add more elements outside the 3x3 range (in the example code). Like A[4, 4] = 1 doesn't currently work.


Solution

  • You can just create a new sparse array with

    julia> i, j, v = findnz(A)
    ([1, 2, 3], [1, 2, 3], [1, 2, 3])
    
    julia> sparse(i, j, v, 5, 5)
    5×5 SparseMatrixCSC{Int64, Int64} with 3 stored entries:
     1  ⋅  ⋅  ⋅  ⋅
     ⋅  2  ⋅  ⋅  ⋅
     ⋅  ⋅  3  ⋅  ⋅
     ⋅  ⋅  ⋅  ⋅  ⋅
     ⋅  ⋅  ⋅  ⋅  ⋅
    

    The inverse of sparse is findnz, which retrieves the inputs used to create the sparse array. See the docs.

    (Edit, just to note that my output is different from yours because I used Julia v1.6 (release candidate 1 or rc1 at the time of writing), which has this cool new show methods for sparse matrices.)