Skip to content

Commit a5b61f2

Browse files
authored
Fix banded-diagonal Lmul/Rmul copy (#255)
* Fix banded-diagonal `Lmul`/`Rmul` copy * Add tests for lower Bidiagonal * Add comments
1 parent 96b1c5d commit a5b61f2

File tree

3 files changed

+39
-14
lines changed

3 files changed

+39
-14
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 = "1.11.0"
4+
version = "1.11.1"
55

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

src/diagonal.jl

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -63,28 +63,47 @@ _similar(A::SymTridiagonal) = similar(Tridiagonal(A.ev, A.dv, A.ev))
6363
_copy_diag(M::T, ::T) where {T<:Rmul} = copyto!(_similar(M.A), M)
6464
_copy_diag(M::T, ::T) where {T<:Lmul} = copyto!(_similar(M.B), M)
6565
_copy_diag(M, _) = copy(M)
66+
_bidiagonal(A::Bidiagonal) = A
67+
function _bidiagonal(A)
68+
# we assume that the matrix is indeed bidiagonal,
69+
# so that the conversion is lossless
70+
if iszero(view(A, diagind(A, -1)))
71+
uplo = :U
72+
else
73+
uplo = :L
74+
end
75+
Bidiagonal(A, uplo)
76+
end
6677
function copy(M::Rmul{<:BidiagonalLayout,<:DiagonalLayout})
67-
A = convert(Bidiagonal, M.A)
78+
A = _bidiagonal(M.A)
6879
_copy_diag(Rmul(A, M.B), M)
6980
end
7081
function copy(M::Lmul{<:DiagonalLayout,<:BidiagonalLayout})
71-
B = convert(Bidiagonal, M.B)
82+
B = _bidiagonal(M.B)
7283
_copy_diag(Lmul(M.A, B), M)
7384
end
85+
# we assume that the matrix is indeed tridiagonal,
86+
# so that the conversion is lossless
87+
_tridiagonal(A::Tridiagonal) = A
88+
_tridiagonal(A) = Tridiagonal(A)
7489
function copy(M::Rmul{<:TridiagonalLayout,<:DiagonalLayout})
75-
A = convert(Tridiagonal, M.A)
90+
A = _tridiagonal(M.A)
7691
_copy_diag(Rmul(A, M.B), M)
7792
end
7893
function copy(M::Lmul{<:DiagonalLayout,<:TridiagonalLayout})
79-
B = convert(Tridiagonal, M.B)
94+
B = _tridiagonal(M.B)
8095
_copy_diag(Lmul(M.A, B), M)
8196
end
97+
# we assume that the matrix is indeed symmetric tridiagonal,
98+
# so that the conversion is lossless
99+
_symtridiagonal(A::SymTridiagonal) = A
100+
_symtridiagonal(A) = SymTridiagonal(A)
82101
function copy(M::Rmul{<:SymTridiagonalLayout,<:DiagonalLayout})
83-
A = convert(SymTridiagonal, M.A)
102+
A = _symtridiagonal(M.A)
84103
_copy_diag(Rmul(A, M.B), M)
85104
end
86105
function copy(M::Lmul{<:DiagonalLayout,<:SymTridiagonalLayout})
87-
B = convert(SymTridiagonal, M.B)
106+
B = _symtridiagonal(M.B)
88107
_copy_diag(Lmul(M.A, B), M)
89108
end
90109

test/test_layoutarray.jl

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -338,18 +338,24 @@ Base.copy(A::MyVector) = MyVector(copy(A.A))
338338

339339
@testset "Diagonal * Bidiagonal/Tridiagonal with structured diags" begin
340340
n = size(D,1)
341-
B = Bidiagonal(map(MyVector, (rand(n), rand(n-1)))..., :U)
342-
MB = MyMatrix(B)
341+
BU = Bidiagonal(map(MyVector, (rand(n), rand(n-1)))..., :U)
342+
MBU = MyMatrix(BU)
343+
BL = Bidiagonal(map(MyVector, (rand(n), rand(n-1)))..., :L)
344+
MBL = MyMatrix(BL)
343345
S = SymTridiagonal(map(MyVector, (rand(n), rand(n-1)))...)
344346
MS = MyMatrix(S)
345347
T = Tridiagonal(map(MyVector, (rand(n-1), rand(n), rand(n-1)))...)
346348
MT = MyMatrix(T)
347-
DA, BA, SA, TA = map(Array, (D, B, S, T))
349+
DA, BUA, BLA, SA, TA = map(Array, (D, BU, BL, S, T))
348350
if VERSION >= v"1.11"
349-
@test D * B DA * BA
350-
@test B * D BA * DA
351-
@test D * MB DA * BA
352-
@test MB * D BA * DA
351+
@test D * BU DA * BUA
352+
@test BU * D BUA * DA
353+
@test D * MBU DA * BUA
354+
@test MBU * D BUA * DA
355+
@test D * BL DA * BLA
356+
@test BL * D BLA * DA
357+
@test D * MBL DA * BLA
358+
@test MBL * D BLA * DA
353359
end
354360
if VERSION >= v"1.12.0-DEV.824"
355361
@test D * S DA * SA

0 commit comments

Comments
 (0)