Skip to content

Commit 869b28a

Browse files
authored
Add LayoutArray (#7)
* Add LayoutArray * Increase coverage * Update triangular.jl * make layoutmatrix macro, move tests
1 parent a905b67 commit 869b28a

File tree

8 files changed

+121
-12
lines changed

8 files changed

+121
-12
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
*.jl.*.cov
33
*.jl.mem
44
deps/deps.jl
5+
Manifest.toml

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.1.5"
4+
version = "0.2.0"
55

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

src/ArrayLayouts.jl

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,14 +50,20 @@ export materialize, materialize!, MulAdd, muladd!, Ldiv, Rdiv, Lmul, Rmul, lmul,
5050
DenseColumnMajor, ColumnMajor, ZerosLayout, FillLayout, AbstractColumnMajor, RowMajor, AbstractRowMajor,
5151
DiagonalLayout, ScalarLayout, SymTridiagonalLayout, HermitianLayout, SymmetricLayout, TriangularLayout,
5252
UnknownLayout, AbstractBandedLayout, ApplyBroadcastStyle, ConjLayout, AbstractFillLayout,
53-
colsupport, rowsupport, lazy_getindex, QLayout
53+
colsupport, rowsupport, layout_getindex, QLayout, LayoutArray, LayoutMatrix, LayoutVector
5454

5555
struct ApplyBroadcastStyle <: BroadcastStyle end
5656
@inline function copyto!(dest::AbstractArray, bc::Broadcasted{ApplyBroadcastStyle})
5757
@assert length(bc.args) == 1
5858
copyto!(dest, first(bc.args))
5959
end
6060

61+
# Subtypes of LayoutArray default to
62+
# ArrayLayouts routines
63+
abstract type LayoutArray{T,N} <: AbstractArray{T,N} end
64+
const LayoutMatrix{T} = LayoutArray{T,2}
65+
const LayoutVector{T} = LayoutArray{T,1}
66+
6167
include("memorylayout.jl")
6268
include("muladd.jl")
6369
include("lmul.jl")
@@ -70,7 +76,27 @@ include("factorizations.jl")
7076
@inline sub_materialize(L, V) = sub_materialize(L, V, axes(V))
7177
@inline sub_materialize(V::SubArray) = sub_materialize(MemoryLayout(typeof(V)), V)
7278

73-
@inline lazy_getindex(A, I...) = sub_materialize(view(A, I...))
79+
@inline layout_getindex(A, I...) = sub_materialize(view(A, I...))
80+
81+
82+
83+
macro layoutmatrix(Typ)
84+
esc(quote
85+
ArrayLayouts.@layoutldiv $Typ
86+
ArrayLayouts.@layoutmul $Typ
87+
ArrayLayouts.@layoutlmul $Typ
88+
89+
@inline Base.getindex(A::$Typ, kr::Colon, jr::Colon) = ArrayLayouts.layout_getindex(A, kr, jr)
90+
@inline Base.getindex(A::$Typ, kr::Colon, jr::AbstractUnitRange) = ArrayLayouts.layout_getindex(A, kr, jr)
91+
@inline Base.getindex(A::$Typ, kr::AbstractUnitRange, jr::Colon) = ArrayLayouts.layout_getindex(A, kr, jr)
92+
@inline Base.getindex(A::$Typ, kr::AbstractUnitRange, jr::AbstractUnitRange) = ArrayLayouts.layout_getindex(A, kr, jr)
93+
@inline Base.getindex(A::$Typ, kr::AbstractVector, jr::AbstractVector) = ArrayLayouts.layout_getindex(A, kr, jr)
94+
@inline Base.getindex(A::$Typ, kr::Colon, jr::AbstractVector) = ArrayLayouts.layout_getindex(A, kr, jr)
95+
@inline Base.getindex(A::$Typ, kr::AbstractVector, jr::Colon) = ArrayLayouts.layout_getindex(A, kr, jr)
96+
end)
97+
end
98+
99+
@layoutmatrix LayoutMatrix
74100

75101
zero!(A::AbstractArray{T}) where T = fill!(A,zero(T))
76102
function zero!(A::AbstractArray{<:AbstractArray})

src/ldiv.jl

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,9 @@ end
6363
Rdiv(instantiate(L.A), instantiate(L.B))
6464
end
6565

66-
@inline _ldiv!(A, B) = ldiv!(factorize(A), B)
66+
__ldiv!(::Mat, ::Mat, B) where Mat = error("Overload ldiv! for $Mat")
67+
__ldiv!(_, F, B) = ldiv!(F, B)
68+
@inline _ldiv!(A, B) = __ldiv!(A, factorize(A), B)
6769
@inline _ldiv!(A::Factorization, B) = ldiv!(A, B)
6870

6971
@inline _ldiv!(dest, A, B) = ldiv!(dest, factorize(A), B)
@@ -97,7 +99,7 @@ const BlasMatRdivMat{styleA, styleB, T<:BlasFloat} = MatRdivMat{styleA, styleB,
9799
# end
98100

99101

100-
macro lazyldiv(Typ)
102+
macro _layoutldiv(Typ)
101103
esc(quote
102104
LinearAlgebra.ldiv!(A::$Typ, x::AbstractVector) = ArrayLayouts.materialize!(ArrayLayouts.Ldiv(A,x))
103105
LinearAlgebra.ldiv!(A::$Typ, x::AbstractMatrix) = ArrayLayouts.materialize!(ArrayLayouts.Ldiv(A,x))
@@ -121,3 +123,14 @@ macro lazyldiv(Typ)
121123
Base.:/(x::$Typ, A::$Typ) = ArrayLayouts.materialize(ArrayLayouts.Rdiv(x,A))
122124
end)
123125
end
126+
127+
macro layoutldiv(Typ)
128+
esc(quote
129+
ArrayLayouts.@_layoutldiv $Typ
130+
ArrayLayouts.@_layoutldiv UpperTriangular{T, <:$Typ{T}} where T
131+
ArrayLayouts.@_layoutldiv UnitUpperTriangular{T, <:$Typ{T}} where T
132+
ArrayLayouts.@_layoutldiv LowerTriangular{T, <:$Typ{T}} where T
133+
ArrayLayouts.@_layoutldiv UnitLowerTriangular{T, <:$Typ{T}} where T
134+
end)
135+
end
136+

src/lmul.jl

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ materialize!(M::Rmul) = rmul!(M.A,M.B)
6363

6464

6565

66-
macro lazylmul(Typ)
66+
macro _layoutlmul(Typ)
6767
esc(quote
6868
LinearAlgebra.lmul!(A::$Typ, x::AbstractVector) = ArrayLayouts.materialize!(ArrayLayouts.Lmul(A,x))
6969
LinearAlgebra.lmul!(A::$Typ, x::AbstractMatrix) = ArrayLayouts.materialize!(ArrayLayouts.Lmul(A,x))
@@ -72,5 +72,11 @@ macro lazylmul(Typ)
7272
end)
7373
end
7474

75-
76-
75+
macro layoutlmul(Typ)
76+
esc(quote
77+
ArrayLayouts.@_layoutlmul UpperTriangular{T, <:$Typ{T}} where T
78+
ArrayLayouts.@_layoutlmul UnitUpperTriangular{T, <:$Typ{T}} where T
79+
ArrayLayouts.@_layoutlmul LowerTriangular{T, <:$Typ{T}} where T
80+
ArrayLayouts.@_layoutlmul UnitLowerTriangular{T, <:$Typ{T}} where T
81+
end)
82+
end

src/muladd.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ end
406406

407407
mul(A::AbstractArray, B::AbstractArray) = materialize(MulAdd(A,B))
408408

409-
macro lazymul(Typ)
409+
macro layoutmul(Typ)
410410
ret = quote
411411
LinearAlgebra.mul!(dest::AbstractVector, A::$Typ, b::AbstractVector) =
412412
ArrayLayouts.mul!(dest,A,b)
@@ -461,4 +461,4 @@ macro lazymul(Typ)
461461
end
462462

463463
esc(ret)
464-
end
464+
end

src/triangular.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ function materialize!(M::MatLdivVec{<:TriangularLayout{'L','N'}})
212212
b
213213
end
214214

215-
function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'L','U'}})
215+
function materialize!(M::MatLdivVec{<:TriangularLayout{'L','U'}})
216216
A,b = M.A,M.B
217217
require_one_based_indexing(A, b)
218218
n = size(A, 2)

