Allocating column of sparseArrays adds explicit zeros

I’m not sure if this is a bug or a feature but copying a sparse vector into a column of a sparse matrix keeps (or rather adds) some of the zeros explicitly:

 julia> using SparseArrays
 julia> m=sparse([[0,1,2,0,0] [0,3,0,4,0]])
5×2 SparseMatrixCSC{Int64,Int64} with 4 stored entries:
  [2, 1]  =  1
  [3, 1]  =  2
  [2, 2]  =  3
  [4, 2]  =  4

julia> v=sparse([1,2,0,0,0])
5-element SparseVector{Int64,Int64} with 2 stored entries:
  [1]  =  1
  [2]  =  2

julia> m[:,1]=v
5-element SparseVector{Int64,Int64} with 2 stored entries:
  [1]  =  1
  [2]  =  2

julia> m
5×2 SparseMatrixCSC{Int64,Int64} with 5 stored entries:
  [1, 1]  =  1
  [2, 1]  =  2
  [3, 1]  =  0 <-----
  [2, 2]  =  3
  [4, 2]  =  4

julia> findnz(m)
([1, 2, 3, 2, 4], [1, 1, 1, 2, 2], [1, 2, 0, 3, 4])

I understand explicitly allocating a particular entry of the matrix to 0 does just that, but here the right hand side is a sparse vector, so I don’t get why this is happening.

It didn’t allocate an explicit zero, it just chose not to drop the stored entry (that was there from the beginning). Use dropzeros! to drop eventual stored zeros.

1 Like

I know about dropzeros, but the point is that it was not explicitly stored in v, so I wouldn’t say it was there from the beginning ! Besides, there were three zeros in v, and only one shows up in m so it’s definitely a strange behaviour don’t you think ?

Oh, I see, that’s because the 3 that was already there is replaced by 0 and not dropped ?

Yes.

I find this behavior surprising. Since assignment has to handle allocating new elements, it seems odd that it wouldn’t also deallocate elements when appropriate.

I do find this surprising too, at least as a default behavior, whenever I write A=B I’d expect A and B to be then, well, pretty much identical.

Rearranging the sparsity structure is quite costly. If you are iteratively updating a matrix using a loop, doing this for each element would be very expensive. Better to have it performed explicitly (eg when you are done updating).

Sure. My point is, it already seemed to be rearranging the sparsity structure by allocating new elements. So I guess it’s just doing the minimal necessary restructuring (?).