From 55c32b5d9767fd897b008ccc8b753ef77ad42233 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Thu, 13 May 2021 17:22:54 +0100 Subject: [PATCH] Make issparse handle nested wrappers (#34308) --- NEWS.md | 2 +- stdlib/SparseArrays/src/abstractsparse.jl | 22 ++++++++++++---------- stdlib/SparseArrays/test/sparse.jl | 6 ++++++ 3 files changed, 19 insertions(+), 11 deletions(-) diff --git a/NEWS.md b/NEWS.md index eafec374d5a0e..d93e4d2d5f968 100644 --- a/NEWS.md +++ b/NEWS.md @@ -117,7 +117,7 @@ Standard library changes * new `sizehint!(::SparseMatrixCSC, ::Integer)` method ([#30676]). * `cholesky()` now fully preserves the user-specified permutation. ([#40560]) - +* `issparse` now applies consistently to all wrapper arrays, including nested, by checking `issparse` on the wrapped parent array ([#37644]). #### Dates diff --git a/stdlib/SparseArrays/src/abstractsparse.jl b/stdlib/SparseArrays/src/abstractsparse.jl index 3ea70f48b4a7e..86d6c4b3da56d 100644 --- a/stdlib/SparseArrays/src/abstractsparse.jl +++ b/stdlib/SparseArrays/src/abstractsparse.jl @@ -50,17 +50,19 @@ julia> issparse(Array(sv)) false ``` """ -issparse(A::AbstractArray) = false +function issparse(A::AbstractArray) + # Handle wrapper arrays: sparse if it is wrapping a sparse array. + # This gets compiled away during specialization. + p = parent(A) + if p === A + # have reached top of wrapping without finding a sparse array, assume it is not. + return false + else + return issparse(p) + end +end +issparse(A::DenseArray) = false issparse(S::AbstractSparseArray) = true -issparse(S::LinearAlgebra.Adjoint{<:Any,<:AbstractSparseArray}) = true -issparse(S::LinearAlgebra.Transpose{<:Any,<:AbstractSparseArray}) = true - -issparse(S::LinearAlgebra.Symmetric{<:Any,<:AbstractSparseMatrix}) = true -issparse(S::LinearAlgebra.Hermitian{<:Any,<:AbstractSparseMatrix}) = true -issparse(S::LinearAlgebra.LowerTriangular{<:Any,<:AbstractSparseMatrix}) = true -issparse(S::LinearAlgebra.UnitLowerTriangular{<:Any,<:AbstractSparseMatrix}) = true -issparse(S::LinearAlgebra.UpperTriangular{<:Any,<:AbstractSparseMatrix}) = true -issparse(S::LinearAlgebra.UnitUpperTriangular{<:Any,<:AbstractSparseMatrix}) = true indtype(S::AbstractSparseArray{<:Any,Ti}) where {Ti} = Ti diff --git a/stdlib/SparseArrays/test/sparse.jl b/stdlib/SparseArrays/test/sparse.jl index f2754ba5ade81..4c6ca81127129 100644 --- a/stdlib/SparseArrays/test/sparse.jl +++ b/stdlib/SparseArrays/test/sparse.jl @@ -2165,6 +2165,12 @@ end @test issparse(LinearAlgebra.UnitLowerTriangular(Array(m))) == false @test issparse(UpperTriangular(Array(m))) == false @test issparse(LinearAlgebra.UnitUpperTriangular(Array(m))) == false + @test issparse(Base.ReshapedArray(m, (20, 5), ())) + @test issparse(@view m[1:3, :]) + + # greater nesting + @test issparse(Symmetric(UpperTriangular(m))) + @test issparse(Symmetric(UpperTriangular(Array(m)))) == false end @testset "issparse for sparse vectors #34253" begin