Skip to content

Commit ba46baf

Browse files
authored
Merge pull request #17690 from Sacha0/sparsegencat
Fix #17680 (sparse general concatenation) and #17686 (concatenation of heterogeneous Matrix-Vector combinations)
2 parents 6b41538 + 9a67c16 commit ba46baf

File tree

6 files changed

+75
-39
lines changed

6 files changed

+75
-39
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: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -643,6 +643,26 @@ function reverse!(v::AbstractVector, s=1, n=length(v))
643643
return v
644644
end
645645

646+
647+
# concatenations of combinations (homogeneous, heterogeneous) of dense matrices/vectors #
648+
vcat{T}(A::Union{Vector{T},Matrix{T}}...) = typed_vcat(T, A...)
649+
vcat(A::Union{Vector,Matrix}...) = typed_vcat(promote_eltype(A...), A...)
650+
hcat{T}(A::Union{Vector{T},Matrix{T}}...) = typed_hcat(T, A...)
651+
hcat(A::Union{Vector,Matrix}...) = typed_hcat(promote_eltype(A...), A...)
652+
hvcat{T}(rows::Tuple{Vararg{Int}}, xs::Union{Vector{T},Matrix{T}}...) = typed_hvcat(T, rows, xs...)
653+
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{Vector,Matrix}...) = typed_hvcat(promote_eltype(xs...), rows, xs...)
654+
cat{T}(catdims, xs::Union{Vector{T},Matrix{T}}...) = Base.cat_t(catdims, T, xs...)
655+
cat(catdims, xs::Union{Vector,Matrix}...) = Base.cat_t(catdims, promote_eltype(xs...), xs...)
656+
# concatenations of homogeneous combinations of vectors, horizontal and vertical
657+
function hcat{T}(V::Vector{T}...)
658+
height = length(V[1])
659+
for j = 2:length(V)
660+
if length(V[j]) != height
661+
throw(DimensionMismatch("vectors must have same lengths"))
662+
end
663+
end
664+
return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
665+
end
646666
function vcat{T}(arrays::Vector{T}...)
647667
n = 0
648668
for a in arrays
@@ -670,34 +690,6 @@ function vcat{T}(arrays::Vector{T}...)
670690
return arr
671691
end
672692

673-
function hcat{T}(V::Vector{T}...)
674-
height = length(V[1])
675-
for j = 2:length(V)
676-
if length(V[j]) != height
677-
throw(DimensionMismatch("vectors must have same lengths"))
678-
end
679-
end
680-
return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
681-
end
682-
683-
hcat(A::Matrix...) = typed_hcat(promote_eltype(A...), A...)
684-
hcat{T}(A::Matrix{T}...) = typed_hcat(T, A...)
685-
686-
vcat(A::Matrix...) = typed_vcat(promote_eltype(A...), A...)
687-
vcat{T}(A::Matrix{T}...) = typed_vcat(T, A...)
688-
689-
hcat(A::Union{Matrix, Vector}...) = typed_hcat(promote_eltype(A...), A...)
690-
hcat{T}(A::Union{Matrix{T}, Vector{T}}...) = typed_hcat(T, A...)
691-
692-
693-
vcat(A::Union{Matrix, Vector}...) = typed_vcat(promote_eltype(A...), A...)
694-
vcat{T}(A::Union{Matrix{T}, Vector{T}}...) = typed_vcat(T, A...)
695-
696-
hvcat(rows::Tuple{Vararg{Int}}, xs::Vector...) = typed_hvcat(promote_eltype(xs...), rows, xs...)
697-
hvcat{T}(rows::Tuple{Vararg{Int}}, xs::Vector{T}...) = typed_hvcat(T, rows, xs...)
698-
699-
hvcat(rows::Tuple{Vararg{Int}}, xs::Matrix...) = typed_hvcat(promote_eltype(xs...), rows, xs...)
700-
hvcat{T}(rows::Tuple{Vararg{Int}}, xs::Matrix{T}...) = typed_hvcat(T, rows, xs...)
701693

702694
## find ##
703695

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/arrayops.jl

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1703,3 +1703,25 @@ for op in (:.+, :.*, :.÷, :.%, :.<<, :.>>, :.-, :./, :.\, :.//, :.^)
17031703
end
17041704

17051705
end
1706+
1707+
# Test that concatenations of dense matrices/vectors yield dense matrices/vectors
1708+
let
1709+
N = 4
1710+
densevec = ones(N)
1711+
densemat = diagm(ones(N))
1712+
# Test that concatenations of homogeneous pairs of either dense matrices or dense vectors
1713+
# (i.e., Matrix-Matrix concatenations, and Vector-Vector concatenations) yield dense arrays
1714+
for densearray in (densevec, densemat)
1715+
@test isa(vcat(densearray, densearray), Array)
1716+
@test isa(hcat(densearray, densearray), Array)
1717+
@test isa(hvcat((2,), densearray, densearray), Array)
1718+
@test isa(cat((1,2), densearray, densearray), Array)
1719+
end
1720+
# Test that concatenations of heterogeneous Matrix-Vector pairs yield dense matrices
1721+
@test isa(hcat(densemat, densevec), Array)
1722+
@test isa(hcat(densevec, densemat), Array)
1723+
@test isa(hvcat((2,), densemat, densevec), Array)
1724+
@test isa(hvcat((2,), densevec, densemat), Array)
1725+
@test isa(cat((1,2), densemat, densevec), Array)
1726+
@test isa(cat((1,2), densevec, densemat), Array)
1727+
end

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)