From 1b377d6cf49f0313907e08051c8586b766407c0a Mon Sep 17 00:00:00 2001 From: Patrick Kofod Mogensen Date: Mon, 25 Apr 2016 11:06:25 +0200 Subject: [PATCH] Fix #13130 such that concatenation of sparse and dense is sparse. --- NEWS.md | 3 +++ base/array.jl | 8 ++++++++ base/sparse/sparsematrix.jl | 15 ++++++++++++++- test/sparsedir/sparse.jl | 13 +++++++++++++ 4 files changed, 38 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 744b4c70f691a5..53c830503b1d2b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -138,6 +138,8 @@ Library improvements * The new `Base.StackTraces` module makes stack traces easier to use programmatically. ([#14469]) + * Concatenating dense and sparse matrices now returns a sparse matrix ([#15172]). + Deprecated or removed --------------------- @@ -198,3 +200,4 @@ Deprecated or removed [#15550]: https://github.com/JuliaLang/julia/issues/15550 [#15609]: https://github.com/JuliaLang/julia/issues/15609 [#15763]: https://github.com/JuliaLang/julia/issues/15763 +[#15172]: https://github.com/JuliaLang/julia/issues/15172 diff --git a/base/array.jl b/base/array.jl index 7535b4b8d45872..425c264f6f654d 100644 --- a/base/array.jl +++ b/base/array.jl @@ -714,6 +714,14 @@ function hcat{T}(V::Vector{T}...) [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ] end +hcat(A::Matrix...) = typed_hcat(promote_eltype(A...), A...) +hcat{T}(A::Matrix{T}...) = typed_hcat(T, A...) + +vcat(A::Matrix...) = typed_vcat(promote_eltype(A...), A...) +vcat{T}(A::Matrix{T}...) = typed_vcat(T, A...) + +hvcat(rows::Tuple{Vararg{Int}}, xs::Matrix...) = typed_hvcat(promote_eltype(xs...), rows, xs...) +hvcat{T}(rows::Tuple{Vararg{Int}}, xs::Matrix{T}...) = typed_hvcat(T, rows, xs...) ## find ## diff --git a/base/sparse/sparsematrix.jl b/base/sparse/sparsematrix.jl index 062287ec41ea73..041c3eb0befb41 100644 --- a/base/sparse/sparsematrix.jl +++ b/base/sparse/sparsematrix.jl @@ -2867,7 +2867,20 @@ function hcat(X::SparseMatrixCSC...) SparseMatrixCSC(m, n, colptr, rowval, nzval) end -function hvcat(rows::Tuple{Vararg{Int}}, X::SparseMatrixCSC...) + +# Sparse/dense concatenation + +function hcat(Xin::Union{Matrix, SparseMatrixCSC}...) + X = SparseMatrixCSC[issparse(x) ? x : sparse(x) for x in Xin] + hcat(X...) +end + +function vcat(Xin::Union{Matrix, SparseMatrixCSC}...) + X = SparseMatrixCSC[issparse(x) ? x : sparse(x) for x in Xin] + vcat(X...) +end + +function hvcat(rows::Tuple{Vararg{Int}}, X::Union{Matrix, SparseMatrixCSC}...) nbr = length(rows) # number of block rows tmp_rows = Array(SparseMatrixCSC, nbr) diff --git a/test/sparsedir/sparse.jl b/test/sparsedir/sparse.jl index 9252c212e497de..e48de0f78fbefe 100644 --- a/test/sparsedir/sparse.jl +++ b/test/sparsedir/sparse.jl @@ -1319,3 +1319,16 @@ let @test issparse(UpperTriangular(full(m))) == false @test issparse(LinAlg.UnitUpperTriangular(full(m))) == false end + +# dense sparse concatenation -> sparse return type +@test issparse([sprand(10,10,.1) rand(10,10)]) +@test issparse([sprand(10,10,.1); rand(10,10)]) +@test issparse([sprand(10,10,.1) rand(10,10); rand(10,10) rand(10,10)]) +#--- +# Matrix vector cat not supported for sparse #13130 +#@test issparse([sprand(10,10,.1) rand(10)]) +#@test issparse([sprand(10,10,.1) sprand(10,.1)]) +# --- +@test !issparse([rand(10,10) rand(10,10)]) +@test !issparse([rand(10,10); rand(10,10)]) +@test !issparse([rand(10,10) rand(10,10); rand(10,10) rand(10,10)])