Skip to content

Commit e6c84a1

Browse files
authored
Merge pull request #48933 from JuliaLang/dk/cat_array_number
Let Base handle concatenation of arrays and numbers
2 parents ee62d37 + 2709dcf commit e6c84a1

File tree

4 files changed

+26
-4
lines changed

4 files changed

+26
-4
lines changed

base/abstractarray.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1985,12 +1985,16 @@ julia> cat(1, [2], [3;;]; dims=Val(2))
19851985

19861986
# The specializations for 1 and 2 inputs are important
19871987
# especially when running with --inline=no, see #11158
1988+
# The specializations for Union{AbstractVecOrMat,Number} are necessary
1989+
# to have more specialized methods here than in LinearAlgebra/uniformscaling.jl
19881990
vcat(A::AbstractArray) = cat(A; dims=Val(1))
19891991
vcat(A::AbstractArray, B::AbstractArray) = cat(A, B; dims=Val(1))
19901992
vcat(A::AbstractArray...) = cat(A...; dims=Val(1))
1993+
vcat(A::Union{AbstractVecOrMat,Number}...) = cat(A...; dims=Val(1))
19911994
hcat(A::AbstractArray) = cat(A; dims=Val(2))
19921995
hcat(A::AbstractArray, B::AbstractArray) = cat(A, B; dims=Val(2))
19931996
hcat(A::AbstractArray...) = cat(A...; dims=Val(2))
1997+
hcat(A::Union{AbstractVecOrMat,Number}...) = cat(A...; dims=Val(2))
19941998

19951999
typed_vcat(T::Type, A::AbstractArray) = _cat_t(Val(1), T, A)
19962000
typed_vcat(T::Type, A::AbstractArray, B::AbstractArray) = _cat_t(Val(1), T, A, B)
@@ -2140,6 +2144,8 @@ end
21402144

21412145
hvcat(rows::Tuple{Vararg{Int}}, xs::Number...) = typed_hvcat(promote_typeof(xs...), rows, xs...)
21422146
hvcat(rows::Tuple{Vararg{Int}}, xs...) = typed_hvcat(promote_eltypeof(xs...), rows, xs...)
2147+
# the following method is needed to provide a more specific one compared to LinearAlgebra/uniformscaling.jl
2148+
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{AbstractVecOrMat,Number}...) = typed_hvcat(promote_eltypeof(xs...), rows, xs...)
21432149

21442150
function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, xs::Number...) where T
21452151
nr = length(rows)

base/array.jl

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,7 @@ function reverse!(v::AbstractVector, start::Integer, stop::Integer=lastindex(v))
19161916
return v
19171917
end
19181918

1919-
# concatenations of homogeneous combinations of vectors, horizontal and vertical
1919+
# concatenations of (in)homogeneous combinations of vectors, horizontal and vertical
19201920

19211921
vcat() = Vector{Any}()
19221922
hcat() = Vector{Any}()
@@ -1930,6 +1930,7 @@ function hcat(V::Vector{T}...) where T
19301930
end
19311931
return [ V[j][i]::T for i=1:length(V[1]), j=1:length(V) ]
19321932
end
1933+
hcat(A::Vector...) = cat(A...; dims=Val(2)) # more special than SparseArrays's hcat
19331934

19341935
function vcat(arrays::Vector{T}...) where T
19351936
n = 0
@@ -1946,6 +1947,19 @@ function vcat(arrays::Vector{T}...) where T
19461947
end
19471948
return arr
19481949
end
1950+
vcat(A::Vector...) = cat(A...; dims=Val(1)) # more special than SparseArrays's vcat
1951+
1952+
# disambiguation with LinAlg/special.jl
1953+
# Union{Number,Vector,Matrix} is for LinearAlgebra._DenseConcatGroup
1954+
# VecOrMat{T} is for LinearAlgebra._TypedDenseConcatGroup
1955+
hcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(2))
1956+
hcat(A::VecOrMat{T}...) where {T} = typed_hcat(T, A...)
1957+
vcat(A::Union{Number,Vector,Matrix}...) = cat(A...; dims=Val(1))
1958+
vcat(A::VecOrMat{T}...) where {T} = typed_vcat(T, A...)
1959+
hvcat(rows::Tuple{Vararg{Int}}, xs::Union{Number,Vector,Matrix}...) =
1960+
typed_hvcat(promote_eltypeof(xs...), rows, xs...)
1961+
hvcat(rows::Tuple{Vararg{Int}}, xs::VecOrMat{T}...) where {T} =
1962+
typed_hvcat(T, rows, xs...)
19491963

19501964
_cat(n::Integer, x::Integer...) = reshape([x...], (ntuple(Returns(1), n-1)..., length(x)))
19511965

stdlib/LinearAlgebra/src/special.jl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -335,9 +335,7 @@ const _TypedDenseConcatGroup{T} = Union{Vector{T}, Adjoint{T,Vector{T}}, Transpo
335335
promote_to_array_type(::Tuple{Vararg{Union{_DenseConcatGroup,UniformScaling}}}) = Matrix
336336

337337
Base._cat(dims, xs::_DenseConcatGroup...) = Base._cat_t(dims, promote_eltype(xs...), xs...)
338-
vcat(A::Vector...) = Base.typed_vcat(promote_eltype(A...), A...)
339338
vcat(A::_DenseConcatGroup...) = Base.typed_vcat(promote_eltype(A...), A...)
340-
hcat(A::Vector...) = Base.typed_hcat(promote_eltype(A...), A...)
341339
hcat(A::_DenseConcatGroup...) = Base.typed_hcat(promote_eltype(A...), A...)
342340
hvcat(rows::Tuple{Vararg{Int}}, xs::_DenseConcatGroup...) = Base.typed_hvcat(promote_eltype(xs...), rows, xs...)
343341
# For performance, specially handle the case where the matrices/vectors have homogeneous eltype

stdlib/LinearAlgebra/src/uniformscaling.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,14 @@ promote_to_arrays(n,k, ::Type{T}, A, B, Cs...) where {T} =
419419
(promote_to_arrays_(n[k], T, A), promote_to_arrays_(n[k+1], T, B), promote_to_arrays(n,k+2, T, Cs...)...)
420420
promote_to_array_type(A::Tuple{Vararg{Union{AbstractVecOrMat,UniformScaling,Number}}}) = Matrix
421421

422+
_us2number(A) = A
423+
_us2number(J::UniformScaling) = J.λ
424+
422425
for (f, _f, dim, name) in ((:hcat, :_hcat, 1, "rows"), (:vcat, :_vcat, 2, "cols"))
423426
@eval begin
424427
@inline $f(A::Union{AbstractVecOrMat,UniformScaling}...) = $_f(A...)
425-
@inline $f(A::Union{AbstractVecOrMat,UniformScaling,Number}...) = $_f(A...)
428+
# if there's a Number present, J::UniformScaling must be 1x1-dimensional
429+
@inline $f(A::Union{AbstractVecOrMat,UniformScaling,Number}...) = $f(map(_us2number, A)...)
426430
function $_f(A::Union{AbstractVecOrMat,UniformScaling,Number}...; array_type = promote_to_array_type(A))
427431
n = -1
428432
for a in A

0 commit comments

Comments
 (0)