Skip to content

Commit 7036a50

Browse files
authored
Introduce AbstractZeros and AbstractOnes (#299)
* Introduce AbstractZeros and AbstractOnes * Remove repeated AbstractZeros and AbstractOnes definitions * Refactor to allow customizing algebra outputs * Remove extraneous comment * Bump minor version number
1 parent 77cf6d6 commit 7036a50

File tree

5 files changed

+198
-151
lines changed

5 files changed

+198
-151
lines changed

Project.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name = "FillArrays"
22
uuid = "1a297f60-69ca-5386-bcde-b61e274b549b"
3-
version = "1.6.2"
3+
version = "1.7.0"
44

55
[deps]
66
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"

src/FillArrays.jl

+33-27
Original file line numberDiff line numberDiff line change
@@ -278,10 +278,15 @@ Base._reshape(parent::AbstractFill, dims::Tuple{Integer,Vararg{Integer}}) = fill
278278
# Resolves ambiguity error with `_reshape(v::AbstractArray{T, 1}, dims::Tuple{Int})`
279279
Base._reshape(parent::AbstractFill{T, 1, Axes}, dims::Tuple{Int}) where {T, Axes} = fill_reshape(parent, dims...)
280280

281-
for (Typ, funcs, func) in ((:Zeros, :zeros, :zero), (:Ones, :ones, :one))
281+
for (AbsTyp, Typ, funcs, func) in ((:AbstractZeros, :Zeros, :zeros, :zero), (:AbstractOnes, :Ones, :ones, :one))
282282
@eval begin
283+
abstract type $AbsTyp{T, N, Axes} <: AbstractFill{T, N, Axes} end
284+
$(Symbol(AbsTyp,"Vector")){T} = $AbsTyp{T,1}
285+
$(Symbol(AbsTyp,"Matrix")){T} = $AbsTyp{T,2}
286+
$(Symbol(AbsTyp,"VecOrMat")){T} = Union{$(Symbol(AbsTyp,"Vector")){T},$(Symbol(AbsTyp,"Matrix"))}
287+
283288
""" `$($Typ){T, N, Axes} <: AbstractFill{T, N, Axes}` (lazy `$($funcs)` with axes)"""
284-
struct $Typ{T, N, Axes} <: AbstractFill{T, N, Axes}
289+
struct $Typ{T, N, Axes} <: $AbsTyp{T, N, Axes}
285290
axes::Axes
286291
@inline $Typ{T,N,Axes}(sz::Axes) where Axes<:Tuple{Vararg{AbstractUnitRange,N}} where {T, N} =
287292
new{T,N,Axes}(sz)
@@ -312,29 +317,29 @@ for (Typ, funcs, func) in ((:Zeros, :zeros, :zero), (:Ones, :ones, :one))
312317
@inline $Typ(::Type{T}, m...) where T = $Typ{T}(m...)
313318

314319
@inline axes(Z::$Typ) = Z.axes
315-
@inline size(Z::$Typ) = length.(Z.axes)
316-
@inline getindex_value(Z::$Typ{T}) where T = $func(T)
320+
@inline size(Z::$AbsTyp) = length.(axes(Z))
321+
@inline getindex_value(Z::$AbsTyp{T}) where T = $func(T)
317322

318-
AbstractArray{T}(F::$Typ) where T = $Typ{T}(F.axes)
319-
AbstractArray{T,N}(F::$Typ{V,N}) where {T,V,N} = $Typ{T}(F.axes)
323+
AbstractArray{T}(F::$AbsTyp) where T = $Typ{T}(axes(F))
324+
AbstractArray{T,N}(F::$AbsTyp{V,N}) where {T,V,N} = $Typ{T}(axes(F))
320325

321-
copy(F::$Typ) = F
326+
copy(F::$AbsTyp) = F
322327

323-
getindex(F::$Typ{T,0}) where T = getindex_value(F)
328+
getindex(F::$AbsTyp{T,0}) where T = getindex_value(F)
324329

325330
promote_rule(::Type{$Typ{T, N, Axes}}, ::Type{$Typ{V, N, Axes}}) where {T,V,N,Axes} = $Typ{promote_type(T,V),N,Axes}
326-
function convert(::Type{$Typ{T,N,Axes}}, A::$Typ{V,N,Axes}) where {T,V,N,Axes}
331+
function convert(::Type{Typ}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes,Typ<:$AbsTyp{T,N,Axes}}
327332
convert(T, getindex_value(A)) # checks that the types are convertible
328-
$Typ{T,N,Axes}(axes(A))
333+
Typ(axes(A))
329334
end
330-
convert(::Type{$Typ{T,N}}, A::$Typ{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)
331-
convert(::Type{$Typ{T}}, A::$Typ{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)
332-
function convert(::Type{$Typ{T,N,Axes}}, A::AbstractFill{V,N}) where {T,V,N,Axes}
335+
convert(::Type{$Typ{T,N}}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)
336+
convert(::Type{$Typ{T}}, A::$AbsTyp{V,N,Axes}) where {T,V,N,Axes} = convert($Typ{T,N,Axes}, A)
337+
function convert(::Type{Typ}, A::AbstractFill{V,N}) where {T,V,N,Axes,Typ<:$AbsTyp{T,N,Axes}}
333338
axes(A) isa Axes || throw(ArgumentError("cannot convert, as axes of array are not $Axes"))
334339
val = getindex_value(A)
335340
y = convert(T, val)
336341
y == $func(T) || throw(ArgumentError(string("cannot convert an array containinig $val to ", $Typ)))
337-
$Typ{T,N,Axes}(axes(A))
342+
Typ(axes(A))
338343
end
339344
function convert(::Type{$Typ{T,N}}, A::AbstractFill{<:Any,N}) where {T,N}
340345
convert($Typ{T,N,typeof(axes(A))}, A)
@@ -517,7 +522,7 @@ Base.Array{T,N}(F::AbstractFill{V,N}) where {T,V,N} =
517522
convert(Array{T,N}, fill(convert(T, getindex_value(F)), size(F)))
518523

519524
# These are in case `zeros` or `ones` are ever faster than `fill`
520-
for (Typ, funcs, func) in ((:Zeros, :zeros, :zero), (:Ones, :ones, :one))
525+
for (Typ, funcs, func) in ((:AbstractZeros, :zeros, :zero), (:AbstractOnes, :ones, :one))
521526
@eval begin
522527
Base.Array{T,N}(F::$Typ{V,N}) where {T,V,N} = $funcs(T,size(F))
523528
end
@@ -562,16 +567,16 @@ end
562567
# These methods are necessary to deal with infinite arrays
563568
sum(x::AbstractFill) = getindex_value(x)*length(x)
564569
sum(f, x::AbstractFill) = length(x) * f(getindex_value(x))
565-
sum(x::Zeros) = getindex_value(x)
570+
sum(x::AbstractZeros) = getindex_value(x)
566571

567572
# needed to support infinite case
568573
steprangelen(st...) = StepRangeLen(st...)
569574
cumsum(x::AbstractFill{<:Any,1}) = steprangelen(getindex_value(x), getindex_value(x), length(x))
570575

571-
cumsum(x::ZerosVector) = x
572-
cumsum(x::ZerosVector{Bool}) = x
573-
cumsum(x::OnesVector{II}) where II<:Integer = convert(AbstractVector{II}, oneto(length(x)))
574-
cumsum(x::OnesVector{Bool}) = oneto(length(x))
576+
cumsum(x::AbstractZerosVector) = x
577+
cumsum(x::AbstractZerosVector{Bool}) = x
578+
cumsum(x::AbstractOnesVector{II}) where II<:Integer = convert(AbstractVector{II}, oneto(length(x)))
579+
cumsum(x::AbstractOnesVector{Bool}) = oneto(length(x))
575580

576581

577582
#########
@@ -591,8 +596,9 @@ allunique(x::AbstractFill) = length(x) < 2
591596
# zero
592597
#########
593598

594-
zero(r::Zeros{T,N}) where {T,N} = r
595-
zero(r::Ones{T,N}) where {T,N} = Zeros{T,N}(r.axes)
599+
zero(r::AbstractZeros{T,N}) where {T,N} = r
600+
# TODO: Make this required?
601+
zero(r::AbstractOnes{T,N}) where {T,N} = Zeros{T,N}(axes(r))
596602
zero(r::Fill{T,N}) where {T,N} = Zeros{T,N}(r.axes)
597603

598604
#########
@@ -641,8 +647,8 @@ all(f::Function, x::AbstractFill) = isempty(x) || all(f(getindex_value(x)))
641647
any(x::AbstractFill) = any(identity, x)
642648
all(x::AbstractFill) = all(identity, x)
643649

644-
count(x::Ones{Bool}) = length(x)
645-
count(x::Zeros{Bool}) = 0
650+
count(x::AbstractOnes{Bool}) = length(x)
651+
count(x::AbstractZeros{Bool}) = 0
646652
count(f, x::AbstractFill) = f(getindex_value(x)) ? length(x) : 0
647653

648654
#########
@@ -671,7 +677,7 @@ end
671677
##
672678
# print
673679
##
674-
Base.replace_in_print_matrix(::Zeros, ::Integer, ::Integer, s::AbstractString) =
680+
Base.replace_in_print_matrix(::AbstractZeros, ::Integer, ::Integer, s::AbstractString) =
675681
Base.replace_with_centered_mark(s)
676682

677683
# following support blocked fill array printing via
@@ -704,7 +710,7 @@ function Base.show(io::IO, ::MIME"text/plain", x::Union{Eye, AbstractFill})
704710
return show(io, x)
705711
end
706712
summary(io, x)
707-
if x isa Union{Zeros, Ones, Eye}
713+
if x isa Union{AbstractZeros, AbstractOnes, Eye}
708714
# then no need to print entries
709715
elseif length(x) > 1
710716
print(io, ", with entries equal to ", getindex_value(x))
@@ -716,7 +722,7 @@ end
716722
function Base.show(io::IO, x::AbstractFill) # for example (Fill(π,3),)
717723
print(io, nameof(typeof(x)))
718724
sz = size(x)
719-
args = if x isa Union{Zeros, Ones}
725+
args = if x isa Union{AbstractZeros, AbstractOnes}
720726
T = eltype(x)
721727
if T != Float64
722728
print(io,"{", T, "}")

0 commit comments

Comments
 (0)