@@ -11,6 +11,54 @@ function DerivableInterfaces.interface(::Type{<:AbstractSparseArray})
11
11
return SparseArrayInterface ()
12
12
end
13
13
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
+
14
62
using DerivableInterfaces: @derive
15
63
16
64
# TODO : These need to be loaded since `AbstractArrayOps`
@@ -20,12 +68,30 @@ using DerivableInterfaces: @derive
20
68
using ArrayLayouts: ArrayLayouts
21
69
using LinearAlgebra: LinearAlgebra
22
70
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
29
95
30
96
using DerivableInterfaces. Concatenate: concatenate
31
97
# We overload `Base._cat` instead of `Base.cat` since it
@@ -35,7 +101,12 @@ function Base._cat(dims, a::AnyAbstractSparseArray...)
35
101
return concatenate (dims, a... )
36
102
end
37
103
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.
38
108
function map_stored (f, a:: AnyAbstractSparseArray )
109
+ iszero (storedlength (a)) && return a
39
110
kvs = storedpairs (a)
40
111
# `collect` to convert to `Vector`, since otherwise
41
112
# if it stays as `Dictionary` we might hit issues like
52
123
53
124
using Adapt: adapt
54
125
function 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.
55
130
a′ = map_stored (adapt (Array), a)
56
131
return @invoke Base. print_array (io:: typeof (io), a′:: AbstractArray{<:Any,ndims(a)} )
57
132
end
@@ -75,27 +150,30 @@ from the input indices.
75
150
This constructor does not take ownership of the supplied storage, and will result in an
76
151
independent container.
77
152
"""
78
- sparse (:: Union{AbstractDict,AbstractDictionary} , dims... ; kwargs ... )
153
+ sparse (:: Union{AbstractDict,AbstractDictionary} , dims... )
79
154
80
155
const AbstractDictOrDictionary = Union{AbstractDict,AbstractDictionary}
81
156
# 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) )
84
159
for (i, v) in pairs (storage)
85
160
A[i] = v
86
161
end
87
162
return A
88
163
end
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)
91
169
end
92
170
# Determine the size automatically.
93
- function sparse (storage:: AbstractDictOrDictionary ; kwargs ... )
171
+ function sparse (storage:: AbstractDictOrDictionary )
94
172
dims = ntuple (Returns (0 ), length (keytype (storage)))
95
173
for I in keys (storage)
96
174
dims = map (max, dims, Tuple (I))
97
175
end
98
- return sparse (storage, dims; kwargs ... )
176
+ return sparse (storage, dims)
99
177
end
100
178
101
179
using Random: Random, AbstractRNG, default_rng
@@ -107,12 +185,18 @@ Create an empty size `dims` sparse array.
107
185
The optional `T` argument specifies the element type, which defaults to `Float64`.
108
186
""" sparsezeros
109
187
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))
112
196
end
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)
116
200
117
201
@doc """
118
202
sparserand([rng], [T::Type], dims; density::Real=0.5, randfun::Function=rand) -> A::SparseArrayDOK{T}
0 commit comments