test/runtests.jl

Lines changed: 64 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,68 @@
11
using ArrayLayouts, Test
2+
import ArrayLayouts: MemoryLayout, @_layoutlmul, triangulardata
23

34
include("test_layouts.jl")
45
include("test_muladd.jl")
5-
include("test_ldiv.jl")
6+
include("test_ldiv.jl")
7+
8+
struct MyMatrix <: LayoutMatrix{Float64}
9+
A::Matrix{Float64}
10+
end
11+
12+
Base.getindex(A::MyMatrix, k::Int, j::Int) = A.A[k,j]
13+
Base.size(A::MyMatrix) = size(A.A)
14+
Base.strides(A::MyMatrix) = strides(A.A)
15+
Base.unsafe_convert(::Type{Ptr{T}}, A::MyMatrix) where T = Base.unsafe_convert(Ptr{T}, A.A)
16+
MemoryLayout(::Type{MyMatrix}) = DenseColumnMajor()
17+
18+
@testset "LayoutMatrix" begin
19+
A = MyMatrix(randn(5,5))
20+
for (kr,jr) in ((1:2,2:3), (:,:), (:,1:2), (2:3,:), ([1,2],3:4), (:,[1,2]), ([2,3],:))
21+
@test A[kr,jr] == A.A[kr,jr]
22+
end
23+
b = randn(5)
24+
for Tri in (UpperTriangular, UnitUpperTriangular, LowerTriangular, UnitLowerTriangular)
25+
@test ldiv!(Tri(A), copy(b)) ldiv!(Tri(A.A), copy(b))
26+
@test lmul!(Tri(A), copy(b)) lmul!(Tri(A.A), copy(b))
27+
end
28+
end
29+
30+
struct MyUpperTriangular{T} <: AbstractMatrix{T}
31+
A::UpperTriangular{T,Matrix{T}}
32+
end
33+
34+
MyUpperTriangular{T}(::UndefInitializer, n::Int, m::Int) where T = MyUpperTriangular{T}(UpperTriangular(Array{T}(undef, n, m)))
35+
MyUpperTriangular(A::AbstractMatrix{T}) where T = MyUpperTriangular{T}(UpperTriangular(Matrix{T}(A)))
36+
Base.convert(::Type{MyUpperTriangular{T}}, A::MyUpperTriangular{T}) where T = A
37+
Base.convert(::Type{MyUpperTriangular{T}}, A::MyUpperTriangular) where T = MyUpperTriangular(convert(AbstractArray{T}, A.A))
38+
Base.convert(::Type{MyUpperTriangular}, A::MyUpperTriangular)= A
39+
Base.convert(::Type{AbstractArray{T}}, A::MyUpperTriangular) where T = MyUpperTriangular(convert(AbstractArray{T}, A.A))
40+
Base.convert(::Type{AbstractMatrix{T}}, A::MyUpperTriangular) where T = MyUpperTriangular(convert(AbstractArray{T}, A.A))
41+
Base.convert(::Type{MyUpperTriangular{T}}, A::AbstractArray{T}) where T = MyUpperTriangular{T}(A)
42+
Base.convert(::Type{MyUpperTriangular{T}}, A::AbstractArray) where T = MyUpperTriangular{T}(convert(AbstractArray{T}, A))
43+
Base.convert(::Type{MyUpperTriangular}, A::AbstractArray{T}) where T = MyUpperTriangular{T}(A)
44+
Base.getindex(A::MyUpperTriangular, kj...) = A.A[kj...]
45+
Base.getindex(A::MyUpperTriangular, ::Colon, j::AbstractVector) = MyUpperTriangular(A.A[:,j])
46+
Base.setindex!(A::MyUpperTriangular, v, kj...) = setindex!(A.A, v, kj...)
47+
Base.size(A::MyUpperTriangular) = size(A.A)
48+
Base.similar(::Type{MyUpperTriangular{T}}, m::Int, n::Int) where T = MyUpperTriangular{T}(undef, m, n)
49+
Base.similar(::MyUpperTriangular{T}, m::Int, n::Int) where T = MyUpperTriangular{T}(undef, m, n)
50+
Base.similar(::MyUpperTriangular, ::Type{T}, m::Int, n::Int) where T = MyUpperTriangular{T}(undef, m, n)
51+
LinearAlgebra.factorize(A::MyUpperTriangular) = factorize(A.A)
52+
53+
MemoryLayout(::Type{MyUpperTriangular{T}}) where T = MemoryLayout(UpperTriangular{T,Matrix{T}})
54+
triangulardata(A::MyUpperTriangular) = triangulardata(A.A)
55+
56+
@_layoutlmul MyUpperTriangular
57+
58+
59+
@testset "MyUpperTriangular" begin
60+
A = randn(5,5)
61+
B = randn(5,5)
62+
x = randn(5)
63+
64+
@test lmul!(MyUpperTriangular(A), copy(x)) MyUpperTriangular(A) * x
65+
@test lmul!(MyUpperTriangular(A), copy(B)) MyUpperTriangular(A) * B
66+
67+
@test_skip lmul!(MyUpperTriangular(A),view(copy(B),collect(1:5),1:5)) MyUpperTriangular(A) * B
68+
end

0 commit comments

Comments
 (0)