Skip to content

Commit d4dcecd

Browse files
authored
Allow trans/adj in triangular ldiv! (#383)
* Allow trans/adj in triangular ldiv! * Update matmul.jl * Update Project.toml * Use dualadjoint * Increase codecov * banded and dense matrix tests
1 parent 23c358f commit d4dcecd

File tree

9 files changed

+86
-17
lines changed

9 files changed

+86
-17
lines changed

Project.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ BandedMatricesSparseArraysExt = "SparseArrays"
1717

1818
[compat]
1919
Aqua = "0.6"
20-
ArrayLayouts = "1"
20+
ArrayLayouts = "1.1"
2121
Documenter = "0.27"
2222
FillArrays = "1.3"
2323
InfiniteArrays = "0.12"

src/BandedMatrices.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import ArrayLayouts: MemoryLayout, transposelayout, triangulardata,
3232
sublayout, sub_materialize, _fill_lmul!, _copy_oftype,
3333
reflector!, reflectorApply!, _copyto!, checkdimensions,
3434
_qr!, _qr, _lu!, _lu, _factorize, AbstractTridiagonalLayout, TridiagonalLayout,
35-
BidiagonalLayout, bidiagonaluplo, diagonaldata, supdiagonaldata, subdiagonaldata
35+
BidiagonalLayout, bidiagonaluplo, diagonaldata, supdiagonaldata, subdiagonaldata, copymutable_oftype_layout, dualadjoint
3636

3737
import FillArrays: AbstractFill, getindex_value, _broadcasted_zeros, unique_value, OneElement
3838

src/banded/BandedMatrix.jl

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -148,15 +148,16 @@ convert(::Type{DefaultBandedMatrix}, M::AbstractMatrix{T}) where T = convert(Def
148148

149149
copy(B::BandedMatrix) = _BandedMatrix(copy(B.data), B.raxis, B.l, B.u)
150150

151-
if isdefined(LinearAlgebra, :copymutable_oftype)
152-
LinearAlgebra.copymutable_oftype(B::BandedMatrix, ::Type{S}) where S =
153-
_BandedMatrix(LinearAlgebra.copymutable_oftype(B.data, S), B.raxis, B.l, B.u)
154151

155-
LinearAlgebra.copymutable_oftype(B::Adjoint{<:Any,<:BandedMatrix}, ::Type{S}) where S =
156-
LinearAlgebra.copymutable_oftype(parent(B), S)'
157-
LinearAlgebra.copymutable_oftype(B::Transpose{<:Any,<:BandedMatrix}, ::Type{S}) where S =
158-
transpose(LinearAlgebra.copymutable_oftype(parent(B), S))
159-
end
152+
copymutable_oftype_layout(::BandedColumns, B, ::Type{S}) where S =
153+
_BandedMatrix(LinearAlgebra.copymutable_oftype(bandeddata(B), S), axes(B,1), bandwidths(B)...)
154+
155+
copymutable_oftype_layout(::BandedRows, B, ::Type{S}) where S =
156+
dualadjoint(B)(LinearAlgebra.copymutable_oftype(parent(B), S))
157+
158+
copymutable_oftype_layout(::AbstractBandedLayout, B, ::Type{S}) where S =
159+
copyto!(BandedMatrix{S}(undef, axes(B), bandwidths(B)), B)
160+
160161

161162
promote_rule(::Type{BandedMatrix{T1, C1}}, ::Type{BandedMatrix{T2, C2}}) where {T1,C1, T2,C2} =
162163
BandedMatrix{promote_type(T1,T2), promote_type(C1, C2)}

src/generic/matmul.jl

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ end
239239

240240
### BandedMatrix * dense matrix
241241

242-
function materialize!(M::MulAdd{BandedColumns{DenseColumnMajor}, <:AbstractColumnMajor, <:AbstractColumnMajor,
242+
function materialize!(M::MulAdd{<:BandedColumns, <:AbstractColumnMajor, <:AbstractColumnMajor,
243243
T, <:AbstractMatrix, <:AbstractMatrix, <:AbstractMatrix}) where {T}
244244
α, β, A, B, C = M.α, M.β, M.A, M.B, M.C
245245

@@ -258,3 +258,22 @@ function materialize!(M::MulAdd{BandedColumns{DenseColumnMajor}, <:AbstractColum
258258

259259
return C
260260
end
261+
262+
function materialize!(M::MulAdd{<:AbstractColumnMajor, <:BandedColumns, <:AbstractColumnMajor,
263+
T, <:AbstractMatrix, <:AbstractMatrix, <:AbstractMatrix}) where {T}
264+
α, β, A, B, C = M.α, M.β, M.A, M.B, M.C
265+
mA, nA = size(A)
266+
mB, nB = size(B)
267+
mC, nC = size(C)
268+
(nA == mB && mC == mA && nC == nB) || throw(DimensionMismatch("A has size ($mA, $nA), B has size ($mB, $nB), C has size ($mC, $nC)"))
269+
270+
if iszero(α)
271+
lmul!(β, C)
272+
else
273+
for (rowC, rowA) in zip(eachrow(C), eachrow(A))
274+
mul!(rowC, transpose(B), rowA, α, β)
275+
end
276+
end
277+
278+
return C
279+
end

src/tribanded.jl

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -79,17 +79,27 @@ end
7979
# Ldiv
8080
for UNIT in ('N', 'U')
8181
@eval begin
82-
@inline function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'U',$UNIT,<:BandedColumnMajor},
83-
<:AbstractStridedLayout})
82+
@inline function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'U',$UNIT,<:BandedColumnMajor}, <:AbstractStridedLayout})
8483
A,x = M.A,M.B
8584
tbsv!('U', 'N', $UNIT, size(A,1), bandwidth(A,2), bandeddata(A), x)
8685
end
8786

