Skip to content

Commit 58092c0

Browse files
committed
Make general concatenations (cat) of combinations of sparse matrices with sparse matrices or dense matrices/vectors yield sparse arrays (fixes #17680).
1 parent e18ae9e commit 58092c0

File tree

5 files changed

+36
-11
lines changed

5 files changed

+36
-11
lines changed

base/abstractarray.jl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -998,7 +998,7 @@ function cat_t(catdims, typeC::Type, X...)
998998
end
999999
end
10001000

1001-
C = similar(isa(X[1],AbstractArray) ? full(X[1]) : [X[1]], typeC, tuple(dimsC...))
1001+
C = similar(isa(X[1],AbstractArray) ? X[1] : [X[1]], typeC, tuple(dimsC...))
10021002
if length(catdims)>1
10031003
fill!(C,0)
10041004
end

base/array.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -699,6 +699,9 @@ hvcat{T}(rows::Tuple{Vararg{Int}}, xs::Vector{T}...) = typed_hvcat(T, rows, xs..
699699
hvcat(rows::Tuple{Vararg{Int}}, xs::Matrix...) = typed_hvcat(promote_eltype(xs...), rows, xs...)
700700
hvcat{T}(rows::Tuple{Vararg{Int}}, xs::Matrix{T}...) = typed_hvcat(T, rows, xs...)
701701

702+
cat(catdims, xs::Union{Matrix,Vector}...) = Base.cat_t(catdims, promote_eltype(xs...), xs...)
703+
cat{T}(catdims, xs::Union{Matrix{T},Vector{T}}...) = Base.cat_t(catdims, T, xs...)
704+
702705
## find ##
703706

704707
# returns the index of the next non-zero element, or 0 if all zeros

base/sparse/sparse.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ import Base: @get!, acos, acosd, acot, acotd, acsch, asech, asin, asind, asinh,
2121
tand, tanh, trace, transpose!, tril!, triu!, trunc, vecnorm, abs, abs2,
2222
broadcast, ceil, complex, cond, conj, convert, copy, copy!, ctranspose, diagm,
2323
exp, expm1, factorize, find, findmax, findmin, findnz, float, full, getindex,
24-
hcat, hvcat, imag, indmax, ishermitian, kron, length, log, log1p, max, min,
24+
vcat, hcat, hvcat, cat, imag, indmax, ishermitian, kron, length, log, log1p, max, min,
2525
maximum, minimum, norm, one, promote_eltype, real, reinterpret, reshape, rot180,
2626
rotl90, rotr90, round, scale!, setindex!, similar, size, transpose, tril,
27-
triu, vcat, vec, permute!
27+
triu, vec, permute!
2828

2929
import Base.Broadcast: broadcast_shape
3030

base/sparse/sparsematrix.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3253,6 +3253,12 @@ function hvcat(rows::Tuple{Vararg{Int}}, X::Union{Vector, Matrix, SparseMatrixCS
32533253
vcat(tmp_rows...)
32543254
end
32553255

3256+
function cat(catdims, Xin::Union{Vector, Matrix, SparseMatrixCSC}...)
3257+
X = SparseMatrixCSC[issparse(x) ? x : sparse(x) for x in Xin]
3258+
T = promote_eltype(Xin...)
3259+
Base.cat_t(catdims, T, X...)
3260+
end
3261+
32563262
"""
32573263
blkdiag(A...)
32583264

test/sparsedir/sparse.jl

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1554,14 +1554,30 @@ end
15541554
@inferred sprand(1, 1, 1.0, rand, Float64)
15551555
@inferred sprand(1, 1, 1.0, x->round(Int,rand(x)*100))
15561556

1557-
# dense sparse concatenation -> sparse return type
1558-
@test issparse([sprand(10,10,.1) rand(10,10)])
1559-
@test issparse([sprand(10,10,.1); rand(10,10)])
1560-
@test issparse([sprand(10,10,.1) rand(10,10); rand(10,10) rand(10,10)])
1561-
# ---
1562-
@test !issparse([rand(10,10) rand(10,10)])
1563-
@test !issparse([rand(10,10); rand(10,10)])
1564-
@test !issparse([rand(10,10) rand(10,10); rand(10,10) rand(10,10)])
1557+
# Test that concatenations of combinations of sparse matrices with sparse matrices or dense
1558+
# matrices/vectors yield sparse arrays
1559+
let
1560+
N = 4
1561+
densevec = ones(N)
1562+
densemat = diagm(ones(N))
1563+
spmat = spdiagm(ones(N))
1564+
# Test that concatenations of pairs of sparse matrices yield sparse arrays
1565+
@test issparse(vcat(spmat, spmat))
1566+
@test issparse(hcat(spmat, spmat))
1567+
@test issparse(hvcat((2,), spmat, spmat))
1568+
@test issparse(cat((1,2), spmat, spmat))
1569+
# Test that concatenations of a sparse matrice with a dense matrix/vector yield sparse arrays
1570+
@test issparse(vcat(spmat, densemat))
1571+
@test issparse(vcat(densemat, spmat))
1572+
for densearg in (densevec, densemat)
1573+
@test issparse(hcat(spmat, densearg))
1574+
@test issparse(hcat(densearg, spmat))
1575+
@test issparse(hvcat((2,), spmat, densearg))
1576+
@test issparse(hvcat((2,), densearg, spmat))
1577+
@test issparse(cat((1,2), spmat, densearg))
1578+
@test issparse(cat((1,2), densearg, spmat))
1579+
end
1580+
end
15651581

15661582
# issue #14816
15671583
let m = 5

0 commit comments

Comments
 (0)