Skip to content

Commit fd7e413

Browse files
jishnubdkarrasch
andauthored
Add transpose/adjoint specializations for block Bidiagonal (#1231)
With this, the adjoint of a block `Bidiagonal` will also be a `Bidiagonal`, following the behavior of a `Diagonal`. ```julia julia> m = rand(Int8, 2, 2) 2×2 Matrix{Int8}: -50 -123 -11 18 julia> B = Bidiagonal(fill(m,4), fill(m,3), :U) 4×4 Bidiagonal{Matrix{Int8}, Vector{Matrix{Int8}}}: [-50 -123; -11 18] [-50 -123; -11 18] … ⋅ ⋅ [-50 -123; -11 18] ⋅ ⋅ ⋅ [-50 -123; -11 18] ⋅ ⋅ [-50 -123; -11 18] julia> B' 4×4 Bidiagonal{Adjoint{Int8, Matrix{Int8}}, Vector{Adjoint{Int8, Matrix{Int8}}}}: [-50 -11; -123 18] ⋅ … ⋅ [-50 -11; -123 18] [-50 -11; -123 18] ⋅ ⋅ [-50 -11; -123 18] ⋅ ⋅ ⋅ [-50 -11; -123 18] julia> B'' 4×4 Bidiagonal{Matrix{Int8}, Vector{Matrix{Int8}}}: [-50 -123; -11 18] [-50 -123; -11 18] … ⋅ ⋅ [-50 -123; -11 18] ⋅ ⋅ ⋅ [-50 -123; -11 18] ⋅ ⋅ [-50 -123; -11 18] ``` --------- Co-authored-by: Daniel Karrasch <daniel.karrasch@posteo.de>
1 parent c4a477f commit fd7e413

File tree

2 files changed

+15
-22
lines changed

2 files changed

+15
-22
lines changed

src/bidiag.jl

Lines changed: 2 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -311,20 +311,14 @@ isreal(M::Bidiagonal) = isreal(M.dv) && isreal(M.ev)
311311
adjoint(B::Bidiagonal{<:Number}) = Bidiagonal(vec(adjoint(B.dv)), vec(adjoint(B.ev)), B.uplo == 'U' ? :L : :U)
312312
adjoint(B::Bidiagonal{<:Number, <:Base.ReshapedArray{<:Number,1,<:Adjoint}}) =
313313
Bidiagonal(adjoint(parent(B.dv)), adjoint(parent(B.ev)), B.uplo == 'U' ? :L : :U)
314+
adjoint(B::Bidiagonal) = Bidiagonal(adjoint.(B.dv), adjoint.(B.ev), B.uplo == 'U' ? :L : :U)
314315
transpose(B::Bidiagonal{<:Number}) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? :L : :U)
316+
transpose(B::Bidiagonal) = Bidiagonal(transpose.(B.dv), transpose.(B.ev), B.uplo == 'U' ? :L : :U)
315317
permutedims(B::Bidiagonal) = Bidiagonal(B.dv, B.ev, B.uplo == 'U' ? 'L' : 'U')
316318
function permutedims(B::Bidiagonal, perm)
317319
Base.checkdims_perm(axes(B), axes(B), perm)
318320
NTuple{2}(perm) == (2, 1) ? permutedims(B) : B
319321
end
320-
function Base.copy(aB::Adjoint{<:Any,<:Bidiagonal})
321-
B = aB.parent
322-
return Bidiagonal(map(x -> copy.(adjoint.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U)
323-
end
324-
function Base.copy(tB::Transpose{<:Any,<:Bidiagonal})
325-
B = tB.parent
326-
return Bidiagonal(map(x -> copy.(transpose.(x)), (B.dv, B.ev))..., B.uplo == 'U' ? :L : :U)
327-
end
328322

329323
@noinline function throw_zeroband_error(A)
330324
uplo = A.uplo
@@ -1362,14 +1356,10 @@ function ldiv!(c::AbstractVecOrMat, A::Bidiagonal, b::AbstractVecOrMat)
13621356
end
13631357
return c
13641358
end
1365-
ldiv!(A::AdjOrTrans{<:Any,<:Bidiagonal}, b::AbstractVecOrMat) = @inline ldiv!(b, A, b)
1366-
ldiv!(c::AbstractVecOrMat, A::AdjOrTrans{<:Any,<:Bidiagonal}, b::AbstractVecOrMat) =
1367-
(t = wrapperop(A); _rdiv!(t(c), t(b), t(A)); return c)
13681359

13691360
### Generic promotion methods and fallbacks
13701361
\(A::Bidiagonal, B::AbstractVecOrMat) =
13711362
ldiv!(matprod_dest(A, B, promote_op(\, eltype(A), eltype(B))), A, B)
1372-
\(xA::AdjOrTrans{<:Any,<:Bidiagonal}, B::AbstractVecOrMat) = copy(xA) \ B
13731363

13741364
### Triangular specializations
13751365
for tri in (:UpperTriangular, :UnitUpperTriangular)
@@ -1441,9 +1431,6 @@ function _rdiv!(C::AbstractMatrix, A::AbstractMatrix, B::Bidiagonal)
14411431
C
14421432
end
14431433
rdiv!(A::AbstractMatrix, B::Bidiagonal) = @inline _rdiv!(A, A, B)
1444-
rdiv!(A::AbstractMatrix, B::AdjOrTrans{<:Any,<:Bidiagonal}) = @inline _rdiv!(A, A, B)
1445-
_rdiv!(C::AbstractMatrix, A::AbstractMatrix, B::AdjOrTrans{<:Any,<:Bidiagonal}) =
1446-
(t = wrapperop(B); ldiv!(t(C), t(B), t(A)); return C)
14471434

14481435
/(A::AbstractMatrix, B::Bidiagonal) =
14491436
_rdiv!(similar(A, promote_op(/, eltype(A), eltype(B)), size(A)), A, B)
@@ -1476,15 +1463,9 @@ function /(D::Diagonal, B::Bidiagonal)
14761463
return B.uplo == 'U' ? UpperTriangular(A) : LowerTriangular(A)
14771464
end
14781465

1479-
/(A::AbstractMatrix, B::Transpose{<:Any,<:Bidiagonal}) = A / copy(B)
1480-
/(A::AbstractMatrix, B::Adjoint{<:Any,<:Bidiagonal}) = A / copy(B)
14811466
# disambiguation
14821467
/(A::AdjointAbsVec, B::Bidiagonal) = adjoint(adjoint(B) \ parent(A))
14831468
/(A::TransposeAbsVec, B::Bidiagonal) = transpose(transpose(B) \ parent(A))
1484-
/(A::AdjointAbsVec, B::Transpose{<:Any,<:Bidiagonal}) = adjoint(adjoint(B) \ parent(A))
1485-
/(A::TransposeAbsVec, B::Transpose{<:Any,<:Bidiagonal}) = transpose(transpose(B) \ parent(A))
1486-
/(A::AdjointAbsVec, B::Adjoint{<:Any,<:Bidiagonal}) = adjoint(adjoint(B) \ parent(A))
1487-
/(A::TransposeAbsVec, B::Adjoint{<:Any,<:Bidiagonal}) = transpose(transpose(B) \ parent(A))
14881469

14891470
factorize(A::Bidiagonal) = A
14901471
function inv(B::Bidiagonal{T}) where T

test/bidiag.jl

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -807,7 +807,7 @@ end
807807
@test convert(AbstractMatrix{Float64}, Bl)::Bidiagonal{Float64,ImmutableArray{Float64,1,Array{Float64,1}}} == Bl
808808
end
809809

810-
@testset "block-bidiagonal matrix indexing" begin
810+
@testset "block-bidiagonal matrix" begin
811811
dv = [ones(4,3), ones(2,2).*2, ones(2,3).*3, ones(4,4).*4]
812812
evu = [ones(4,2), ones(2,3).*2, ones(2,4).*3]
813813
evl = [ones(2,3), ones(2,2).*2, ones(4,3).*3]
@@ -847,6 +847,18 @@ end
847847
@test @inferred(B[2,1]) isa typeof(s)
848848
@test all(iszero, B[2,1])
849849
end
850+
851+
@testset "adjoint/transpose" begin
852+
m = rand(Int, 2, 2)
853+
for uplo in [:U, :L]
854+
B = Bidiagonal(fill(m,4), fill(m,3), uplo)
855+
A = Array{Matrix{Int}}(B)
856+
@testset for f in (adjoint, transpose)
857+
@test f(B) == f(A)
858+
@test f(f(B)) == B
859+
end
860+
end
861+
end
850862
end
851863

852864
@testset "copyto!" begin

0 commit comments

Comments
 (0)