@@ -1108,7 +1108,9 @@ function hcat(Xin::AbstractSparseVector...)
11081108 X = map (_unsafe_unfix, Xin)
11091109 Tv = promote_type (map (eltype, X)... )
11101110 Ti = promote_type (map (indtype, X)... )
1111- r = _absspvec_hcat (map (x -> convert (SparseVector{Tv,Ti}, x), X)... )
1111+ r = (function (:: Type{SV} ) where SV
1112+ _absspvec_hcat (map (x -> convert (SV, x), X)... )
1113+ end )(SparseVector{Tv,Ti})
11121114 return @if_move_fixed Xin... r
11131115end
11141116function _absspvec_hcat (X:: AbstractSparseVector{Tv,Ti} ...) where {Tv,Ti}
@@ -1144,7 +1146,9 @@ function vcat(Xin::AbstractSparseVector...)
11441146 X = map (_unsafe_unfix, Xin)
11451147 Tv = promote_type (map (eltype, X)... )
11461148 Ti = promote_type (map (indtype, X)... )
1147- r = _absspvec_vcat (map (x -> convert (SparseVector{Tv,Ti}, x), X)... )
1149+ r = (function (:: Type{SV} ) where SV
1150+ _absspvec_vcat (map (x -> convert (SV, x), X)... )
1151+ end )(SparseVector{Tv,Ti})
11481152 return @if_move_fixed Xin... r
11491153end
11501154function _absspvec_vcat (X:: AbstractSparseVector{Tv,Ti} ...) where {Tv,Ti}
@@ -1193,14 +1197,16 @@ _makesparse(x::AbstractMatrix) = convert(SparseMatrixCSC, issparse(x) ? x : spar
11931197anysparse () = false
11941198anysparse (X) = X isa AbstractArray && issparse (X)
11951199anysparse (X, Xs... ) = anysparse (X) || anysparse (Xs... )
1200+ anysparse (X:: T , Xs:: T... ) where {T} = anysparse (X)
11961201
1197- function hcat (X:: Union{Vector, AbstractSparseVector} ...)
1202+ const _SparseVecConcatGroup = Union{Vector, AbstractSparseVector}
1203+ function hcat (X:: _SparseVecConcatGroup... )
11981204 if anysparse (X... )
11991205 X = map (sparse, X)
12001206 end
12011207 return cat (X... ; dims= Val (2 ))
12021208end
1203- function vcat (X:: Union{Vector, AbstractSparseVector} ...)
1209+ function vcat (X:: _SparseVecConcatGroup ... )
12041210 if anysparse (X... )
12051211 X = map (sparse, X)
12061212 end
@@ -1213,30 +1219,30 @@ end
12131219const _SparseConcatGroup = Union{AbstractVecOrMat{<: Number },Number}
12141220
12151221# `@constprop :aggressive` allows `dims` to be propagated as constant improving return type inference
1216- Base. @constprop :aggressive function Base. _cat (dims, X:: _SparseConcatGroup... )
1217- T = promote_eltype (X... )
1218- if anysparse (X... )
1219- X = ( _sparse (first (X)) , map (_makesparse, Base . tail (X)) ... )
1222+ Base. @constprop :aggressive function Base. _cat (dims, X1 :: _SparseConcatGroup , X:: _SparseConcatGroup... )
1223+ T = promote_eltype (X1, X... )
1224+ if anysparse (X1) || anysparse ( X... )
1225+ X1, X = _sparse (X1) , map (_makesparse, X )
12201226 end
1221- return Base. _cat_t (dims, T, X... )
1227+ return Base. _cat_t (dims, T, X1, X... )
12221228end
1223- function hcat (X:: _SparseConcatGroup... )
1224- if anysparse (X... )
1225- X = ( _sparse (first (X)) , map (_makesparse, Base . tail (X)) ... )
1229+ function hcat (X1 :: _SparseConcatGroup , X:: _SparseConcatGroup... )
1230+ if anysparse (X1) || anysparse ( X... )
1231+ X1, X = _sparse (X1) , map (_makesparse, X )
12261232 end
1227- return cat ( X... , dims = Val ( 2 ) )
1233+ return Base . typed_hcat (Base . promote_eltype (X1, X... ), X1, X ... )
12281234end
1229- function vcat (X:: _SparseConcatGroup... )
1230- if anysparse (X... )
1231- X = ( _sparse (first (X)) , map (_makesparse, Base . tail (X)) ... )
1235+ function vcat (X1 :: _SparseConcatGroup , X:: _SparseConcatGroup... )
1236+ if anysparse (X1) || anysparse ( X... )
1237+ X1, X = _sparse (X1) , map (_makesparse, X )
12321238 end
1233- return cat ( X... , dims = Val ( 1 ) )
1239+ return Base . typed_vcat (Base . promote_eltype (X1, X... ), X1, X ... )
12341240end
1235- function hvcat (rows:: Tuple{Vararg{Int}} , X:: _SparseConcatGroup... )
1236- if anysparse (X... )
1237- vcat (_hvcat_rows (rows, X... )... )
1241+ function hvcat (rows:: Tuple{Vararg{Int}} , X1 :: _SparseConcatGroup , X:: _SparseConcatGroup... )
1242+ if anysparse (X1) || anysparse ( X... )
1243+ vcat (_hvcat_rows (rows, X1, X... )... )
12381244 else
1239- Base. typed_hvcat (Base. promote_eltypeof (X... ), rows, X... )
1245+ Base. typed_hvcat (Base. promote_eltypeof (X1, X... ), rows, X1 , X... )
12401246 end
12411247end
12421248function _hvcat_rows ((row1, rows... ):: Tuple{Vararg{Int}} , X:: _SparseConcatGroup... )
@@ -1254,6 +1260,15 @@ function _hvcat_rows((row1, rows...)::Tuple{Vararg{Int}}, X::_SparseConcatGroup.
12541260end
12551261_hvcat_rows (:: Tuple{} , X:: _SparseConcatGroup... ) = ()
12561262
1263+ # disambiguation for type-piracy problems created above
1264+ hcat (n1:: Number , ns:: Vararg{Number} ) = invoke (hcat, Tuple{Vararg{Number}}, n1, ns... )
1265+ vcat (n1:: Number , ns:: Vararg{Number} ) = invoke (vcat, Tuple{Vararg{Number}}, n1, ns... )
1266+ hcat (n1:: Type{N} , ns:: Vararg{N} ) where {N<: Number } = invoke (hcat, Tuple{Vararg{Number}}, n1, ns... )
1267+ vcat (n1:: Type{N} , ns:: Vararg{N} ) where {N<: Number } = invoke (vcat, Tuple{Vararg{Number}}, n1, ns... )
1268+ hvcat (rows:: Tuple{Vararg{Int}} , n1:: Number , ns:: Vararg{Number} ) = invoke (hvcat, Tuple{typeof (rows), Vararg{Number}}, rows, n1, ns... )
1269+ hvcat (rows:: Tuple{Vararg{Int}} , n1:: N , ns:: Vararg{N} ) where {N<: Number } = invoke (hvcat, Tuple{typeof (rows), Vararg{N}}, rows, n1, ns... )
1270+
1271+
12571272# make sure UniformScaling objects are converted to sparse matrices for concatenation
12581273promote_to_array_type (A:: Tuple{Vararg{Union{_SparseConcatGroup,UniformScaling}}} ) = anysparse (A... ) ? SparseMatrixCSC : Matrix
12591274promote_to_arrays_ (n:: Int , :: Type{SparseMatrixCSC} , J:: UniformScaling ) = sparse (J, n, n)
0 commit comments