How to add a dense and a sparse vector and get a dense vector as result

Hello,
I’d like to add a sparse vector and a dense one and get a dense vector as result.

S=SparseVector(11,[1;11],[1;1])
D=ones(11)
display(S+D)
D+S

In both cases I get an 11-element SparseVector with 11 stored entries.
How can I improve this?

I’m not completely sure what you’d like here, but I might suggest

using SparseArrays
A = sparse(rand(100))
B = rand(100)
pos,vals = findnz(A)
@simd for i = 1:length(pos)
  @inbounds B[pos[i]] = vals[i]
end

Now, I don’t know if the addition operator between dense and sparse arrays could already do some of the obtaining elements and adding them to the dense elements. But the general strategy of finding elements with the findnz function could work here.

To use this on matrices, it should work similarly.

That looks like an awful lot of code for an addition of two vectors. +(::Vector, ::SparseVector) should just do the right thing imo.

2 Likes

You can call Array on the result to convert it to dense. I’m not well-versed in the sparse arrays ecosystem, so I’m not sure what the rationale is for dense + sparse returning sparse.

1 Like

+(D,S) returns a SparseVector too :slightly_frowning_face:

Yeah, +(a, b) is just another way to write a + b. I was just agreeing with you that this is unexpected behaviour.

Another workaround is to store the result directly in-place:

julia> R = similar(D);

julia> @. R = D + S;

julia> R
11-element Vector{Float64}:
 2.0
 1.0
⋮

I’m not an expert on this but I think the reason for this behavior is because the addition falls back to broadcasted addition, and sparse array broadcasting has to deal with arbitrarily complex expressions (eg 2 .* D .* S .+ 3, etc…) and also be type stable (return type doesn’t depend on the values of the arguments) so its not always trivial or maybe even possible to choose the “best” return type. It does seem though than in an expression involving only +/-'s, as soon as at least one argment is dense, the result should be dense. Maybe worth filing a Issue.

4 Likes

I think this is related to Full array minus spares vector gives sparse array as output · Issue #36988 · JuliaLang/julia · GitHub

1 Like