From 6e65672236b77e4f0a57bbf151df1abf429ea9c8 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Fri, 7 Mar 2025 17:41:18 -0500 Subject: [PATCH 1/3] Fix `isstored` with trailing singletons, vector show --- Project.toml | 2 +- src/abstractsparsearray.jl | 4 ++-- src/abstractsparsearrayinterface.jl | 12 +++++++++++- src/sparsearraydok.jl | 2 +- 4 files changed, 15 insertions(+), 5 deletions(-) diff --git a/Project.toml b/Project.toml index f7130fe..26b8341 100644 --- a/Project.toml +++ b/Project.toml @@ -1,7 +1,7 @@ name = "SparseArraysBase" uuid = "0d5efcca-f356-4864-8770-e1ed8d78f208" authors = ["ITensor developers and contributors"] -version = "0.4.0" +version = "0.4.1" [deps] Accessors = "7d9f7c33-5ae7-4f3b-8dc6-eff91059b697" diff --git a/src/abstractsparsearray.jl b/src/abstractsparsearray.jl index fcf79a2..ecb56bf 100644 --- a/src/abstractsparsearray.jl +++ b/src/abstractsparsearray.jl @@ -28,9 +28,9 @@ using LinearAlgebra: LinearAlgebra @derive AnyAbstractSparseArray AbstractArrayOps function Base.replace_in_print_matrix( - A::AnyAbstractSparseArray{<:Any,2}, i::Integer, j::Integer, s::AbstractString + a::AnyAbstractSparseVecOrMat, i::Integer, j::Integer, s::AbstractString ) - return isstored(A, CartesianIndex(i, j)) ? s : Base.replace_with_centered_mark(s) + return isstored(a, i, j) ? s : Base.replace_with_centered_mark(s) end # Special-purpose constructors diff --git a/src/abstractsparsearrayinterface.jl b/src/abstractsparsearrayinterface.jl index e9d6c40..9e3d8bb 100644 --- a/src/abstractsparsearrayinterface.jl +++ b/src/abstractsparsearrayinterface.jl @@ -34,7 +34,17 @@ end # Minimal interface for `SparseArrayInterface`. # Fallbacks for dense/non-sparse arrays. -@interface ::AbstractArrayInterface isstored(a::AbstractArray, I::Int...) = true +@interface ::AbstractArrayInterface function isstored( + a::AbstractArray{<:Any,N}, I::Vararg{Int,N} +) where {N} + @boundscheck checkbounds(a, I...) + return true +end +@interface ::AbstractArrayInterface function isstored(a::AbstractArray, I::Int...) + @boundscheck checkbounds(a, I...) + I′ = ntuple(i -> I[i], ndims(a)) + return isstored(a, I′...) +end @interface ::AbstractArrayInterface eachstoredindex(a::AbstractArray) = eachindex(a) @interface ::AbstractArrayInterface getstoredindex(a::AbstractArray, I::Int...) = getindex(a, I...) diff --git a/src/sparsearraydok.jl b/src/sparsearraydok.jl index 2fcb138..1f373f0 100644 --- a/src/sparsearraydok.jl +++ b/src/sparsearraydok.jl @@ -73,7 +73,7 @@ storage(a::SparseArrayDOK) = a.storage Base.size(a::SparseArrayDOK) = a.size storedvalues(a::SparseArrayDOK) = values(storage(a)) -function isstored(a::SparseArrayDOK, I::Int...) +function isstored(a::SparseArrayDOK{<:Any,N}, I::Vararg{Int,N}) where {N} return CartesianIndex(I) in keys(storage(a)) end function eachstoredindex(a::SparseArrayDOK) From d9535fc4f7b1ddc12217efa3c429463b5f645ee8 Mon Sep 17 00:00:00 2001 From: mtfishman Date: Sat, 8 Mar 2025 09:03:03 -0500 Subject: [PATCH 2/3] Better fix, add tests --- src/abstractsparsearrayinterface.jl | 17 +++++++++++++++-- src/sparsearraydok.jl | 4 ++-- test/test_basics.jl | 3 +++ test/test_sparsearraydok.jl | 4 ++++ 4 files changed, 24 insertions(+), 4 deletions(-) diff --git a/src/abstractsparsearrayinterface.jl b/src/abstractsparsearrayinterface.jl index 9e3d8bb..606cf2e 100644 --- a/src/abstractsparsearrayinterface.jl +++ b/src/abstractsparsearrayinterface.jl @@ -1,3 +1,4 @@ +using Base: @_propagate_inbounds_meta using DerivableInterfaces: DerivableInterfaces, @derive, @interface, AbstractArrayInterface # This is to bring `ArrayLayouts.zero!` into the namespace @@ -37,13 +38,19 @@ end @interface ::AbstractArrayInterface function isstored( a::AbstractArray{<:Any,N}, I::Vararg{Int,N} ) where {N} + @_propagate_inbounds_meta @boundscheck checkbounds(a, I...) return true end -@interface ::AbstractArrayInterface function isstored(a::AbstractArray, I::Int...) +@interface interface::AbstractArrayInterface function isstored(a::AbstractArray, I::Int) + @_propagate_inbounds_meta + return @interface interface isstored(a, Tuple(CartesianIndices(a)[I])...) +end +@interface interface::AbstractArrayInterface function isstored(a::AbstractArray, I::Int...) + @_propagate_inbounds_meta @boundscheck checkbounds(a, I...) I′ = ntuple(i -> I[i], ndims(a)) - return isstored(a, I′...) + return @inbounds @interface interface isstored(a, I′...) end @interface ::AbstractArrayInterface eachstoredindex(a::AbstractArray) = eachindex(a) @interface ::AbstractArrayInterface getstoredindex(a::AbstractArray, I::Int...) = @@ -163,6 +170,12 @@ function Base.setindex!(a::StoredValues, value, I::Int) return setstoredindex!(a.array, value, a.storedindices[I]) end +@interface ::AbstractSparseArrayInterface function isstored( + a::AbstractArray{<:Any,N}, I::Vararg{Int,N} +) where {N} + return CartesianIndex(I) in eachstoredindex(a) +end + @interface ::AbstractSparseArrayInterface storedvalues(a::AbstractArray) = StoredValues(a) @interface ::AbstractSparseArrayInterface function eachstoredindex( diff --git a/src/sparsearraydok.jl b/src/sparsearraydok.jl index 1f373f0..9d33175 100644 --- a/src/sparsearraydok.jl +++ b/src/sparsearraydok.jl @@ -73,8 +73,8 @@ storage(a::SparseArrayDOK) = a.storage Base.size(a::SparseArrayDOK) = a.size storedvalues(a::SparseArrayDOK) = values(storage(a)) -function isstored(a::SparseArrayDOK{<:Any,N}, I::Vararg{Int,N}) where {N} - return CartesianIndex(I) in keys(storage(a)) +function isstored(a::SparseArrayDOK, I::Int...) + return @interface interface(a) isstored(a, I...) end function eachstoredindex(a::SparseArrayDOK) return keys(storage(a)) diff --git a/test/test_basics.jl b/test/test_basics.jl index d434504..3aed922 100644 --- a/test/test_basics.jl +++ b/test/test_basics.jl @@ -26,6 +26,9 @@ arrayts = (Array, JLArray) for indexstyle in (IndexLinear(), IndexCartesian()) for I in eachindex(indexstyle, a) @test isstored(a, I) + if indexstyle == IndexCartesian() + @test isstored(a, Tuple(I)..., 1) + end end end @test eachstoredindex(a) == eachindex(a) diff --git a/test/test_sparsearraydok.jl b/test/test_sparsearraydok.jl index 4e50982..6616a4c 100644 --- a/test/test_sparsearraydok.jl +++ b/test/test_sparsearraydok.jl @@ -210,6 +210,10 @@ arrayts = (Array,) a[1, 2] = 12 @test sprint(show, "text/plain", a) == "$(summary(a)):\n ⋅ $(eltype(a)(12))\n ⋅ ⋅ " + + a = SparseArrayDOK{elt}(undef, 2) + a[1] = 1 + @test sprint(show, "text/plain", a) == "$(summary(a)):\n $(eltype(a)(1))\n ⋅ " end # Regression test for: From 27294ccae1a83069350b588150cf78795c9f160f Mon Sep 17 00:00:00 2001 From: mtfishman Date: Sat, 8 Mar 2025 09:13:46 -0500 Subject: [PATCH 3/3] Fix tests --- src/sparsearraydok.jl | 1 + 1 file changed, 1 insertion(+) diff --git a/src/sparsearraydok.jl b/src/sparsearraydok.jl index 9d33175..9f72bdb 100644 --- a/src/sparsearraydok.jl +++ b/src/sparsearraydok.jl @@ -1,4 +1,5 @@ using Accessors: @set +using DerivableInterfaces: @interface, interface using Dictionaries: Dictionary, IndexError, set! function getzero(a::AbstractArray{<:Any,N}, I::Vararg{Int,N}) where {N}