Skip to content

Commit 3f8ca5c

Browse files
authored
Merge branch 'master' into dsptests
2 parents 88eddfa + 5d50e86 commit 3f8ca5c

File tree

7 files changed

+146
-89
lines changed

7 files changed

+146
-89
lines changed

.github/workflows/downstream.yml

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@ jobs:
4040
- {repo: ArrayLayouts.jl, group: JuliaLinearAlgebra}
4141
- {repo: LazyBandedMatrices.jl, group: JuliaLinearAlgebra}
4242
- {repo: BandedMatrices.jl, group: JuliaLinearAlgebra}
43-
- {repo: ContinuumArrays.jl, group: JuliaApproximation}
4443
- {repo: BlockBandedMatrices.jl, group: JuliaLinearAlgebra}
4544
- {repo: InfiniteLinearAlgebra.jl, group: JuliaLinearAlgebra}
4645
- {repo: Optim.jl, group: JuliaNLSolvers}

Project.toml

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,21 @@
11
name = "FillArrays"
22
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
3-
version = "1.5.0"
3+
version = "1.6.1"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
77
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
DSP = "0.7"
@@ -18,8 +26,9 @@ Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
1826
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
1927
DSP = "717857b8-e6f2-59f4-9121-6e50c889abd2"
2028
ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
29+
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
2130
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
31+
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
2232
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
2333

24-
[targets]
25-
test = ["Aqua", "Test", "Base64", "DSP", "ReverseDiff", "StaticArrays"]
34+
test = ["Aqua", "Test", "Base64", "ReverseDiff", "SparseArrays", "StaticArrays", "Statistics", "DSP"]

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: 21 additions & 83 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
@@ -530,6 +527,9 @@ function convert(::Type{T}, A::AbstractFillMatrix) where T<:Diagonal
530527
isdiag(A) ? T(A) : throw(InexactError(:convert, T, A))
531528
end
532529

530+
Base.StepRangeLen(F::AbstractFillVector{T}) where T = StepRangeLen(getindex_value(F), zero(T), length(F))
531+
convert(::Type{SL}, F::AbstractFillVector) where SL<:AbstractRange = convert(SL, StepRangeLen(F))
532+
533533
#################
534534
# Structured matrix types
535535
#################
@@ -542,52 +542,6 @@ for SMT in (:Diagonal, :Bidiagonal, :Tridiagonal, :SymTridiagonal)
542542
end
543543
end
544544

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

592546
#########
593547
# maximum/minimum
@@ -698,35 +652,6 @@ function in(x, A::RectDiagonal{<:Number})
698652
x == zero(eltype(A)) || x in A.diag
699653
end
700654

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

663+
@static if !isdefined(Base, :get_extension)
664+
include("../ext/FillArraysSparseArraysExt.jl")
665+
include("../ext/FillArraysStatisticsExt.jl")
666+
end
667+
738668
##
739669
# print
740670
##
@@ -781,11 +711,19 @@ function Base.show(io::IO, ::MIME"text/plain", x::Union{Eye, AbstractFill})
781711
end
782712

783713
function Base.show(io::IO, x::AbstractFill) # for example (Fill(π,3),)
784-
print(io, nameof(typeof(x)), "(")
785-
if x isa Union{Zeros, Ones}
714+
print(io, nameof(typeof(x)))
715+
sz = size(x)
716+
args = if x isa Union{Zeros, Ones}
717+
T = eltype(x)
718+
if T != Float64
719+
print(io,"{", T, "}")
720+
end
721+
print(io, "(")
786722
else
787-
show(io, getindex_value(x)) # show not print to handle (Fill(1f0,2),)
788-
ndims(x) > 0 && print(io, ", ")
723+
# show, not print, to handle (Fill(1f0,2),)
724+
print(io, "(")
725+
show(io, getindex_value(x))
726+
ndims(x) == 0 || print(io, ", ")
789727
end
790728
join(io, size(x), ", ")
791729
print(io, ")")

