# Can I set the default operation of a sparse Matrix to not store zeros?

I am building a sparse matrix `II`, however, when I assign some of its elements by zeros they are being stored with zero values unless I use `dropzeros(II)`.

1- Why using `sparse(II)` below not dropping zeros from II?
2- Is there a way to set (as default) at the first of my code that assigning zeros will not be stored into `II`?

``````II=sparse([1 0;1 1;1 1;1 1;1 1])
julia> II=sparse([1 0;1 1;1 1;1 1;1 1])
5×2 SparseMatrixCSC{Int64, Int64} with 9 stored entries:
1  ⋅
1  1
1  1
1  1
1  1
II[1:2,1]=sparse([0 0]);
julia> II
5×2 SparseMatrixCSC{Int64, Int64} with 9 stored entries:
0  ⋅
0  1
1  1
1  1
1  1
julia> sparse(II)
5×2 SparseMatrixCSC{Int64, Int64} with 9 stored entries:
0  ⋅
0  1
1  1
1  1
1  1
julia> dropzeros(II)
5×2 SparseMatrixCSC{Int64, Int64} with 7 stored entries:
⋅  ⋅
⋅  1
1  1
1  1
1  1
``````

Because you might change them later, i.e. it could be intentional?

Not a real answer, but you could filter them out beforehand?

1 Like

This is because I have a `for loop` and inside it I change the value of `II` and then calculate `X = A \II`. So, I want to avoid using `dropzeros(II)` in the loop.

``````for i:11000
# change in II
II = dropzeros(II)
X = A \II
end
``````

Note that you should do `dropzeros!(II)` and not `II=dropzeros(II)`. In any case, this is not advisable if performance is a concern.
The real reason is that removing/inserting a single entry in `SparseArrayCSC` is very slow (O(n)) where `n` is the number of nonzeros. So that loop would be reeeally slow (O(n^2)). True, there is an overhead in `dropzeros!` for finding where the new zero is, but it would still be O(n^2) without that. Do you really need remove it? It’s probably faster by just setting it to zero.

1 Like

Generally yes, but of course it can depend on many things. I would benchmark to be sure.

1 Like

well, constructing the sparse matrix would be also slow (possibly slower!), so I wouldn’t advise that. Note that `dropzeros!` would not be needed in this case. But it’s really easy to benchmark, just use the `BenchmarkTools` package with the `@btime` macro. e.g.

``````julia> @btime \$A \ \$II

julia> @btime sparse(\$A) \ sparse(\$II)
``````

etc

That’s because the input in that case was already a sparse matrix. When the input is a dense array, it will drop the zeros on construction.

``````julia> sparse([0,0,1])
3-element SparseVector{Int64, Int64} with 1 stored entry:
[3]  =  1
``````
1 Like

In general, constructing sparse matrices element-by-element with `A[i,j] = val` is extremely slow. If you want to construct matrices element-by-element, use the `sparse(I,J,V)` constructor.

(Changing entries of a sparse matrix without changing the sparsity pattern is fast, though.)

3 Likes