SparseArrays.jl icon indicating copy to clipboard operation
SparseArrays.jl copied to clipboard

SparseArrays: calling sparsevec on a sparse matrix is not a sparse vector

Open jessymilare opened this issue 4 years ago • 3 comments

Julia is not detecting reshaped sparse arrays as sparse. This has a wierd consequence when trying to create a sparse vector from a sparse matrix.

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

julia> v = sparsevec(D)
16-element reshape(::SparseMatrixCSC{Int64,Int64}, 16) with eltype Int64:
 1
 0
 0
 0
 0
 1
 0
 0
 0
 0
 1
 0
 0
 0
 0
 1

julia> issparse(v)
false

julia> findnz(v)
ERROR: MethodError: no method matching findnz(::Base.ReshapedArray{Int64,1,SparseMatrixCSC{Int64,Int64},Tuple{Base.MultiplicativeInverses.SignedMultiplicativeInverse{Int64}}})
Closest candidates are:
  findnz(::SparseArrays.AbstractSparseMatrixCSC{Tv,Ti}) where {Tv, Ti} at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\SparseArrays\src\sparsematrix.jl:1453
  findnz(::SparseVector{Tv,Ti}) where {Tv, Ti} at C:\buildbot\worker\package_win64\build\usr\share\julia\stdlib\v1.5\SparseArrays\src\sparsevector.jl:735
Stacktrace:
 [1] top-level scope at REPL[116]:1

jessymilare avatar Feb 11 '21 20:02 jessymilare

I think the best way to fix this would be to add a ReshapedSparseArray <: AbstractSparseArray wrapper type. This type could then be used not only for sparsevec but also for reshapeing sparse arrays in general.

sostock avatar Feb 12 '21 10:02 sostock

Maybe the sparsevec definition could be changed to something like

sparsevec(a::AbstractSparseArray) = sparsevec(vec(a))

?

barucden avatar Feb 12 '21 13:02 barucden

That would be a simple solution, but seems inefficient. It would also create a completely new array that shares no memory with the original one, in contrast to the current behavior where modifying the new array will also modify the old one.

sostock avatar Feb 12 '21 13:02 sostock