@@ -1635,11 +1635,21 @@ cat_size(A::AbstractArray) = size(A)
16351635cat_size (A, d) = 1
16361636cat_size (A:: AbstractArray , d) = size (A, d)
16371637
1638+ cat_length (:: Any ) = 1
1639+ cat_length (a:: AbstractArray ) = length (a)
1640+
1641+ cat_ndims (a) = 0
1642+ cat_ndims (a:: AbstractArray ) = ndims (a)
1643+
16381644cat_indices (A, d) = OneTo (1 )
16391645cat_indices (A:: AbstractArray , d) = axes (A, d)
16401646
1641- cat_similar (A, :: Type{T} , shape) where T = Array {T} (undef, shape)
1642- cat_similar (A:: AbstractArray , :: Type{T} , shape) where T = similar (A, T, shape)
1647+ cat_similar (A, :: Type{T} , shape:: Tuple ) where T = Array {T} (undef, shape)
1648+ cat_similar (A, :: Type{T} , shape:: Vector ) where T = Array {T} (undef, shape... )
1649+ cat_similar (A:: Array , :: Type{T} , shape:: Tuple ) where T = Array {T} (undef, shape)
1650+ cat_similar (A:: Array , :: Type{T} , shape:: Vector ) where T = Array {T} (undef, shape... )
1651+ cat_similar (A:: AbstractArray , T:: Type , shape:: Tuple ) = similar (A, T, shape)
1652+ cat_similar (A:: AbstractArray , T:: Type , shape:: Vector ) = similar (A, T, shape... )
16431653
16441654# These are for backwards compatibility (even though internal)
16451655cat_shape (dims, shape:: Tuple{Vararg{Int}} ) = shape
@@ -2034,22 +2044,25 @@ function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T
20342044 T[rs... ;]
20352045end
20362046
2037- # nd concatenation
2047+ # # N-dimensional concatenation ##
20382048
20392049"""
2050+ hvncat(dim::Int, row_first, values...)
20402051 hvncat(dims::Tuple{Vararg{Int}}, row_first, values...)
20412052 hvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)
20422053
20432054Horizontal, vertical, and n-dimensional concatenation of many `values` in one call.
20442055
2045- This function is called
2046- for block matrix syntax. The first argument either specifies the shape of the concatenation,
2047- similar to `hvcat`, as a tuple of tuples, or the dimensions that specify the key number of
2048- elements along each axis, and is used to determine the output dimensions. The `dims` form
2049- is more performant, and is used by default when the concatenation operation has the same
2050- number of elements along each axis (e.g., [a b; c d;;; e f ; g h]). The `shape` form is used
2051- when the number of elements along each axis is unbalanced (e.g., [a b ; c]). Unbalanced
2052- syntax needs additional validation overhead.
2056+ This function is called for block matrix syntax. The first argument either specifies the
2057+ shape of the concatenation, similar to `hvcat`, as a tuple of tuples, or the dimensions that
2058+ specify the key number of elements along each axis, and is used to determine the output
2059+ dimensions. The `dims` form is more performant, and is used by default when the concatenation
2060+ operation has the same number of elements along each axis (e.g., [a b; c d;;; e f ; g h]).
2061+ The `shape` form is used when the number of elements along each axis is unbalanced
2062+ (e.g., [a b ; c]). Unbalanced syntax needs additional validation overhead. The `dim` form
2063+ is an optimization for concatenation along just one dimension. `row_first` indicates how
2064+ `values` are ordered. The meaning of the first and second elements of `shape` are also
2065+ swapped based on `row_first`.
20532066
20542067# Examples
20552068```jldoctest
@@ -2097,6 +2110,24 @@ julia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f)
20972110[:, :, 2] =
20982111 4 5 6
20992112```
2113+
2114+ # Examples for construction of the arguments:
2115+ [a b c ; d e f ;;;
2116+ g h i ; j k l ;;;
2117+ m n o ; p q r ;;;
2118+ s t u ; v w x]
2119+ => dims = (2, 3, 4)
2120+
2121+ [a b ; c ;;; d ;;;;]
2122+ ___ _ _
2123+ 2 1 1 = elements in each row (2, 1, 1)
2124+ _______ _
2125+ 3 1 = elements in each column (3, 1)
2126+ _____________
2127+ 4 = elements in each 3d slice (4,)
2128+ _____________
2129+ 4 = elements in each 4d slice (4,)
2130+ => shape = ((2, 1, 1), (3, 1), (4,), (4,)) with `rowfirst` = true
21002131"""
21012132hvncat (:: Tuple{} , :: Bool ) = []
21022133hvncat (:: Tuple{} , :: Bool , xs... ) = []
@@ -2177,7 +2208,7 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N}
21772208 end
21782209 end
21792210
2180- A = Array {T, nd} (undef, ntuple (d -> cat_size (as[1 ], d), N - 1 )... , Ndim, ntuple (x -> 1 , nd - N)... )
2211+ A = cat_similar (as[ 1 ], T, ( ntuple (d -> size (as[1 ], d), N - 1 )... , Ndim, ntuple (x -> 1 , nd - N)... ) )
21812212 k = 1
21822213 for a ∈ as
21832214 for i ∈ eachindex (a)
@@ -2188,9 +2219,6 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N}
21882219 return A
21892220end
21902221
2191- cat_ndims (a) = 0
2192- cat_ndims (a:: AbstractArray ) = ndims (a)
2193-
21942222function _typed_hvncat (:: Type{T} , :: Val{N} , as... ) where {T, N}
21952223 # optimization for scalars and 1-length arrays that can be concatenated by copying them linearly
21962224 # into the destination
@@ -2257,12 +2285,12 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool,
22572285 elseif currentdims[d] < outdims[d] # dimension in progress
22582286 break
22592287 else # exceeded dimension
2260- ArgumentError (" argument $i has too many elements along axis $d " ) |> throw
2288+ throw ( ArgumentError (" argument $i has too many elements along axis $d " ))
22612289 end
22622290 end
22632291 end
22642292 elseif currentdims[d1] > outdims[d1] # exceeded dimension
2265- ArgumentError (" argument $i has too many elements along axis $d1 " ) |> throw
2293+ throw ( ArgumentError (" argument $i has too many elements along axis $d1 " ))
22662294 end
22672295 end
22682296
@@ -2276,7 +2304,7 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool,
22762304 len == outlen || ArgumentError (" too many elements in arguments; expected $(outlen) , got $(len) " ) |> throw
22772305
22782306 # copy into final array
2279- A = Array {T, nd} (undef , outdims... )
2307+ A = cat_similar (as[ 1 ], T , outdims)
22802308 # @assert all(==(0), currentdims)
22812309 outdims .= 0
22822310 hvncat_fill! (A, currentdims, outdims, d1, d2, as)
@@ -2308,7 +2336,8 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
23082336 if d == 1 || i == 1 || wasstartblock
23092337 currentdims[d] += dsize
23102338 elseif dsize != cat_size (as[i - 1 ], ad)
2311- ArgumentError (" argument $i has a mismatched number of elements along axis $ad ; expected $(cat_size (as[i - 1 ], ad)) , got $dsize " ) |> throw
2339+ throw (ArgumentError (""" argument $i has a mismatched number of elements along axis $ad ; \
2340+ expected $(cat_size (as[i - 1 ], ad)) , got $dsize """ ))
23122341 end
23132342
23142343 wasstartblock = blockcounts[d] == 1 # remember for next dimension
@@ -2318,7 +2347,8 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
23182347 if outdims[d] == 0
23192348 outdims[d] = currentdims[d]
23202349 elseif outdims[d] != currentdims[d]
2321- ArgumentError (" argument $i has a mismatched number of elements along axis $ad ; expected $(abs (outdims[d] - (currentdims[d] - dsize))) , got $dsize " ) |> throw
2350+ throw (ArgumentError (""" argument $i has a mismatched number of elements along axis $ad ; \
2351+ expected $(abs (outdims[d] - (currentdims[d] - dsize))) , got $dsize """ ))
23222352 end
23232353 currentdims[d] = 0
23242354 blockcounts[d] = 0
@@ -2335,12 +2365,12 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
23352365 # @assert all(==(0), blockcounts)
23362366
23372367 # copy into final array
2338- A = Array {T, nd} (undef , outdims... )
2368+ A = cat_similar (as[ 1 ], T , outdims)
23392369 hvncat_fill! (A, currentdims, blockcounts, d1, d2, as)
23402370 return A
23412371end
23422372
2343- function hvncat_fill! (A:: Array {T, N} , scratch1:: Vector{Int} , scratch2:: Vector{Int} , d1:: Int , d2:: Int , as:: Tuple{Vararg} ) where {T, N}
2373+ function hvncat_fill! (A:: AbstractArray {T, N} , scratch1:: Vector{Int} , scratch2:: Vector{Int} , d1:: Int , d2:: Int , as:: Tuple{Vararg} ) where {T, N}
23442374 outdims = size (A)
23452375 offsets = scratch1
23462376 inneroffsets = scratch2
@@ -2382,9 +2412,6 @@ end
23822412 Ai
23832413end
23842414
2385- cat_length (a:: AbstractArray ) = length (a)
2386- cat_length (:: Any ) = 1
2387-
23882415# # Reductions and accumulates ##
23892416
23902417function isequal (A:: AbstractArray , B:: AbstractArray )
0 commit comments