@@ -6,7 +6,7 @@ import Base: size, getindex, setindex!, IndexStyle, checkbounds, convert,
6
6
+ , - , * , / , \ , diff, sum, cumsum, maximum, minimum, sort, sort!,
7
7
any, all, axes, isone, iterate, unique, allunique, permutedims, inv,
8
8
copy, vec, setindex!, count, == , reshape, _throw_dmrs, map, zero,
9
- show, view, in, mapreduce, one, reverse, promote_op
9
+ show, view, in, mapreduce, one, reverse, promote_op, promote_rule
10
10
11
11
import LinearAlgebra: rank, svdvals!, tril, triu, tril!, triu!, diag, transpose, adjoint, fill!,
12
12
dot, norm2, norm1, normInf, normMinusInf, normp, lmul!, rmul!, diagzero, AdjointAbsVec, TransposeAbsVec,
@@ -18,7 +18,7 @@ import Base.Broadcast: broadcasted, DefaultArrayStyle, broadcast_shape
18
18
import Statistics: mean, std, var, cov, cor
19
19
20
20
21
- export Zeros, Ones, Fill, Eye, Trues, Falses
21
+ export Zeros, Ones, Fill, Eye, Trues, Falses, OneElement
22
22
23
23
import Base: oneto
24
24
@@ -34,6 +34,7 @@ const AbstractFillVecOrMat{T} = Union{AbstractFillVector{T},AbstractFillMatrix{T
34
34
35
35
== (a:: AbstractFill , b:: AbstractFill ) = axes (a) == axes (b) && getindex_value (a) == getindex_value (b)
36
36
37
+
37
38
@inline function _fill_getindex (F:: AbstractFill , kj:: Integer... )
38
39
@boundscheck checkbounds (F, kj... )
39
40
getindex_value (F)
@@ -147,15 +148,47 @@ Fill{T,0}(x::T, ::Tuple{}) where T = Fill{T,0,Tuple{}}(x, ()) # ambiguity fix
147
148
@inline axes (F:: Fill ) = F. axes
148
149
@inline size (F:: Fill ) = map (length, F. axes)
149
150
151
+ """
152
+ getindex_value(F::AbstractFill)
153
+
154
+ Return the value that `F` is filled with.
155
+
156
+ # Examples
157
+
158
+ ```jldoctest
159
+ julia> f = Ones(3);
160
+
161
+ julia> FillArrays.getindex_value(f)
162
+ 1.0
163
+
164
+ julia> g = Fill(2, 10);
165
+
166
+ julia> FillArrays.getindex_value(g)
167
+ 2
168
+ ```
169
+ """
170
+ getindex_value
171
+
150
172
@inline getindex_value (F:: Fill ) = F. value
151
173
152
174
AbstractArray {T} (F:: Fill{V,N} ) where {T,V,N} = Fill {T} (convert (T, F. value):: T , F. axes)
153
175
AbstractArray {T,N} (F:: Fill{V,N} ) where {T,V,N} = Fill {T} (convert (T, F. value):: T , F. axes)
154
176
AbstractFill {T} (F:: AbstractFill ) where T = AbstractArray {T} (F)
177
+ AbstractFill {T,N} (F:: AbstractFill ) where {T,N} = AbstractArray {T,N} (F)
178
+ AbstractFill {T,N,Ax} (F:: AbstractFill{<:Any,N,Ax} ) where {T,N,Ax} = AbstractArray {T,N} (F)
179
+
180
+ convert (:: Type{AbstractFill{T}} , F:: AbstractFill ) where T = convert (AbstractArray{T}, F)
181
+ convert (:: Type{AbstractFill{T,N}} , F:: AbstractFill ) where {T,N} = convert (AbstractArray{T,N}, F)
182
+ convert (:: Type{AbstractFill{T,N,Ax}} , F:: AbstractFill{<:Any,N,Ax} ) where {T,N,Ax} = convert (AbstractArray{T,N}, F)
155
183
156
184
copy (F:: Fill ) = Fill (F. value, F. axes)
157
185
158
- """ Throws an error if `arr` does not contain one and only one unique value. """
186
+ """
187
+ unique_value(arr::AbstractArray)
188
+
189
+ Return `only(unique(arr))` without intermediate allocations.
190
+ Throws an error if `arr` does not contain one and only one unique value.
191
+ """
159
192
function unique_value (arr:: AbstractArray )
160
193
if isempty (arr) error (" Cannot convert empty array to Fill" ) end
161
194
val = first (arr)
@@ -274,6 +307,14 @@ for (Typ, funcs, func) in ((:Zeros, :zeros, :zero), (:Ones, :ones, :one))
274
307
copy (F:: $Typ ) = F
275
308
276
309
getindex (F:: $Typ{T,0} ) where T = getindex_value (F)
310
+
311
+ promote_rule (:: Type{$Typ{T, N, Axes}} , :: Type{$Typ{V, N, Axes}} ) where {T,V,N,Axes} = $ Typ{promote_type (T,V),N,Axes}
312
+ function convert (:: Type{$Typ{T,N,Axes}} , A:: $Typ{V,N,Axes} ) where {T,V,N,Axes}
313
+ convert (T, getindex_value (A)) # checks that the types are convertible
314
+ $ Typ {T,N,Axes} (axes (A))
315
+ end
316
+ convert (:: Type{$Typ{T,N}} , A:: $Typ{V,N,Axes} ) where {T,V,N,Axes} = convert ($ Typ{T,N,Axes}, A)
317
+ convert (:: Type{$Typ{T}} , A:: $Typ{V,N,Axes} ) where {T,V,N,Axes} = convert ($ Typ{T,N,Axes}, A)
277
318
end
278
319
end
279
320
@@ -285,6 +326,8 @@ for TYPE in (:Fill, :AbstractFill, :Ones, :Zeros), STYPE in (:AbstractArray, :Ab
285
326
end
286
327
end
287
328
329
+ promote_rule (:: Type{<:AbstractFill{T, N, Axes}} , :: Type{<:AbstractFill{V, N, Axes}} ) where {T,V,N,Axes} = Fill{promote_type (T,V),N,Axes}
330
+
288
331
"""
289
332
fillsimilar(a::AbstractFill, axes)
290
333
427
470
428
471
429
472
# # Array
430
- Base. Array {T,N} (F:: AbstractFill{V,N} ) where {T,V,N} = fill (convert (T, getindex_value (F)), size (F))
473
+ Base. Array {T,N} (F:: AbstractFill{V,N} ) where {T,V,N} =
474
+ convert (Array{T,N}, fill (convert (T, getindex_value (F)), size (F)))
431
475
432
476
# These are in case `zeros` or `ones` are ever faster than `fill`
433
477
for (Typ, funcs, func) in ((:Zeros , :zeros , :zero ), (:Ones , :ones , :one ))
438
482
439
483
# temporary patch. should be a PR(#48895) to LinearAlgebra
440
484
Diagonal {T} (A:: AbstractFillMatrix ) where T = Diagonal {T} (diag (A))
441
- function convert (:: Type{T} , A:: AbstractFillMatrix ) where T<: Diagonal
485
+ function convert (:: Type{T} , A:: AbstractFillMatrix ) where T<: Diagonal
442
486
checksquare (A)
443
487
isdiag (A) ? T (A) : throw (InexactError (:convert , T, A))
444
488
end
@@ -497,14 +541,14 @@ sum(x::AbstractFill) = getindex_value(x)*length(x)
497
541
sum (f, x:: AbstractFill ) = length (x) * f (getindex_value (x))
498
542
sum (x:: Zeros ) = getindex_value (x)
499
543
500
- cumsum (x:: AbstractFill{<:Any,1} ) = range (getindex_value (x); step= getindex_value (x),
501
- length= length (x))
544
+ # needed to support infinite case
545
+ steprangelen (st... ) = StepRangeLen (st... )
546
+ cumsum (x:: AbstractFill{<:Any,1} ) = steprangelen (getindex_value (x), getindex_value (x), length (x))
502
547
503
548
cumsum (x:: ZerosVector ) = x
504
549
cumsum (x:: ZerosVector{Bool} ) = x
505
550
cumsum (x:: OnesVector{II} ) where II<: Integer = convert (AbstractVector{II}, oneto (length (x)))
506
551
cumsum (x:: OnesVector{Bool} ) = oneto (length (x))
507
- cumsum (x:: AbstractFillVector{Bool} ) = cumsum (AbstractFill {Int} (x))
508
552
509
553
510
554
# ########
@@ -718,4 +762,6 @@ Base.@propagate_inbounds function view(A::AbstractFill, I::Vararg{Real})
718
762
fillsimilar (A)
719
763
end
720
764
765
+ include (" oneelement.jl" )
766
+
721
767
end # module
0 commit comments