Skip to content

Commit 5abd5f6

Browse files
authored
Handle Statistics and SparseArrays as extensions (#286)
* Handle Statistics and SparseArrays as extensions * review comments * clean-ip * add deprecation * error or load * Revert "error or load" This reverts commit 7c7a333.
1 parent 48f6157 commit 5abd5f6

File tree

5 files changed

+109
-81
lines changed

5 files changed

+109
-81
lines changed

Project.toml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,14 @@ Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c"
88
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
99
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
1010

11+
[weakdeps]
12+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
13+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
14+
15+
[extensions]
16+
FillArraysSparseArraysExt = "SparseArrays"
17+
FillArraysStatisticsExt = "Statistics"
18+
1119
[compat]
1220
Aqua = "0.5, 0.6"
1321
julia = "1.6"
@@ -16,8 +24,10 @@ julia = "1.6"
1624
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
1725
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
1826
ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
27+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
1928
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
29+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2030
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2131

2232
[targets]
23-
test = ["Aqua", "Test", "Base64", "ReverseDiff", "StaticArrays"]
33+
test = ["Aqua", "Test", "Base64", "ReverseDiff", "SparseArrays", "StaticArrays", "Statistics"]

ext/FillArraysSparseArraysExt.jl

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
module FillArraysSparseArraysExt
2+
3+
using SparseArrays
4+
import Base: convert, kron
5+
using FillArrays
6+
using FillArrays: RectDiagonalFill, RectOrDiagonalFill, ZerosVector, ZerosMatrix, getindex_value
7+
using LinearAlgebra
8+
9+
##################
10+
## Sparse arrays
11+
##################
12+
SparseVector{T}(Z::ZerosVector) where T = spzeros(T, length(Z))
13+
SparseVector{Tv,Ti}(Z::ZerosVector) where {Tv,Ti} = spzeros(Tv, Ti, length(Z))
14+
15+
convert(::Type{AbstractSparseVector}, Z::ZerosVector{T}) where T = spzeros(T, length(Z))
16+
convert(::Type{AbstractSparseVector{T}}, Z::ZerosVector) where T= spzeros(T, length(Z))
17+
18+
SparseMatrixCSC{T}(Z::ZerosMatrix) where T = spzeros(T, size(Z)...)
19+
SparseMatrixCSC{Tv,Ti}(Z::Zeros{T,2,Axes}) where {Tv,Ti<:Integer,T,Axes} = spzeros(Tv, Ti, size(Z)...)
20+
21+
convert(::Type{AbstractSparseMatrix}, Z::ZerosMatrix{T}) where T = spzeros(T, size(Z)...)
22+
convert(::Type{AbstractSparseMatrix{T}}, Z::ZerosMatrix) where T = spzeros(T, size(Z)...)
23+
24+
convert(::Type{AbstractSparseArray}, Z::Zeros{T}) where T = spzeros(T, size(Z)...)
25+
convert(::Type{AbstractSparseArray{Tv}}, Z::Zeros{T}) where {T,Tv} = spzeros(Tv, size(Z)...)
26+
convert(::Type{AbstractSparseArray{Tv,Ti}}, Z::Zeros{T}) where {T,Tv,Ti} = spzeros(Tv, Ti, size(Z)...)
27+
convert(::Type{AbstractSparseArray{Tv,Ti,N}}, Z::Zeros{T,N}) where {T,Tv,Ti,N} = spzeros(Tv, Ti, size(Z)...)
28+
29+
SparseMatrixCSC{Tv}(Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)
30+
# works around missing `speye`:
31+
SparseMatrixCSC{Tv,Ti}(Z::Eye{T}) where {T,Tv,Ti<:Integer} =
32+
convert(SparseMatrixCSC{Tv,Ti}, SparseMatrixCSC{Tv}(I, size(Z)...))
33+
34+
convert(::Type{AbstractSparseMatrix}, Z::Eye{T}) where {T} = SparseMatrixCSC{T}(I, size(Z)...)
35+
convert(::Type{AbstractSparseMatrix{Tv}}, Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)
36+
37+
convert(::Type{AbstractSparseArray}, Z::Eye{T}) where T = SparseMatrixCSC{T}(I, size(Z)...)
38+
convert(::Type{AbstractSparseArray{Tv}}, Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)
39+
40+
41+
convert(::Type{AbstractSparseArray{Tv,Ti}}, Z::Eye{T}) where {T,Tv,Ti} =
42+
convert(SparseMatrixCSC{Tv,Ti}, Z)
43+
convert(::Type{AbstractSparseArray{Tv,Ti,2}}, Z::Eye{T}) where {T,Tv,Ti} =
44+
convert(SparseMatrixCSC{Tv,Ti}, Z)
45+
46+
function SparseMatrixCSC{Tv}(R::RectOrDiagonalFill) where {Tv}
47+
SparseMatrixCSC{Tv,eltype(axes(R,1))}(R)
48+
end
49+
function SparseMatrixCSC{Tv,Ti}(R::RectOrDiagonalFill) where {Tv,Ti}
50+
Base.require_one_based_indexing(R)
51+
v = parent(R)
52+
J = getindex_value(v)*I
53+
SparseMatrixCSC{Tv,Ti}(J, size(R))
54+
end
55+
56+
# TODO: remove in v2.0
57+
@deprecate kron(E1::RectDiagonalFill, E2::RectDiagonalFill) kron(sparse(E1), sparse(E2))
58+
59+
end # module

ext/FillArraysStatisticsExt.jl

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
module FillArraysStatisticsExt
2+
3+
import Statistics: mean, var, cov, cor
4+
using LinearAlgebra: diagind
5+
6+
using FillArrays
7+
using FillArrays: AbstractFill, AbstractFillVector, AbstractFillMatrix, getindex_value
8+
9+
mean(A::AbstractFill; dims=(:)) = mean(identity, A; dims=dims)
10+
function mean(f::Union{Function, Type}, A::AbstractFill; dims=(:))
11+
val = float(f(getindex_value(A)))
12+
dims isa Colon ? val :
13+
Fill(val, ntuple(d -> d in dims ? 1 : size(A,d), ndims(A))...)
14+
end
15+
16+
17+
function var(A::AbstractFill{T}; corrected::Bool=true, mean=nothing, dims=(:)) where {T<:Number}
18+
dims isa Colon ? zero(float(T)) :
19+
Zeros{float(T)}(ntuple(d -> d in dims ? 1 : size(A,d), ndims(A))...)
20+
end
21+
22+
cov(::AbstractFillVector{T}; corrected::Bool=true) where {T<:Number} = zero(float(T))
23+
cov(A::AbstractFillMatrix{T}; corrected::Bool=true, dims::Integer=1) where {T<:Number} =
24+
Zeros{float(T)}(size(A, 3-dims), size(A, 3-dims))
25+
26+
cor(::AbstractFillVector{T}) where {T<:Number} = one(float(T))
27+
function cor(A::AbstractFillMatrix{T}; dims::Integer=1) where {T<:Number}
28+
out = fill(float(T)(NaN), size(A, 3-dims), size(A, 3-dims))
29+
out[diagind(out)] .= 1
30+
out
31+
end
32+
33+
end # module

src/FillArrays.jl

Lines changed: 6 additions & 79 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
""" `FillArrays` module to lazily represent matrices with a single value """
22
module FillArrays
33

4-
using LinearAlgebra, SparseArrays, Statistics
4+
using LinearAlgebra
55
import Base: size, getindex, setindex!, IndexStyle, checkbounds, convert,
66
+, -, *, /, \, diff, sum, cumsum, maximum, minimum, sort, sort!,
77
any, all, axes, isone, iterate, unique, allunique, permutedims, inv,
@@ -16,9 +16,6 @@ import LinearAlgebra: rank, svdvals!, tril, triu, tril!, triu!, diag, transpose,
1616

1717
import Base.Broadcast: broadcasted, DefaultArrayStyle, broadcast_shape, BroadcastStyle, Broadcasted
1818

19-
import Statistics: mean, std, var, cov, cor
20-
21-
2219
export Zeros, Ones, Fill, Eye, Trues, Falses, OneElement
2320

2421
import Base: oneto
@@ -545,52 +542,6 @@ for SMT in (:Diagonal, :Bidiagonal, :Tridiagonal, :SymTridiagonal)
545542
end
546543
end
547544

548-
##################
549-
## Sparse arrays
550-
##################
551-
SparseVector{T}(Z::ZerosVector) where T = spzeros(T, length(Z))
552-
SparseVector{Tv,Ti}(Z::ZerosVector) where {Tv,Ti} = spzeros(Tv, Ti, length(Z))
553-
554-
convert(::Type{AbstractSparseVector}, Z::ZerosVector{T}) where T = spzeros(T, length(Z))
555-
convert(::Type{AbstractSparseVector{T}}, Z::ZerosVector) where T= spzeros(T, length(Z))
556-
557-
SparseMatrixCSC{T}(Z::ZerosMatrix) where T = spzeros(T, size(Z)...)
558-
SparseMatrixCSC{Tv,Ti}(Z::Zeros{T,2,Axes}) where {Tv,Ti<:Integer,T,Axes} = spzeros(Tv, Ti, size(Z)...)
559-
560-
convert(::Type{AbstractSparseMatrix}, Z::ZerosMatrix{T}) where T = spzeros(T, size(Z)...)
561-
convert(::Type{AbstractSparseMatrix{T}}, Z::ZerosMatrix) where T = spzeros(T, size(Z)...)
562-
563-
convert(::Type{AbstractSparseArray}, Z::Zeros{T}) where T = spzeros(T, size(Z)...)
564-
convert(::Type{AbstractSparseArray{Tv}}, Z::Zeros{T}) where {T,Tv} = spzeros(Tv, size(Z)...)
565-
convert(::Type{AbstractSparseArray{Tv,Ti}}, Z::Zeros{T}) where {T,Tv,Ti} = spzeros(Tv, Ti, size(Z)...)
566-
convert(::Type{AbstractSparseArray{Tv,Ti,N}}, Z::Zeros{T,N}) where {T,Tv,Ti,N} = spzeros(Tv, Ti, size(Z)...)
567-
568-
SparseMatrixCSC{Tv}(Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)
569-
# works around missing `speye`:
570-
SparseMatrixCSC{Tv,Ti}(Z::Eye{T}) where {T,Tv,Ti<:Integer} =
571-
convert(SparseMatrixCSC{Tv,Ti}, SparseMatrixCSC{Tv}(I, size(Z)...))
572-
573-
convert(::Type{AbstractSparseMatrix}, Z::Eye{T}) where {T} = SparseMatrixCSC{T}(I, size(Z)...)
574-
convert(::Type{AbstractSparseMatrix{Tv}}, Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)
575-
576-
convert(::Type{AbstractSparseArray}, Z::Eye{T}) where T = SparseMatrixCSC{T}(I, size(Z)...)
577-
convert(::Type{AbstractSparseArray{Tv}}, Z::Eye{T}) where {T,Tv} = SparseMatrixCSC{Tv}(I, size(Z)...)
578-
579-
580-
convert(::Type{AbstractSparseArray{Tv,Ti}}, Z::Eye{T}) where {T,Tv,Ti} =
581-
convert(SparseMatrixCSC{Tv,Ti}, Z)
582-
convert(::Type{AbstractSparseArray{Tv,Ti,2}}, Z::Eye{T}) where {T,Tv,Ti} =
583-
convert(SparseMatrixCSC{Tv,Ti}, Z)
584-
585-
function SparseMatrixCSC{Tv}(R::RectOrDiagonalFill) where {Tv}
586-
SparseMatrixCSC{Tv,eltype(axes(R,1))}(R)
587-
end
588-
function SparseMatrixCSC{Tv,Ti}(R::RectOrDiagonalFill) where {Tv,Ti}
589-
Base.require_one_based_indexing(R)
590-
v = parent(R)
591-
J = getindex_value(v)*I
592-
SparseMatrixCSC{Tv,Ti}(J, size(R))
593-
end
594545

595546
#########
596547
# maximum/minimum
@@ -701,35 +652,6 @@ function in(x, A::RectDiagonal{<:Number})
701652
x == zero(eltype(A)) || x in A.diag
702653
end
703654

704-
#########
705-
# mean, std
706-
#########
707-
708-
mean(A::AbstractFill; dims=(:)) = mean(identity, A; dims=dims)
709-
function mean(f::Union{Function, Type}, A::AbstractFill; dims=(:))
710-
val = float(f(getindex_value(A)))
711-
dims isa Colon ? val :
712-
Fill(val, ntuple(d -> d in dims ? 1 : size(A,d), ndims(A))...)
713-
end
714-
715-
716-
function var(A::AbstractFill{T}; corrected::Bool=true, mean=nothing, dims=(:)) where {T<:Number}
717-
dims isa Colon ? zero(float(T)) :
718-
Zeros{float(T)}(ntuple(d -> d in dims ? 1 : size(A,d), ndims(A))...)
719-
end
720-
721-
cov(A::AbstractFillVector{T}; corrected::Bool=true) where {T<:Number} = zero(float(T))
722-
cov(A::AbstractFillMatrix{T}; corrected::Bool=true, dims::Integer=1) where {T<:Number} =
723-
Zeros{float(T)}(size(A, 3-dims), size(A, 3-dims))
724-
725-
cor(A::AbstractFillVector{T}) where {T<:Number} = one(float(T))
726-
function cor(A::AbstractFillMatrix{T}; dims::Integer=1) where {T<:Number}
727-
out = fill(float(T)(NaN), size(A, 3-dims), size(A, 3-dims))
728-
out[LinearAlgebra.diagind(out)] .= 1
729-
out
730-
end
731-
732-
733655
#########
734656
# include
735657
#########
@@ -738,6 +660,11 @@ include("fillalgebra.jl")
738660
include("fillbroadcast.jl")
739661
include("trues.jl")
740662

663+
@static if !isdefined(Base, :get_extension)
664+
include("../ext/FillArraysSparseArraysExt.jl")
665+
include("../ext/FillArraysStatisticsExt.jl")
666+
end
667+
741668
##
742669
# print
743670
##

src/fillalgebra.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -467,4 +467,3 @@ function kron(f::AbstractFillVecOrMat, g::AbstractFillVecOrMat)
467467
sz = _kronsize(f, g)
468468
_kron(f, g, sz)
469469
end
470-
kron(E1::RectDiagonalFill, E2::RectDiagonalFill) = kron(sparse(E1), sparse(E2))

0 commit comments

Comments
 (0)