Skip to content

Commit 7ce8f5b

Browse files
authored
Merge branch 'master' into permutedims
2 parents 5030c7e + c7c34aa commit 7ce8f5b

File tree

7 files changed

+255
-81
lines changed

7 files changed

+255
-81
lines changed

Project.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,9 +22,11 @@ FillArraysStatisticsExt = "Statistics"
2222
[compat]
2323
Aqua = "0.8"
2424
Base64 = "1.6"
25+
Documenter = "1"
2526
Infinities = "0.1"
2627
LinearAlgebra = "1.6"
2728
PDMats = "0.11.17"
29+
Quaternions = "0.7"
2830
Random = "1.6"
2931
ReverseDiff = "1"
3032
SparseArrays = "1.6"
@@ -36,13 +38,15 @@ julia = "1.6"
3638
[extras]
3739
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
3840
Base64 = "2a0f44e3-6c83-55bd-87e4-b1978d98bd5f"
41+
Documenter = "e30172f5-a6a5-5a46-863b-614d45cd2de4"
3942
Infinities = "e1ba4f0e-776d-440f-acd9-e1d2e9742647"
4043
PDMats = "90014a1f-27ba-587c-ab20-58faa44d9150"
44+
Quaternions = "94ee1d12-ae83-5a48-8b1c-48b8ff168ae0"
4145
ReverseDiff = "37e2e3b7-166d-5795-8a7a-e32c996b4267"
4246
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
4347
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
4448
Statistics = "10745b16-79ce-11e8-11f9-7d13ad32a3b2"
4549
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
4650

4751
[targets]
48-
test = ["Aqua", "Test", "Base64", "Infinities", "PDMats", "ReverseDiff", "SparseArrays", "StaticArrays", "Statistics"]
52+
test = ["Aqua", "Test", "Base64", "Infinities", "PDMats", "ReverseDiff", "SparseArrays", "StaticArrays", "Statistics", "Quaternions", "Documenter"]

docs/Project.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,7 @@ SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
66
StaticArrays = "90137ffa-7385-5640-81b9-e52037218182"
77

88
[compat]
9-
Documenter = "0.27"
9+
Documenter = "1"
10+
Random = "1"
11+
SparseArrays = "1"
1012
StaticArrays = "1"

docs/src/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ The elements of a `Fill` array don't need to be restricted to numbers, and these
6969

