Skip to content

Commit 3adc6f3

Browse files
KlausCstaticfloat
authored andcommitted
Permit Bidiagonal represents empty matrix (#38392)
(cherry picked from commit 293e60c)
1 parent 18711ab commit 3adc6f3

File tree

4 files changed

+53
-9
lines changed

4 files changed

+53
-9
lines changed

stdlib/LinearAlgebra/src/bidiag.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct Bidiagonal{T,V<:AbstractVector{T}} <: AbstractMatrix{T}
77
uplo::Char # upper bidiagonal ('U') or lower ('L')
88
function Bidiagonal{T,V}(dv, ev, uplo::AbstractChar) where {T,V<:AbstractVector{T}}
99
require_one_based_indexing(dv, ev)
10-
if length(ev) != length(dv)-1
10+
if length(ev) != max(length(dv)-1, 0)
1111
throw(DimensionMismatch("length of diagonal vector is $(length(dv)), length of off-diagonal vector is $(length(ev))"))
1212
end
1313
new{T,V}(dv, ev, uplo)
@@ -352,7 +352,7 @@ function diag(M::Bidiagonal, n::Integer=0)
352352
end
353353

354354
function +(A::Bidiagonal, B::Bidiagonal)
355-
if A.uplo == B.uplo
355+
if A.uplo == B.uplo || length(A.dv) == 0
356356
Bidiagonal(A.dv+B.dv, A.ev+B.ev, A.uplo)
357357
else
358358
newdv = A.dv+B.dv
@@ -361,7 +361,7 @@ function +(A::Bidiagonal, B::Bidiagonal)
361361
end
362362

363363
function -(A::Bidiagonal, B::Bidiagonal)
364-
if A.uplo == B.uplo
364+
if A.uplo == B.uplo || length(A.dv) == 0
365365
Bidiagonal(A.dv-B.dv, A.ev-B.ev, A.uplo)
366366
else
367367
newdv = A.dv-B.dv

stdlib/LinearAlgebra/src/structuredbroadcast.jl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,12 @@ find_uplo(a) = nothing
7070
find_uplo(bc::Broadcasted) = mapreduce(find_uplo, merge_uplos, bc.args, init=nothing)
7171

7272
function structured_broadcast_alloc(bc, ::Type{<:Bidiagonal}, ::Type{ElType}, n) where {ElType}
73-
uplo = find_uplo(bc)
73+
uplo = n > 0 ? find_uplo(bc) : 'U'
74+
n1 = max(n - 1, 0)
7475
if uplo == 'T'
75-
return Tridiagonal(Array{ElType}(undef, n-1), Array{ElType}(undef, n), Array{ElType}(undef, n-1))
76+
return Tridiagonal(Array{ElType}(undef, n1), Array{ElType}(undef, n), Array{ElType}(undef, n1))
7677
end
77-
return Bidiagonal(Array{ElType}(undef, n),Array{ElType}(undef, n-1), uplo)
78+
return Bidiagonal(Array{ElType}(undef, n),Array{ElType}(undef, n1), uplo)
7879
end
7980
structured_broadcast_alloc(bc, ::Type{<:SymTridiagonal}, ::Type{ElType}, n) where {ElType} =
8081
SymTridiagonal(Array{ElType}(undef, n),Array{ElType}(undef, n-1))

stdlib/LinearAlgebra/test/bidiag.jl

Lines changed: 45 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,19 @@ Random.seed!(1)
2626
ev += im*convert(Vector{elty}, rand(1:10, n-1))
2727
end
2828
end
29+
dv0 = zeros(elty, 0)
30+
ev0 = zeros(elty, 0)
2931

3032
@testset "Constructors" begin
31-
for (x, y) in ((dv, ev), (GenericArray(dv), GenericArray(ev)))
33+
for (x, y) in ((dv0, ev0), (dv, ev), (GenericArray(dv), GenericArray(ev)))
3234
# from vectors
3335
ubd = Bidiagonal(x, y, :U)
3436
lbd = Bidiagonal(x, y, :L)
35-
@test ubd != lbd
37+
@test ubd != lbd || x === dv0
3638
@test ubd.dv === x
3739
@test lbd.ev === y
3840
@test_throws ArgumentError Bidiagonal(x, y, :R)
39-
@test_throws DimensionMismatch Bidiagonal(x, x, :U)
41+
x == dv0 || @test_throws DimensionMismatch Bidiagonal(x, x, :U)
4042
@test_throws MethodError Bidiagonal(x, y)
4143
# from matrix
4244
@test Bidiagonal(ubd, :U) == Bidiagonal(Matrix(ubd), :U) == ubd
@@ -593,4 +595,44 @@ Base.transpose(n::MyNotANumberType) = n
593595
@test transpose(copy(tB)) == B
594596
end
595597

598+
@testset "empty bidiagonal matrices" begin
599+
dv0 = zeros(0)
600+
ev0 = zeros(0)
601+
zm = zeros(0, 0)
602+
ubd = Bidiagonal(dv0, ev0, :U)
603+
lbd = Bidiagonal(dv0, ev0, :L)
604+
@test size(ubd) == (0, 0)
605+
@test_throws BoundsError getindex(ubd, 1, 1)
606+
@test_throws BoundsError setindex!(ubd, 0.0, 1, 1)
607+
@test similar(ubd) == ubd
608+
@test similar(lbd, Int) == zeros(Int, 0, 0)
609+
@test ubd == zm
610+
@test lbd == zm
611+
@test ubd == lbd
612+
@test ubd * ubd == ubd
613+
@test lbd + lbd == lbd
614+
@test lbd' == ubd
615+
@test ubd' == lbd
616+
@test triu(ubd, 1) == ubd
617+
@test triu(lbd, 1) == ubd
618+
@test tril(ubd, -1) == ubd
619+
@test tril(lbd, -1) == ubd
620+
@test_throws ArgumentError triu(ubd)
621+
@test_throws ArgumentError tril(ubd)
622+
@test sum(ubd) == 0.0
623+
@test reduce(+, ubd) == 0.0
624+
@test reduce(+, ubd, dims=1) == zeros(1, 0)
625+
@test reduce(+, ubd, dims=2) == zeros(0, 1)
626+
@test hcat(ubd, ubd) == zm
627+
@test vcat(ubd, lbd) == zm
628+
@test hcat(lbd, ones(0, 3)) == ones(0, 3)
629+
@test fill!(copy(ubd), 1.0) == ubd
630+
@test map(abs, ubd) == zm
631+
@test lbd .+ 1 == zm
632+
@test lbd + ubd isa Bidiagonal
633+
@test lbd .+ ubd isa Bidiagonal
634+
@test ubd * 5 == ubd
635+
@test ubd .* 3 == ubd
636+
end
637+
596638
end # module TestBidiagonal

stdlib/SparseArrays/src/sparsematrix.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -575,6 +575,7 @@ end
575575
SparseMatrixCSC(B::Bidiagonal{Tv}) where Tv = SparseMatrixCSC{Tv,Int}(B)
576576
function SparseMatrixCSC{Tv,Ti}(B::Bidiagonal) where {Tv,Ti}
577577
m = length(B.dv)
578+
m == 0 && return SparseMatrixCSC{Tv,Ti}(zeros(Tv, 0, 0))
578579

579580
colptr = Vector{Ti}(undef, m+1)
580581
colptr[1] = 1

0 commit comments

Comments
 (0)