@@ -11,6 +11,54 @@ function DerivableInterfaces.interface(::Type{<:AbstractSparseArray})
1111 return SparseArrayInterface ()
1212end
1313
14+ function Base. copy (a:: AnyAbstractSparseArray )
15+ return copyto! (similar (a), a)
16+ end
17+
18+ function similar_sparsearray (a:: AnyAbstractSparseArray , unstored:: Unstored )
19+ return SparseArrayDOK (unstored)
20+ end
21+ function similar_sparsearray (a:: AnyAbstractSparseArray , T:: Type , ax:: Tuple )
22+ return similar_sparsearray (a, Unstored (unstoredsimilar (unstored (a), T, ax)))
23+ end
24+ function similar_sparsearray (a:: AnyAbstractSparseArray , T:: Type )
25+ return similar_sparsearray (a, Unstored (unstoredsimilar (unstored (a), T)))
26+ end
27+ function similar_sparsearray (a:: AnyAbstractSparseArray , ax:: Tuple )
28+ return similar_sparsearray (a, Unstored (unstoredsimilar (unstored (a), ax)))
29+ end
30+ function similar_sparsearray (a:: AnyAbstractSparseArray )
31+ return similar_sparsearray (a, Unstored (unstored (a)))
32+ end
33+
34+ function Base. similar (a:: AnyAbstractSparseArray , unstored:: Unstored )
35+ return similar_sparsearray (a, unstored)
36+ end
37+ function Base. similar (a:: AnyAbstractSparseArray )
38+ return similar_sparsearray (a)
39+ end
40+ function Base. similar (a:: AnyAbstractSparseArray , T:: Type )
41+ return similar_sparsearray (a, T)
42+ end
43+ function Base. similar (a:: AnyAbstractSparseArray , ax:: Tuple )
44+ return similar_sparsearray (a, ax)
45+ end
46+ function Base. similar (a:: AnyAbstractSparseArray , T:: Type , ax:: Tuple )
47+ return similar_sparsearray (a, T, ax)
48+ end
49+ # Fix ambiguity error.
50+ function Base. similar (a:: AnyAbstractSparseArray , T:: Type , ax:: Tuple{Int,Vararg{Int}} )
51+ return similar_sparsearray (a, T, ax)
52+ end
53+ # Fix ambiguity error.
54+ function Base. similar (
55+ a:: AnyAbstractSparseArray ,
56+ T:: Type ,
57+ ax:: Tuple{Union{Integer,Base.OneTo},Vararg{Union{Integer,Base.OneTo}}} ,
58+ )
59+ return similar_sparsearray (a, T, ax)
60+ end
61+
1462using DerivableInterfaces: @derive
1563
1664# TODO : These need to be loaded since `AbstractArrayOps`
@@ -20,12 +68,30 @@ using DerivableInterfaces: @derive
2068using ArrayLayouts: ArrayLayouts
2169using LinearAlgebra: LinearAlgebra
2270
23- # DerivableInterfaces `Base.getindex`, `Base.setindex!`, etc.
24- # TODO : Define `AbstractMatrixOps` and overload for
25- # `AnyAbstractSparseMatrix` and `AnyAbstractSparseVector`,
26- # which is where matrix multiplication and factorizations
27- # should go.
28- @derive AnyAbstractSparseArray AbstractArrayOps
71+ @derive (T= AnyAbstractSparseArray,) begin
72+ Base. getindex (:: T , :: Any... )
73+ Base. getindex (:: T , :: Int... )
74+ Base. setindex! (:: T , :: Any , :: Any... )
75+ Base. setindex! (:: T , :: Any , :: Int... )
76+ Base. copy! (:: AbstractArray , :: T )
77+ Base. copyto! (:: AbstractArray , :: T )
78+ Base. map (:: Any , :: T... )
79+ Base. map! (:: Any , :: AbstractArray , :: T... )
80+ Base. mapreduce (:: Any , :: Any , :: T... ; kwargs... )
81+ Base. reduce (:: Any , :: T... ; kwargs... )
82+ Base. all (:: Function , :: T )
83+ Base. all (:: T )
84+ Base. iszero (:: T )
85+ Base. real (:: T )
86+ Base. fill! (:: T , :: Any )
87+ DerivableInterfaces. zero! (:: T )
88+ Base. zero (:: T )
89+ Base. permutedims! (:: Any , :: T , :: Any )
90+ Broadcast. BroadcastStyle (:: Type{<:T} )
91+ Base. copyto! (:: T , :: Broadcast.Broadcasted{Broadcast.DefaultArrayStyle{0}} )
92+ ArrayLayouts. MemoryLayout (:: Type{<:T} )
93+ LinearAlgebra. mul! (:: AbstractMatrix , :: T , :: T , :: Number , :: Number )
94+ end
2995
3096using DerivableInterfaces. Concatenate: concatenate
3197# We overload `Base._cat` instead of `Base.cat` since it
@@ -35,7 +101,12 @@ function Base._cat(dims, a::AnyAbstractSparseArray...)
35101 return concatenate (dims, a... )
36102end
37103
104+ # TODO : Use `map(WeakPreserving(f), a)` instead.
105+ # Currently that has trouble with type unstable maps, since
106+ # the element type becomes abstract and therefore the zero/unstored
107+ # values are not well defined.
38108function map_stored (f, a:: AnyAbstractSparseArray )
109+ iszero (storedlength (a)) && return a
39110 kvs = storedpairs (a)
40111 # `collect` to convert to `Vector`, since otherwise
41112 # if it stays as `Dictionary` we might hit issues like
52123
53124using Adapt: adapt
54125function Base. print_array (io:: IO , a:: AnyAbstractSparseArray )
126+ # TODO : Use `map(WeakPreserving(adapt(Array)), a)` instead.
127+ # Currently that has trouble with type unstable maps, since
128+ # the element type becomes abstract and therefore the zero/unstored
129+ # values are not well defined.
55130 a′ = map_stored (adapt (Array), a)
56131 return @invoke Base. print_array (io:: typeof (io), a′:: AbstractArray{<:Any,ndims(a)} )
57132end
@@ -75,27 +150,30 @@ from the input indices.
75150This constructor does not take ownership of the supplied storage, and will result in an
76151independent container.
77152"""
78- sparse (:: Union{AbstractDict,AbstractDictionary} , dims... ; kwargs ... )
153+ sparse (:: Union{AbstractDict,AbstractDictionary} , dims... )
79154
80155const AbstractDictOrDictionary = Union{AbstractDict,AbstractDictionary}
81156# checked constructor from data: use `setindex!` to validate/convert input
82- function sparse (storage:: AbstractDictOrDictionary , dims :: Dims ; kwargs ... )
83- A = SparseArrayDOK {valtype(storage)} (undef, dims; kwargs ... )
157+ function sparse (storage:: AbstractDictOrDictionary , unstored :: AbstractArray )
158+ A = SparseArrayDOK ( Unstored (unstored) )
84159 for (i, v) in pairs (storage)
85160 A[i] = v
86161 end
87162 return A
88163end
89- function sparse (storage:: AbstractDictOrDictionary , dims:: Int... ; kwargs... )
90- return sparse (storage, dims; kwargs... )
164+ function sparse (storage:: AbstractDictOrDictionary , ax:: Tuple )
165+ return sparse (storage, Zeros {valtype(storage)} (ax))
166+ end
167+ function sparse (storage:: AbstractDictOrDictionary , dims:: Int... )
168+ return sparse (storage, dims)
91169end
92170# Determine the size automatically.
93- function sparse (storage:: AbstractDictOrDictionary ; kwargs ... )
171+ function sparse (storage:: AbstractDictOrDictionary )
94172 dims = ntuple (Returns (0 ), length (keytype (storage)))
95173 for I in keys (storage)
96174 dims = map (max, dims, Tuple (I))
97175 end
98- return sparse (storage, dims; kwargs ... )
176+ return sparse (storage, dims)
99177end
100178
101179using Random: Random, AbstractRNG, default_rng
@@ -107,12 +185,18 @@ Create an empty size `dims` sparse array.
107185The optional `T` argument specifies the element type, which defaults to `Float64`.
108186""" sparsezeros
109187
110- function sparsezeros (:: Type{T} , dims:: Dims ; kwargs... ) where {T}
111- return SparseArrayDOK {T} (undef, dims; kwargs... )
188+ function sparsezeros (:: Type{T} , unstored:: AbstractArray{<:Any,N} ) where {T,N}
189+ return SparseArrayDOK {T,N} (Unstored (unstored))
190+ end
191+ function sparsezeros (unstored:: AbstractArray{T,N} ) where {T,N}
192+ return SparseArrayDOK {T,N} (Unstored (unstored))
193+ end
194+ function sparsezeros (:: Type{T} , dims:: Dims ) where {T}
195+ return sparsezeros (T, Zeros {T} (dims))
112196end
113- sparsezeros (:: Type{T} , dims:: Int... ; kwargs ... ) where {T} = sparsezeros (T, dims; kwargs ... )
114- sparsezeros (dims:: Dims ; kwargs ... ) = sparsezeros (Float64, dims; kwargs ... )
115- sparsezeros (dims:: Int... ; kwargs ... ) = sparsezeros (Float64, dims; kwargs ... )
197+ sparsezeros (:: Type{T} , dims:: Int... ) where {T} = sparsezeros (T, dims)
198+ sparsezeros (dims:: Dims ) = sparsezeros (Float64, dims)
199+ sparsezeros (dims:: Int... ) = sparsezeros (Float64, dims)
116200
117201@doc """
118202 sparserand([rng], [T::Type], dims; density::Real=0.5, randfun::Function=rand) -> A::SparseArrayDOK{T}
0 commit comments