src/fillalgebra.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,8 @@ end
353353
-(a::Zeros) = a
354354
-(a::AbstractFill) = Fill(-getindex_value(a), size(a))
355355

356+
# special-cased for type-stability, as Ones + Ones is not a Ones
357+
Base.reduce_first(::typeof(+), x::Ones) = Fill(Base.reduce_first(+, getindex_value(x)), axes(x))
356358

357359
function +(a::Zeros{T}, b::Zeros{V}) where {T, V} # for disambiguity
358360
promote_shape(a,b)
@@ -467,4 +469,3 @@ function kron(f::AbstractFillVecOrMat, g::AbstractFillVecOrMat)
467469
sz = _kronsize(f, g)
468470
_kron(f, g, sz)
469471
end
470-
kron(E1::RectDiagonalFill, E2::RectDiagonalFill) = kron(sparse(E1), sparse(E2))

test/runtests.jl

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,11 @@ import FillArrays: AbstractFill, RectDiagonal, SquareEye
1313

1414
using Aqua
1515
@testset "Project quality" begin
16-
Aqua.test_all(FillArrays, ambiguities=false)
16+
Aqua.test_all(FillArrays, ambiguities=false,
17+
# only test formatting on VERSION >= v1.7
18+
# https://github.com/JuliaTesting/Aqua.jl/issues/105#issuecomment-1551405866
19+
project_toml_formatting = VERSION >= v"1.7",
20+
)
1721
end
1822

1923
include("infinitearrays.jl")
@@ -307,6 +311,13 @@ end
307311
@test A[1,:,1] A[1,1:6,1] Fill(2.0,6)
308312
@test A[:,:,:] A[1:5,1:6,1:7] A[1:5,:,1:7] A[:,1:6,1:7] A
309313
end
314+
315+
@testset "StepRangeLen convert" begin
316+
for (z,s) in ((Zeros{Int}(5), StepRangeLen(0, 0, 5)), (Ones{Int}(5), StepRangeLen(1, 0, 5)), (Fill(2,5), StepRangeLen(2, 0, 5)))
317+
@test s == z
318+
@test StepRangeLen(z) convert(StepRangeLen, z) convert(StepRangeLen{Int}, z) convert(typeof(s), z) convert(AbstractRange, z) s
319+
end
320+
end
310321
end
311322

312323
@testset "RectDiagonal" begin
@@ -824,6 +835,9 @@ end
824835
@test diff(Ones{Float64}(10)) Zeros{Float64}(9)
825836
@test_throws UndefKeywordError cumsum(Fill(1,1,5))
826837

838+
@test @inferred(sum([Ones(4)])) Fill(1.0, 4)
839+
@test @inferred(sum([Trues(4)])) Fill(1, 4)
840+
827841
@testset "infinite arrays" begin
828842
r = InfiniteArrays.OneToInf()
829843
A = Ones{Int}((r,))
@@ -1735,7 +1749,11 @@ end
17351749
@test Base.replace_in_print_matrix(Zeros(5,3), 1, 2, "0.0") == ""
17361750

17371751
# 2-arg show, compact printing
1752+
@test repr(Zeros{Int}()) == "Zeros{$Int}()"
1753+
@test repr(Zeros{Int}(3)) == "Zeros{$Int}(3)"
17381754
@test repr(Zeros(3)) == "Zeros(3)"
1755+
@test repr(Ones{Int}(3)) == "Ones{$Int}(3)"
1756+
@test repr(Ones{Int}(3,2)) == "Ones{$Int}(3, 2)"
17391757
@test repr(Ones(3,2)) == "Ones(3, 2)"
17401758
@test repr(Fill(7,3,2)) == "Fill(7, 3, 2)"
17411759
@test repr(Fill(1f0,10)) == "Fill(1.0f0, 10)" # Float32!

0 commit comments

Comments
 (0)