Skip to content

Commit

Permalink
Fix sparse constructor when Tridiagonal/SymTridiagonal are empty (#…
Browse files Browse the repository at this point in the history
…42574)

Co-authored-by: Daniel Karrasch <daniel.karrasch@posteo.de>
(cherry picked from commit b3c268c)
  • Loading branch information
mcognetta authored and staticfloat committed Dec 22, 2022
1 parent ba61fb0 commit 445e795
Show file tree
Hide file tree
Showing 2 changed files with 33 additions and 2 deletions.
8 changes: 6 additions & 2 deletions stdlib/SparseArrays/src/sparsematrix.jl
Original file line number Diff line number Diff line change
Expand Up @@ -515,6 +515,8 @@ SparseMatrixCSC(M::Matrix) = sparse(M)
SparseMatrixCSC(T::Tridiagonal{Tv}) where Tv = SparseMatrixCSC{Tv,Int}(T)
function SparseMatrixCSC{Tv,Ti}(T::Tridiagonal) where {Tv,Ti}
m = length(T.d)
m == 0 && return SparseMatrixCSC{Tv,Ti}(0, 0, ones(Ti, 1), Ti[], Tv[])
m == 1 && return SparseMatrixCSC{Tv,Ti}(1, 1, Ti[1, 2], Ti[1], Tv[T.d[1]])

colptr = Vector{Ti}(undef, m+1)
colptr[1] = 1
Expand Down Expand Up @@ -545,6 +547,8 @@ end
SparseMatrixCSC(T::SymTridiagonal{Tv}) where Tv = SparseMatrixCSC{Tv,Int}(T)
function SparseMatrixCSC{Tv,Ti}(T::SymTridiagonal) where {Tv,Ti}
m = length(T.dv)
m == 0 && return SparseMatrixCSC{Tv,Ti}(0, 0, ones(Ti, 1), Ti[], Tv[])
m == 1 && return SparseMatrixCSC{Tv,Ti}(1, 1, Ti[1, 2], Ti[1], Tv[T.dv[1]])

colptr = Vector{Ti}(undef, m+1)
colptr[1] = 1
Expand Down Expand Up @@ -575,7 +579,7 @@ end
SparseMatrixCSC(B::Bidiagonal{Tv}) where Tv = SparseMatrixCSC{Tv,Int}(B)
function SparseMatrixCSC{Tv,Ti}(B::Bidiagonal) where {Tv,Ti}
m = length(B.dv)
m == 0 && return SparseMatrixCSC{Tv,Ti}(zeros(Tv, 0, 0))
m == 0 && return SparseMatrixCSC{Tv,Ti}(0, 0, ones(Ti, 1), Ti[], Tv[])

colptr = Vector{Ti}(undef, m+1)
colptr[1] = 1
Expand Down Expand Up @@ -604,7 +608,7 @@ end
SparseMatrixCSC(D::Diagonal{Tv}) where Tv = SparseMatrixCSC{Tv,Int}(D)
function SparseMatrixCSC{Tv,Ti}(D::Diagonal) where {Tv,Ti}
m = length(D.diag)
return SparseMatrixCSC(m, m, Vector(1:(m+1)), Vector(1:m), Vector{Tv}(D.diag))
return SparseMatrixCSC(m, m, Vector(Ti(1):Ti(m+1)), Vector(Ti(1):Ti(m)), Vector{Tv}(D.diag))
end
SparseMatrixCSC(M::AbstractMatrix{Tv}) where {Tv} = SparseMatrixCSC{Tv,Int}(M)
SparseMatrixCSC{Tv}(M::AbstractMatrix{Tv}) where {Tv} = SparseMatrixCSC{Tv,Int}(M)
Expand Down
27 changes: 27 additions & 0 deletions stdlib/SparseArrays/test/sparse.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1669,6 +1669,33 @@ end
S2 = SparseMatrixCSC(D)
@test Array(D) == Array(S) == Array(S2)
@test S == S2

# An issue discovered in #42574 where
# SparseMatrixCSC{Tv, Ti}(::Diagonal) ignored Ti
D = Diagonal(rand(3))
S = SparseMatrixCSC{Float64, Int8}(D)
@test S isa SparseMatrixCSC{Float64, Int8}
end

@testset "Sparse construction with empty/1x1 structured matrices" begin
empty = spzeros(0, 0)

@test sparse(Diagonal(zeros(0, 0))) == empty
@test sparse(Bidiagonal(zeros(0, 0), :U)) == empty
@test sparse(Bidiagonal(zeros(0, 0), :L)) == empty
@test sparse(SymTridiagonal(zeros(0, 0))) == empty
@test sparse(Tridiagonal(zeros(0, 0))) == empty

one_by_one = rand(1,1)
sp_one_by_one = sparse(one_by_one)

@test sparse(Diagonal(one_by_one)) == sp_one_by_one
@test sparse(Bidiagonal(one_by_one, :U)) == sp_one_by_one
@test sparse(Bidiagonal(one_by_one, :L)) == sp_one_by_one
@test sparse(Tridiagonal(one_by_one)) == sp_one_by_one

s = SymTridiagonal(rand(1), rand(0))
@test sparse(s) == s
end

@testset "error conditions for reshape, and dropdims" begin
Expand Down

0 comments on commit 445e795

Please sign in to comment.