88-
@inline function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'L',$UNIT,<:BandedColumnMajor},
89-
<:AbstractStridedLayout})
87+
@inline function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'L',$UNIT,<:BandedColumnMajor}, <:AbstractStridedLayout})
9088
A,x = M.A,M.B
9189
tbsv!('L', 'N', $UNIT, size(A,1), bandwidth(A,1), bandeddata(A), x)
9290
end
91+
92+
@inline function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'U',$UNIT,<:BandedRowMajor}, <:AbstractStridedLayout})
93+
U,x = M.A,M.B
94+
A = triangulardata(U)
95+
tbsv!('L', 'T', $UNIT, size(A,1), bandwidth(A,2), bandeddata(LowerTriangular(A')), x)
96+
end
97+
98+
@inline function materialize!(M::BlasMatLdivVec{<:TriangularLayout{'L',$UNIT,<:BandedRowMajor}, <:AbstractStridedLayout})
99+
L,x = M.A,M.B
100+
A = triangulardata(L)
101+
tbsv!('U', 'T', $UNIT, size(A,1), bandwidth(A,1), bandeddata(UpperTriangular(A')), x)
102+
end
93103
end
94104
# for UPLO in ('U', 'L')
95105
# @eval begin

test/test_banded.jl

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -508,13 +508,15 @@ Base.similar(::MyMatrix, ::Type{T}, m::Int, n::Int) where T = MyMatrix{T}(undef,
508508

509509
if isdefined(LinearAlgebra, :copymutable_oftype)
510510
@testset "copymutable_oftype" begin
511-
B = _BandedMatrix((2:3)', 4, -2, 2)
511+
B = _BandedMatrix((2:5)', 4, -2, 2)
512512
@test LinearAlgebra.copymutable_oftype(B, Float64) == B
513513
@test LinearAlgebra.copymutable_oftype(B, Float64) isa BandedMatrix{Float64}
514514
@test LinearAlgebra.copymutable_oftype(B', Float64) == B'
515515
@test LinearAlgebra.copymutable_oftype(B', Float64) isa Adjoint{Float64,<:BandedMatrix{Float64}}
516516
@test LinearAlgebra.copymutable_oftype(transpose(B), Float64) == transpose(B)
517517
@test LinearAlgebra.copymutable_oftype(transpose(B), Float64) isa Transpose{Float64,<:BandedMatrix{Float64}}
518+
519+
@test LinearAlgebra.copymutable_oftype(UpperTriangular(B), Float64) == B
518520
end
519521
end
520522
end

test/test_interface.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -205,6 +205,12 @@ LinearAlgebra.fill!(A::PseudoBandedMatrix, v) = fill!(A.data,v)
205205
bandwidths(convert(BandedMatrix{Float64}, A)) ==
206206
bandwidths(convert(BandedMatrix{Float64,Matrix{Float64}},A)) ==
207207
bandwidths(A)
208+
209+
@testset "copymutable_oftype" begin
210+
A = PseudoBandedMatrix(rand(5, 4), 1, 2)
211+
@test ArrayLayouts.copymutable_oftype_layout(MemoryLayout(A), A, BigFloat) == A
212+
@test ArrayLayouts.copymutable_oftype_layout(MemoryLayout(A), A, BigFloat) isa BandedMatrix
213+
end
208214
end
209215

210216
@testset "Bi/Tri/Diagonal" begin

test/test_linalg.jl

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,5 +426,12 @@ import BandedMatrices: BandedColumns, _BandedMatrix
426426
end
427427
end
428428
end
429+
430+
@testset "mul with α = 0" begin
431+
A = randn(5,5)
432+
B = brand(5,5,1,2)
433+
@test muladd!(0.0, A, B, 2.0, copy(A)) == 2A
434+
@test muladd!(0.0, B, A, 2.0, copy(A)) == 2A
435+
end
429436
end
430437

test/test_tribanded.jl

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,31 @@ import BandedMatrices: BandedColumns, BandedRows
7373
A = brand(5,5,2,1)
7474
b = randn(5)
7575
U = UpperTriangular(A')
76+
L = LowerTriangular(A')
77+
= LowerTriangular(A)'
78+
= UpperTriangular(A)'
7679
@test MemoryLayout(U) isa TriangularLayout{'U','N',BandedRows{DenseColumnMajor}}
77-
@test ArrayLayouts.lmul!(U,copy(b)) U*b
80+
@test U*b ArrayLayouts.lmul!(U,copy(b)) Matrix(U)*b
81+
@test L*b ArrayLayouts.lmul!(L,copy(b)) Matrix(L)*b
82+
@test ldiv!(U,copy(b)) ArrayLayouts.ldiv!(U,copy(b)) U\b Matrix(U)\b
83+
@test ldiv!(L,copy(b)) ArrayLayouts.ldiv!(L,copy(b)) L\b Matrix(L)\b
84+
@test ldiv!(Ũ,copy(b)) ArrayLayouts.ldiv!(Ũ,copy(b)) \b Matrix(Ũ)\b
85+
@test ldiv!(L̃,copy(b)) ArrayLayouts.ldiv!(L̃,copy(b)) \b Matrix(L̃)\b
86+
87+
B = randn(5,5)
88+
89+
@test U*B ArrayLayouts.lmul!(U,copy(B)) Matrix(U)*B
90+
@test L*B ArrayLayouts.lmul!(L,copy(B)) Matrix(L)*B
91+
@test B*U ArrayLayouts.rmul!(copy(B),U) B*Matrix(U)
92+
@test B*L ArrayLayouts.rmul!(copy(B),L) B*Matrix(L)
93+
94+
@test U \ B Matrix(U) \ B
95+
@test B / U B / Matrix(U)
96+
@test L \ B Matrix(L) \ B
97+
@test B / L B / Matrix(L)
98+
@test\ B Matrix(Ũ) \ B
99+
@test B / B / Matrix(Ũ)
100+
@test\ B Matrix(L̃) \ B
101+
@test B / B / Matrix(L̃)
78102
end
79103
end

0 commit comments

Comments
 (0)