@@ -1635,11 +1635,21 @@ cat_size(A::AbstractArray) = size(A)
1635
1635
cat_size (A, d) = 1
1636
1636
cat_size (A:: AbstractArray , d) = size (A, d)
1637
1637
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
+
1638
1644
cat_indices (A, d) = OneTo (1 )
1639
1645
cat_indices (A:: AbstractArray , d) = axes (A, d)
1640
1646
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... )
1643
1653
1644
1654
# These are for backwards compatibility (even though internal)
1645
1655
cat_shape (dims, shape:: Tuple{Vararg{Int}} ) = shape
@@ -2034,22 +2044,25 @@ function typed_hvcat(::Type{T}, rows::Tuple{Vararg{Int}}, as...) where T
2034
2044
T[rs... ;]
2035
2045
end
2036
2046
2037
- # nd concatenation
2047
+ # # N-dimensional concatenation ##
2038
2048
2039
2049
"""
2050
+ hvncat(dim::Int, row_first, values...)
2040
2051
hvncat(dims::Tuple{Vararg{Int}}, row_first, values...)
2041
2052
hvncat(shape::Tuple{Vararg{Tuple}}, row_first, values...)
2042
2053
2043
2054
Horizontal, vertical, and n-dimensional concatenation of many `values` in one call.
2044
2055
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`.
2053
2066
2054
2067
# Examples
2055
2068
```jldoctest
@@ -2097,6 +2110,24 @@ julia> hvncat(((3, 3), (3, 3), (6,)), true, a, b, c, d, e, f)
2097
2110
[:, :, 2] =
2098
2111
4 5 6
2099
2112
```
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
2100
2131
"""
2101
2132
hvncat (:: Tuple{} , :: Bool ) = []
2102
2133
hvncat (:: Tuple{} , :: Bool , xs... ) = []
@@ -2177,7 +2208,7 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N}
2177
2208
end
2178
2209
end
2179
2210
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)... ) )
2181
2212
k = 1
2182
2213
for a ∈ as
2183
2214
for i ∈ eachindex (a)
@@ -2188,9 +2219,6 @@ function _typed_hvncat(::Type{T}, ::Val{N}, as::AbstractArray...) where {T, N}
2188
2219
return A
2189
2220
end
2190
2221
2191
- cat_ndims (a) = 0
2192
- cat_ndims (a:: AbstractArray ) = ndims (a)
2193
-
2194
2222
function _typed_hvncat (:: Type{T} , :: Val{N} , as... ) where {T, N}
2195
2223
# optimization for scalars and 1-length arrays that can be concatenated by copying them linearly
2196
2224
# into the destination
@@ -2257,12 +2285,12 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool,
2257
2285
elseif currentdims[d] < outdims[d] # dimension in progress
2258
2286
break
2259
2287
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 " ))
2261
2289
end
2262
2290
end
2263
2291
end
2264
2292
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 " ))
2266
2294
end
2267
2295
end
2268
2296
@@ -2276,7 +2304,7 @@ function _typed_hvncat(::Type{T}, dims::Tuple{Vararg{Int, N}}, row_first::Bool,
2276
2304
len == outlen || ArgumentError (" too many elements in arguments; expected $(outlen) , got $(len) " ) |> throw
2277
2305
2278
2306
# copy into final array
2279
- A = Array {T, nd} (undef , outdims... )
2307
+ A = cat_similar (as[ 1 ], T , outdims)
2280
2308
# @assert all(==(0), currentdims)
2281
2309
outdims .= 0
2282
2310
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
2308
2336
if d == 1 || i == 1 || wasstartblock
2309
2337
currentdims[d] += dsize
2310
2338
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 """ ))
2312
2341
end
2313
2342
2314
2343
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
2318
2347
if outdims[d] == 0
2319
2348
outdims[d] = currentdims[d]
2320
2349
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 """ ))
2322
2352
end
2323
2353
currentdims[d] = 0
2324
2354
blockcounts[d] = 0
@@ -2335,12 +2365,12 @@ function _typed_hvncat(::Type{T}, shape::Tuple{Vararg{Tuple, N}}, row_first::Boo
2335
2365
# @assert all(==(0), blockcounts)
2336
2366
2337
2367
# copy into final array
2338
- A = Array {T, nd} (undef , outdims... )
2368
+ A = cat_similar (as[ 1 ], T , outdims)
2339
2369
hvncat_fill! (A, currentdims, blockcounts, d1, d2, as)
2340
2370
return A
2341
2371
end
2342
2372
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}
2344
2374
outdims = size (A)
2345
2375
offsets = scratch1
2346
2376
inneroffsets = scratch2
@@ -2382,9 +2412,6 @@ end
2382
2412
Ai
2383
2413
end
2384
2414
2385
- cat_length (a:: AbstractArray ) = length (a)
2386
- cat_length (:: Any ) = 1
2387
-
2388
2415
# # Reductions and accumulates ##
2389
2416
2390
2417
function isequal (A:: AbstractArray , B:: AbstractArray )
0 commit comments