Skip to content

Commit 1d0a09f

Browse files
authored
Turn broken rdiv tests to proper tests, optimize ldiv by diagonal (#113)
1 parent aa9532a commit 1d0a09f

File tree

5 files changed

+43
-17
lines changed

5 files changed

+43
-17
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
name = "ArrayLayouts"
22
uuid = "4c555306-a7a7-4459-81d9-ec55ddd5c99a"
33
authors = ["Sheehan Olver <[email protected]>"]
4-
version = "0.8.13"
4+
version = "0.8.14"
55

66
[deps]
77
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"

README.md

Lines changed: 16 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,15 @@
11
# ArrayLayouts.jl
2+
23
A Julia package for describing array layouts and more general fast linear algebra
34

45
[![Build Status](https://github.com/JuliaLinearAlgebra/ArrayLayouts.jl/workflows/CI/badge.svg)](https://github.com/JuliaMatrices/ArrayLayouts.jl/actions)
56
[![codecov](https://codecov.io/gh/JuliaLinearAlgebra/ArrayLayouts.jl/branch/master/graph/badge.svg)](https://codecov.io/gh/JuliaMatrices/ArrayLayouts.jl)
67

7-
This package implements a trait-based framework for describing array layouts such as column major, row major, etc. that can be dispatched
8-
to appropriate BLAS or optimised Julia linear algebra routines. This supports a much wider class of matrix types than Julia's in-built `StridedArray`. Here is an example:
8+
This package implements a trait-based framework for describing array layouts such as column
9+
major, row major, etc. that can be dispatched to appropriate BLAS or optimised Julia linear
10+
algebra routines. This supports a much wider class of matrix types than Julia's in-built
11+
`StridedArray`. Here is an example:
12+
913
```julia
1014
julia> using ArrayLayouts
1115

@@ -22,7 +26,9 @@ julia> @time muladd!(1.0, V, x, 0.0, y); # ArrayLayouts does and is 3x faster as
2226

2327
## Internal design
2428

25-
The package is based on assigning a `MemoryLayout` to every array, which is used for dispatch. For example,
29+
The package is based on assigning a `MemoryLayout` to every array, which is used for
30+
dispatch. For example,
31+
2632
```julia
2733
julia> MemoryLayout(A) # Each column of A is column major, and columns stored in order
2834
DenseColumnMajor()
@@ -34,9 +40,11 @@ julia> MemoryLayout(V) # A symmetric version, whose storage is DenseColumnMajor
3440
SymmetricLayout{DenseColumnMajor}()
3541
```
3642

37-
This is then used by `muladd!(α, A, B, β, C)`, `ArrayLayouts.lmul!(A, B)`, and `ArrayLayouts.rmul!(A, B)` to
38-
lower to the correct BLAS calls via lazy objects `MulAdd(α, A, B, β, C)`, `Lmul(A, B)`, `Rmul(A, B)` which are materialized,
39-
in analogy to `Base.Broadcasted`.
43+
This is then used by `muladd!(α, A, B, β, C)`, `ArrayLayouts.lmul!(A, B)`, and
44+
`ArrayLayouts.rmul!(A, B)` to lower to the correct BLAS calls via lazy objects
45+
`MulAdd(α, A, B, β, C)`, `Lmul(A, B)`, `Rmul(A, B)` which are materialized, in analogy to
46+
`Base.Broadcasted`.
4047

41-
Note there is also a higher level function `mul(A, B)` that materializes via `Mul(A, B)`, which uses the layout of `A` and `B`
42-
to further reduce to either `MulAdd`, `Lmul`, and `Rmul`.
48+
Note there is also a higher level function `mul(A, B)` that materializes via `Mul(A, B)`,
49+
which uses the layout of `A` and `B` to further reduce to either `MulAdd`, `Lmul`, and
50+
`Rmul`.

src/diagonal.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,8 @@ function materialize!(M::Ldiv{<:DiagonalLayout})
3535
M.B
3636
end
3737

38-
copy(M::Ldiv{<:DiagonalLayout,<:DiagonalLayout}) = diagonal(inv.(M.A.diag) .* M.B.diag)
39-
copy(M::Ldiv{<:DiagonalLayout}) = inv.(M.A.diag) .* M.B
38+
copy(M::Ldiv{<:DiagonalLayout,<:DiagonalLayout}) = diagonal(M.A.diag .\ M.B.diag)
39+
copy(M::Ldiv{<:DiagonalLayout}) = M.A.diag .\ M.B
4040
copy(M::Ldiv{<:DiagonalLayout{<:AbstractFillLayout}}) = inv(getindex_value(M.A.diag)) .* M.B
4141
copy(M::Ldiv{<:DiagonalLayout{<:AbstractFillLayout},<:DiagonalLayout}) = diagonal(inv(getindex_value(M.A.diag)) .* M.B.diag)
4242

src/ldiv.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ macro _layoutldiv(Typ)
143143
(\)(A::$Typ, x::AbstractMatrix) = ArrayLayouts.ldiv(A,x)
144144

145145
(\)(x::AbstractMatrix, A::$Typ) = ArrayLayouts.ldiv(x,A)
146+
(\)(x::LinearAlgebra.HermOrSym, A::$Typ) = ArrayLayouts.ldiv(x,A)
147+
if VERSION < v"1.9-" # disambiguation
148+
\(x::LinearAlgebra.HermOrSym{<:Any,<:StridedMatrix}, A::$Typ) = ArrayLayouts.ldiv(x,A)
149+
end
146150
(\)(x::UpperTriangular, A::$Typ) = ArrayLayouts.ldiv(x,A)
147151
(\)(x::UnitUpperTriangular, A::$Typ) = ArrayLayouts.ldiv(x,A)
148152
(\)(x::LowerTriangular, A::$Typ) = ArrayLayouts.ldiv(x,A)

test/test_layoutarray.jl

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,7 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor()
9494
@test lu!(copy(A)).factors lu(A.A).factors
9595
b = randn(5)
9696
@test all(A \ b .≡ A.A \ b .≡ A.A \ MyVector(b) .≡ ldiv!(lu(A.A), copy(MyVector(b))))
97+
@test all(A \ b .≡ ldiv!(lu(A), copy(MyVector(b))) .≡ ldiv!(lu(A), copy(b)))
9798
@test all(lu(A).L .≡ lu(A.A).L)
9899
@test all(lu(A).U .≡ lu(A.A).U)
99100
@test lu(A).p == lu(A.A).p
@@ -105,13 +106,26 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor()
105106
S = Symmetric(MyMatrix(reshape(inv.(1:25),5,5) + 10I))
106107
@test cholesky(S).U @inferred(cholesky!(deepcopy(S))).U
107108
@test cholesky(S, CRowMaximum()).U cholesky(Matrix(S), CRowMaximum()).U
109+
@test cholesky!(deepcopy(S), CRowMaximum()).U cholesky(Matrix(S), CRowMaximum()).U
108110
@test cholesky(S) \ b cholesky(Matrix(S)) \ b cholesky(Matrix(S)) \ MyVector(b)
109111
@test cholesky(S, CRowMaximum()) \ b cholesky(Matrix(S), CRowMaximum()) \ b
110112
@test cholesky(S, CRowMaximum()) \ b ldiv!(cholesky(Matrix(S), CRowMaximum()), copy(MyVector(b)))
111-
112-
S = Symmetric(MyMatrix(reshape(inv.(1:25),5,5) + 10I),:L)
113+
@test cholesky(S) \ b Matrix(S) \ b Symmetric(Matrix(S)) \ b
114+
@test cholesky(S) \ b Symmetric(Matrix(S)) \ MyVector(b)
115+
if VERSION >= v"1.9-"
116+
@test S \ b Matrix(S) \ b Symmetric(Matrix(S)) \ b
117+
@test S \ b Symmetric(Matrix(S)) \ MyVector(b)
118+
end
119+
120+
S = Symmetric(MyMatrix(reshape(inv.(1:25),5,5) + 10I), :L)
113121
@test cholesky(S).U @inferred(cholesky!(deepcopy(S))).U
114122
@test cholesky(S,CRowMaximum()).U cholesky(Matrix(S),CRowMaximum()).U
123+
@test cholesky(S) \ b Matrix(S) \ b Symmetric(Matrix(S), :L) \ b
124+
@test cholesky(S) \ b Symmetric(Matrix(S), :L) \ MyVector(b)
125+
if VERSION >= v"1.9-"
126+
@test S \ b Matrix(S) \ b Symmetric(Matrix(S), :L) \ b
127+
@test S \ b Symmetric(Matrix(S), :L) \ MyVector(b)
128+
end
115129
end
116130
Bin = randn(5,5)
117131
B = MyMatrix(copy(Bin))
@@ -173,18 +187,18 @@ MemoryLayout(::Type{MyVector}) = DenseColumnMajor()
173187
@test_broken ldiv!(A, t) A\t
174188
@test ldiv!(A, copy(X)) A\X
175189
@test A\T A\
176-
@test_broken A/T A/
190+
VERSION >= v"1.9-" && @test A/T A/
177191
@test_broken ldiv!(A, T) A\T
178192
@test B\A B\Matrix(A)
179193
@test D \ A D \ Matrix(A)
180194
@test transpose(B)\A transpose(B)\Matrix(A) Transpose(B)\A Adjoint(B)\A
181195
@test B'\A B'\Matrix(A)
182196
@test A\A I
183-
@test_broken A/A I
197+
VERSION >= v"1.9-" && @test A/A I
184198
@test A\MyVector(x) A\x
185199
@test A\MyMatrix(X) A\X
186200

187-
@test_broken A/A A.A / A.A
201+
VERSION >= v"1.9-" && @test A/A A.A / A.A
188202
end
189203

190204
@testset "dot" begin
@@ -392,5 +406,5 @@ triangulardata(A::MyUpperTriangular) = triangulardata(A.A)
392406
@test_skip lmul!(U,view(copy(B),collect(1:5),1:5)) U * B
393407

394408
@test MyMatrix(A) / U A / U
395-
@test_broken U / MyMatrix(A) U / A
409+
VERSION >= v"1.9-" && @test U / MyMatrix(A) U / A
396410
end

0 commit comments

Comments
 (0)