diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index 876f1e74b0cae9..836b0235d0f6dc 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -3231,17 +3231,21 @@ end # Sparse/dense concatenation -function hcat(Xin::Union{Vector, Matrix, SparseMatrixCSC}...) +# TODO: A similar definition also exists in base/linalg/bidiag.jl. These definitions should +# be consolidated in a more appropriate location, for example base/linalg/special.jl. +SpecialArrays = Union{Diagonal, Bidiagonal, Tridiagonal, SymTridiagonal} + +function hcat(Xin::Union{Vector, Matrix, SparseMatrixCSC, SpecialArrays}...) X = SparseMatrixCSC[issparse(x) ? x : sparse(x) for x in Xin] hcat(X...) end -function vcat(Xin::Union{Vector, Matrix, SparseMatrixCSC}...) +function vcat(Xin::Union{Vector, Matrix, SparseMatrixCSC, SpecialArrays}...) X = SparseMatrixCSC[issparse(x) ? x : sparse(x) for x in Xin] vcat(X...) end -function hvcat(rows::Tuple{Vararg{Int}}, X::Union{Vector, Matrix, SparseMatrixCSC}...) +function hvcat(rows::Tuple{Vararg{Int}}, X::Union{Vector, Matrix, SparseMatrixCSC, SpecialArrays}...) nbr = length(rows) # number of block rows tmp_rows = Array{SparseMatrixCSC}(nbr) diff --git a/test/linalg/special.jl b/test/linalg/special.jl index 89ddde5ee4b007..796298a4e08e5d 100644 --- a/test/linalg/special.jl +++ b/test/linalg/special.jl @@ -128,3 +128,38 @@ for typ in [UpperTriangular,LowerTriangular,Base.LinAlg.UnitUpperTriangular,Base @test Base.LinAlg.A_mul_Bc(atri,qrb[:Q]) ≈ full(atri) * qrb[:Q]' @test Base.LinAlg.A_mul_Bc!(copy(atri),qrb[:Q]) ≈ full(atri) * qrb[:Q]' end + +# Test that concatenations of combinations of special and other matrix types yield sparse arrays +let + N = 4 + # Test concatenating pairwise combinations of special matrices + diagmat = Diagonal(ones(N)) + bidiagmat = Bidiagonal(ones(N), ones(N-1), true) + tridiagmat = Tridiagonal(ones(N-1), ones(N), ones(N-1)) + symtridiagmat = SymTridiagonal(ones(N), ones(N-1)) + specialmats = (diagmat, bidiagmat, tridiagmat, symtridiagmat) + for specialmata in specialmats, specialmatb in specialmats + @test issubtype(typeof(hcat(specialmata, specialmatb)), AbstractSparseArray) + @test issubtype(typeof(vcat(specialmata, specialmatb)), AbstractSparseArray) + @test issubtype(typeof(hvcat((1,1), specialmata, specialmatb)), AbstractSparseArray) + end + # Test concatenating pairwise combinations of special matrices with sparse or dense matrices + spmat = spdiagm(ones(N)) + densemat = diagm(ones(N)) + for specialmat in specialmats, othermat in (spmat, densemat) + @test issubtype(typeof(hcat(specialmat, spmat)), AbstractSparseArray) + @test issubtype(typeof(hcat(spmat, specialmat)), AbstractSparseArray) + @test issubtype(typeof(vcat(specialmat, spmat)), AbstractSparseArray) + @test issubtype(typeof(vcat(spmat, specialmat)), AbstractSparseArray) + @test issubtype(typeof(hvcat((1,1), specialmat, spmat)), AbstractSparseArray) + @test issubtype(typeof(hvcat((1,1), spmat, specialmat)), AbstractSparseArray) + end + # Test concatenating combinations of special matrices and dense vectors + densevec = ones(N) + for specialmat in specialmats + @test issubtype(typeof(hcat(specialmat, densevec)), AbstractSparseArray) + @test issubtype(typeof(hcat(densevec, specialmat)), AbstractSparseArray) + @test issubtype(typeof(hvcat((2,), specialmat, densevec)), AbstractSparseArray) + @test issubtype(typeof(hvcat((2,), densevec, specialmat)), AbstractSparseArray) + end +end