Addition/Subtraction operations on sparse arrays

If I have a sparse array, is there a way to only broadcast operations onto the non-zero values in that array? I find myself needing this operation quite often.

A broadcast will obviously perform the operation on every element, including the zero elements as such:

using SparseArrays
a = sparse([2], [2], [1])

2×2 SparseMatrixCSC{Int64, Int64} with 1 stored entry:
⋅ ⋅
⋅ 1

a .- 2

2×2 SparseMatrixCSC{Int64, Int64} with 4 stored entries:
-2 -2
-2 -1

What if instead I wanted to ignore the non-zero elements in the broadcast? Is there some sort of sparsebroadcast mechanism? Something like:

sparsebroadcast(-, a, 2)

2×2 SparseMatrixCSC{Int64, Int64} with 1 stored entry:
⋅ ⋅
⋅ -1

TLDR is that this would require a different type, since SparseMatrixCSC only allows 0 as the sparse element. This is because for linear algebra applications (ie matrix multiplication etc) knowing that 0*x=0 is what allows the operations to be efficient.

I think broadcasting checks whether the function maps zero to zero, and if so, the result is sparse. Subtracting 2 doesn’t obey that. You can easily write a function which manipulates only the nonzero values, if for some reason this makes sense:

julia> broadcast(x -> 100x, a)
2×2 SparseMatrixCSC{Float64, Int64} with 1 stored entry:
  ⋅    ⋅ 
  ⋅   4.64159

julia> sparsemap(f, x::SparseMatrixCSC) = SparseMatrixCSC(x.m, x.n, x.colptr, x.rowval, map(f, x.nzval));

julia> sparsemap(x -> x + 100, a)
2×2 SparseMatrixCSC{Int64, Int64} with 1 stored entry:
 ⋅    ⋅
 ⋅  101
1 Like

Thanks, that’s exactly what I was looking for.

The reason I’m looking for this is because I’m implementing something in the form a ./ (b .+ c) where a and b are sparse and c is a scalar, dense vector, or dense matrix. So skipping addition operations in the denominator can be a big savings because they are ignored in the division anyway.