7070
```jldoctest
7171
julia> f = Fill("hello", 2,5)
72-
2×5 Fill{String}, with entries equal to hello
72+
2×5 Fill{String}, with entries equal to "hello"
7373
7474
julia> Array(f)
7575
2×5 Matrix{String}:

src/FillArrays.jl

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,14 @@ module FillArrays
44
using LinearAlgebra
55
import Base: size, getindex, setindex!, IndexStyle, checkbounds, convert,
66
+, -, *, /, \, diff, sum, cumsum, maximum, minimum, sort, sort!,
7-
any, all, axes, isone, iterate, unique, allunique, permutedims, inv,
7+
any, all, axes, isone, iszero, iterate, unique, allunique, permutedims, inv,
88
copy, vec, setindex!, count, ==, reshape, map, zero,
99
show, view, in, mapreduce, one, reverse, promote_op, promote_rule, repeat,
1010
parent, similar, issorted
1111

1212
import LinearAlgebra: rank, svdvals!, tril, triu, tril!, triu!, diag, transpose, adjoint, fill!,
1313
dot, norm2, norm1, normInf, normMinusInf, normp, lmul!, rmul!, diagzero, AdjointAbsVec, TransposeAbsVec,
14-
issymmetric, ishermitian, AdjOrTransAbsVec, checksquare, mul!, kron
14+
issymmetric, ishermitian, AdjOrTransAbsVec, checksquare, mul!, kron, AbstractTriangular
1515

1616

1717
import Base.Broadcast: broadcasted, DefaultArrayStyle, broadcast_shape, BroadcastStyle, Broadcasted
@@ -94,14 +94,10 @@ Typically created by `Fill` or `Zeros` or `Ones`
9494
9595
```jldoctest
9696
julia> Fill(7, (2,3))
97-
2×3 Fill{Int64,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}}:
98-
7 7 7
99-
7 7 7
100-
101-
julia> Fill{Float64, 1, Tuple{UnitRange{Int64}}}(7., (1:2,))
102-
2-element Fill{Float64,1,Tuple{UnitRange{Int64}}} with indices 1:2:
103-
7.0
104-
7.0
97+
2×3 Fill{Int64}, with entries equal to 7
98+
99+
julia> Fill{Float64, 1, Tuple{UnitRange{Int64}}}(7.0, (1:2,))
100+
2-element Fill{Float64, 1, Tuple{UnitRange{Int64}}} with indices 1:2, with entries equal to 7.0
105101
```
106102
"""
107103
struct Fill{T, N, Axes} <: AbstractFill{T, N, Axes}
@@ -621,9 +617,10 @@ end
621617
#########
622618

623619
function isone(AF::AbstractFillMatrix)
624-
isone(getindex_value(AF)) || return false
625620
(n,m) = size(AF)
626621
n != m && return false
622+
(n == 0 || m == 0) && return true
623+
isone(getindex_value(AF)) || return false
627624
n == 1 && return true
628625
return false
629626
end
@@ -715,12 +712,9 @@ function Base.show(io::IO, ::MIME"text/plain", x::Union{Eye, AbstractFill})
715712
return show(io, x)
716713
end
717714
summary(io, x)
718-
if x isa Union{AbstractZeros, AbstractOnes, Eye}
719-
# then no need to print entries
720-
elseif length(x) > 1
721-
print(io, ", with entries equal to ", getindex_value(x))
722-
else
723-
print(io, ", with entry equal to ", getindex_value(x))
715+
if !(x isa Union{AbstractZeros, AbstractOnes, Eye})
716+
print(io, ", with ", length(x) > 1 ? "entries" : "entry", " equal to ")
717+
show(io, getindex_value(x))
724718
end
725719
end
726720

@@ -742,7 +736,13 @@ function Base.show(io::IO, x::AbstractFill) # for example (Fill(π,3),)
742736
join(io, size(x), ", ")
743737
print(io, ")")
744738
end
745-
Base.show(io::IO, x::Eye) = print(io, "Eye(", size(x,1), ")")
739+
function Base.show(io::IO, x::Eye)
740+
print(io, "Eye(", size(x,1))
741+
if size(x,1) != size(x,2)
742+
print(io, ",", size(x,2))
743+
end
744+
print(io, ")")
745+
end
746746

747747
Base.array_summary(io::IO, ::Zeros{T}, inds::Tuple{Vararg{Base.OneTo}}) where T =
748748
print(io, Base.dims2string(length.(inds)), " Zeros{$T}")

src/fillalgebra.jl

Lines changed: 71 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,17 @@ vec(a::AbstractFill) = fillsimilar(a, length(a))
66
# cannot do this for vectors since that would destroy scalar dot product
77

88

9-
transpose(a::Union{AbstractOnesMatrix, AbstractZerosMatrix}) = fillsimilar(a, reverse(axes(a)))
10-
adjoint(a::Union{AbstractOnesMatrix, AbstractZerosMatrix}) = fillsimilar(a, reverse(axes(a)))
11-
transpose(a::FillMatrix{T}) where T = Fill{T}(transpose(a.value), reverse(a.axes))
12-
adjoint(a::FillMatrix{T}) where T = Fill{T}(adjoint(a.value), reverse(a.axes))
9+
for OP in (:transpose, :adjoint)
10+
@eval begin
11+
function $OP(a::AbstractZerosMatrix)
12+
v = getindex_value(a)
13+
T = typeof($OP(v))
14+
Zeros{T}(reverse(axes(a)))
15+
end
16+
$OP(a::AbstractOnesMatrix) = fillsimilar(a, reverse(axes(a)))
17+
$OP(a::FillMatrix) = Fill($OP(a.value), reverse(a.axes))
18+
end
19+
end
1320

1421
permutedims(a::AbstractFillMatrix) = fillsimilar(a, reverse(a.axes))
1522

@@ -91,9 +98,18 @@ mult_ones(a, b) = mult_ones(a, b, mult_axes(a, b))
9198
*(a::AbstractFillMatrix, b::AbstractZerosMatrix) = mult_zeros(a, b)
9299
*(a::AbstractFillMatrix, b::AbstractZerosVector) = mult_zeros(a, b)
93100

94-
*(a::AbstractZerosMatrix, b::AbstractMatrix) = mult_zeros(a, b)
95-
*(a::AbstractMatrix, b::AbstractZerosVector) = mult_zeros(a, b)
96-
*(a::AbstractMatrix, b::AbstractZerosMatrix) = mult_zeros(a, b)
101+
for MT in (:AbstractMatrix, :AbstractTriangular)
102+
@eval *(a::AbstractZerosMatrix, b::$MT) = mult_zeros(a, b)
103+
@eval *(a::$MT, b::AbstractZerosMatrix) = mult_zeros(a, b)
104+
end
105+
# Odd way to deal with the type-parameters to avoid ambiguities
106+
for MT in (:(AbstractMatrix{T}), :(Transpose{<:Any, <:AbstractMatrix{T}}), :(Adjoint{<:Any, <:AbstractMatrix{T}}),
107+
:(AbstractTriangular{T}))
108+
@eval *(a::$MT, b::AbstractZerosVector) where {T} = mult_zeros(a, b)
109+
end
110+
for MT in (:(Transpose{<:Any, <:AbstractVector}), :(Adjoint{<:Any, <:AbstractVector}))
111+
@eval *(a::$MT, b::AbstractZerosMatrix) = mult_zeros(a, b)
112+
end
97113
*(a::AbstractZerosMatrix, b::AbstractVector) = mult_zeros(a, b)
98114

99115
function lmul_diag(a::Diagonal, b)
@@ -139,60 +155,56 @@ end
139155
function mul!(y::AbstractVector, A::AbstractFillMatrix, b::AbstractFillVector, alpha::Number, beta::Number)
140156
check_matmul_sizes(y, A, b)
141157

142-
αAb = alpha * getindex_value(A) * getindex_value(b) * length(b)
158+
Abα = Ref(getindex_value(A) * getindex_value(b) * alpha * length(b))
143159

144160
if iszero(beta)
145-
y .= αAb
161+
y .= Abα
146162
else
147-
y .= αAb .+ beta .* y
163+
y .= Abα .+ y .* beta
148164
end
149165
y
150166
end
151167

152168
function mul!(y::StridedVector, A::StridedMatrix, b::AbstractFillVector, alpha::Number, beta::Number)
153169
check_matmul_sizes(y, A, b)
154170

155-
αb = alpha * getindex_value(b)
171+
= Ref(getindex_value(b) * alpha)
156172

157173
if iszero(beta)
158-
y .= zero(eltype(y))
159-
for col in eachcol(A)
160-
y .+= αb .* col
161-
end
174+
y .= Ref(zero(eltype(y)))
162175
else
163-
lmul!(beta, y)
164-
for col in eachcol(A)
165-
y .+= αb .* col
166-
end
176+
rmul!(y, beta)
177+
end
178+
for Acol in eachcol(A)
179+
@. y += Acol *
167180
end
168181
y
169182
end
170183

171184
function mul!(y::StridedVector, A::AbstractFillMatrix, b::StridedVector, alpha::Number, beta::Number)
172185
check_matmul_sizes(y, A, b)
173186

174-
αA = alpha * getindex_value(A)
187+
Abα = Ref(getindex_value(A) * sum(b) * alpha)
175188

176189
if iszero(beta)
177-
y .= αA .* sum(b)
190+
y .= Abα
178191
else
179-
y .= αA .* sum(b) .+ beta .* y
192+
y .= Abα .+ y .* beta
180193
end
181194
y
182195
end
183196

184-
function _mul_adjtrans!(y::AbstractVector, A::AbstractMatrix, b::AbstractVector, alpha, beta, f)
185-
α = alpha * getindex_value(b)
186-
197+
function _mul_adjtrans!(y::AbstractVector, A::AbstractMatrix, b::AbstractFillVector, alpha, beta, f)
198+
= getindex_value(b) * alpha
187199
At = f(A)
188200

189201
if iszero(beta)
190-
for (ind, col) in zip(eachindex(y), eachcol(At))
191-
y[ind] = α .* f(sum(col))
202+
for (ind, Atcol) in zip(eachindex(y), eachcol(At))
203+
y[ind] = f(sum(Atcol)) *
192204
end
193205
else
194-
for (ind, col) in zip(eachindex(y), eachcol(At))
195-
y[ind] = α .* f(sum(col)) .+ beta .* y[ind]
206+
for (ind, Atcol) in zip(eachindex(y), eachcol(At))
207+
y[ind] = f(sum(Atcol)) *.+ y[ind] .* beta
196208
end
197209
end
198210
y
@@ -207,11 +219,11 @@ end
207219

208220
function mul!(C::AbstractMatrix, A::AbstractFillMatrix, B::AbstractFillMatrix, alpha::Number, beta::Number)
209221
check_matmul_sizes(C, A, B)
210-
αAB = alpha * getindex_value(A) * getindex_value(B) * size(B,1)
222+
ABα = getindex_value(A) * getindex_value(B) * alpha * size(B,1)
211223
if iszero(beta)
212-
C .= αAB
224+
C .= ABα
213225
else
214-
C .= αAB .+ beta .* C
226+
C .= ABα .+ C .* beta
215227
end
216228
C
217229
end
@@ -237,7 +249,7 @@ _firstcol(C::Union{Adjoint, Transpose}) = view(parent(C), 1, :)
237249
function _mulfill!(C, A, B::AbstractFillMatrix, alpha, beta)
238250
check_matmul_sizes(C, A, B)
239251
if iszero(size(B,2))
240-
return lmul!(beta, C)
252+
return rmul!(C, beta)
241253
end
242254
mul!(_firstcol(C), A, view(B, :, 1), alpha, beta)
243255
copyfirstcol!(C)
@@ -288,13 +300,25 @@ function _adjvec_mul_zeros(a, b)
288300
return a1 * b[1]
289301
end
290302

291-
*(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::AbstractMatrix) = (b' * a')'
303+
for MT in (:AbstractMatrix, :AbstractTriangular, :(Adjoint{<:Any,<:TransposeAbsVec}))
304+
@eval *(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::$MT) = (b' * a')'
305+
end
306+
# ambiguity
307+
function *(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::TransposeAbsVec{<:Any,<:AdjointAbsVec})
308+
# change from Transpose ∘ Adjoint to Adjoint ∘ Transpose
309+
b2 = adjoint(transpose(adjoint(transpose(b))))
310+
a * b2
311+
end
292312
*(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, b::AbstractZerosMatrix) = (b' * a')'
293-
*(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, b::AbstractMatrix) = transpose(transpose(b) * transpose(a))
313+
for MT in (:AbstractMatrix, :AbstractTriangular, :(Transpose{<:Any,<:AdjointAbsVec}))
314+
@eval *(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, b::$MT) = transpose(transpose(b) * transpose(a))
315+
end
294316
*(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, b::AbstractZerosMatrix) = transpose(transpose(b) * transpose(a))
295317

296318
*(a::AbstractVector, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))
297-
*(a::AbstractMatrix, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))
319+
for MT in (:AbstractMatrix, :AbstractTriangular)
320+
@eval *(a::$MT, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))
321+
end
298322
*(a::AbstractZerosVector, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))
299323
*(a::AbstractZerosMatrix, b::AdjOrTransAbsVec{<:Any,<:AbstractZerosVector}) = a * permutedims(parent(b))
300324

@@ -305,7 +329,8 @@ end
305329

306330
*(a::Adjoint{T, <:AbstractMatrix{T}} where T, b::AbstractZeros{<:Any, 1}) = mult_zeros(a, b)
307331

308-
*(D::Diagonal, a::AdjointAbsVec{<:Any,<:AbstractZerosVector}) = (a' * D')'
332+
*(D::Diagonal, a::Adjoint{<:Any,<:AbstractZerosVector}) = (a' * D')'
333+
*(D::Diagonal, a::Transpose{<:Any,<:AbstractZerosVector}) = transpose(transpose(a) * transpose(D))
309334
*(a::AdjointAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal) = (D' * a')'
310335
*(a::TransposeAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal) = transpose(D*transpose(a))
311336
function _triple_zeromul(x, D::Diagonal, y)
@@ -323,7 +348,7 @@ end
323348
*(x::TransposeAbsVec{<:Any,<:AbstractZerosVector}, D::Diagonal, y::AbstractZerosVector) = _triple_zeromul(x, D, y)
324349

325350

326-
function *(a::Transpose{T, <:AbstractVector{T}}, b::AbstractZerosVector{T}) where T<:Real
351+
function *(a::Transpose{T, <:AbstractVector}, b::AbstractZerosVector{T}) where T<:Real
327352
la, lb = length(a), length(b)
328353
if la lb
329354
throw(DimensionMismatch("dot product arguments have lengths $la and $lb"))
@@ -496,3 +521,11 @@ function kron(f::AbstractFillVecOrMat, g::AbstractFillVecOrMat)
496521
sz = _kronsize(f, g)
497522
return _kron(f, g, sz)
498523
end
524+
525+
# bandedness
526+
function LinearAlgebra.istriu(A::AbstractFillMatrix, k::Integer = 0)
527+
iszero(A) || k <= -(size(A,1)-1)
528+
end
529+
function LinearAlgebra.istril(A::AbstractFillMatrix, k::Integer = 0)
530+
iszero(A) || k >= size(A,2)-1
531+
end

src/trues.jl

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,24 @@ Typically created using `Trues(dims)` or `Trues(dims...)`
77
88
# Example
99
```jldoctest
10-
julia> Trues(1,3)
11-
1×3 Ones{Bool,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}} = true
10+
julia> T = Trues(1,3)
11+
1×3 Ones{Bool}
1212
13-
julia> Trues((2,3))
14-
2×3 Ones{Bool,2,Tuple{Base.OneTo{Int64},Base.OneTo{Int64}}} = true
13+
julia> Array(T)
14+
1×3 Matrix{Bool}:
15+
1 1 1
1516
```
1617
"""
1718
const Trues = Ones{Bool, N, Axes} where {N, Axes}
1819

1920

20-
""" `Falses = Zeros{Bool, N, Axes}` (see `Trues`) """
21+
"""
22+
Falses = Zeros{Bool, N, Axes}
23+
24+
Lazy version of `falses` with axes.
25+
26+
See also: [`Trues`](@ref)
27+
"""
2128
const Falses = Zeros{Bool, N, Axes} where {N, Axes}
2229

2330

0 commit comments

Comments
 (0)