Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve docs for vcat, cat, etc. #46429

Merged
merged 6 commits into from
Oct 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
197 changes: 106 additions & 91 deletions base/abstractarray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1813,111 +1813,110 @@ end
"""
vcat(A...)

Concatenate along dimension 1. To efficiently concatenate a large vector of arrays,
use `reduce(vcat, x)`.
Concatenate arrays or numbers vertically. Equivalent to [`cat`](@ref)`(A...; dims=1)`,
and to the syntax `[a; b; c]`.

To concatenate a large vector of arrays, `reduce(vcat, A)` calls an efficient method
when `A isa AbstractVector{<:AbstractVecOrMat}`, rather than working pairwise.

See also [`hcat`](@ref), [`Iterators.flatten`](@ref), [`stack`](@ref).

# Examples
```jldoctest
julia> a = [1 2 3 4 5]
1×5 Matrix{Int64}:
1 2 3 4 5
julia> v = vcat([1,2], [3,4])
4-element Vector{Int64}:
1
2
3
4

julia> b = [6 7 8 9 10; 11 12 13 14 15]
2×5 Matrix{Int64}:
6 7 8 9 10
11 12 13 14 15
julia> v == vcat(1, 2, [3,4]) # accepts numbers
true

julia> vcat(a,b)
3×5 Matrix{Int64}:
1 2 3 4 5
6 7 8 9 10
11 12 13 14 15
julia> v == [1; 2; [3,4]] # syntax for the same operation
true

julia> c = ([1 2 3], [4 5 6])
([1 2 3], [4 5 6])
julia> summary(ComplexF64[1; 2; [3,4]]) # syntax for supplying the element type
"4-element Vector{ComplexF64}"

julia> vcat(c...)
2×3 Matrix{Int64}:
1 2 3
4 5 6
julia> vcat(range(1, 2, length=3)) # collects lazy ranges
3-element Vector{Float64}:
1.0
1.5
2.0

julia> two = ([10, 20, 30]', Float64[4 5 6; 7 8 9]) # row vector and a matrix
([10 20 30], [4.0 5.0 6.0; 7.0 8.0 9.0])

julia> vs = [[1, 2], [3, 4], [5, 6]]
3-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
[5, 6]
julia> vcat(two...)
3×3 Matrix{Float64}:
10.0 20.0 30.0
4.0 5.0 6.0
7.0 8.0 9.0

julia> reduce(vcat, vs)
julia> vs = [[1, 2], [3, 4], [5, 6]];

julia> reduce(vcat, vs) # more efficient than vcat(vs...)
6-element Vector{Int64}:
1
2
3
4
5
6

julia> ans == collect(Iterators.flatten(vs))
true
```
"""
vcat(X...) = cat(X...; dims=Val(1))
"""
hcat(A...)

Concatenate along dimension 2. To efficiently concatenate a large vector of arrays,
use `reduce(hcat, x)`.
Concatenate arrays or numbers horizontally. Equivalent to [`cat`](@ref)`(A...; dims=2)`,
and to the syntax `[a b c]` or `[a;; b;; c]`.

For a large vector of arrays, `reduce(hcat, A)` calls an efficient method
when `A isa AbstractVector{<:AbstractVecOrMat}`.
For a vector of vectors, this can also be written [`stack`](@ref)`(A)`.

See also [`vcat`](@ref), [`hvcat`](@ref).

# Examples
```jldoctest
julia> a = [1; 2; 3; 4; 5]
5-element Vector{Int64}:
1
2
3
4
5
julia> hcat([1,2], [3,4], [5,6])
2×3 Matrix{Int64}:
1 3 5
2 4 6

julia> b = [6 7; 8 9; 10 11; 12 13; 14 15]
5×2 Matrix{Int64}:
6 7
8 9
10 11
12 13
14 15

julia> hcat(a,b)
5×3 Matrix{Int64}:
1 6 7
2 8 9
3 10 11
4 12 13
5 14 15

julia> c = ([1; 2; 3], [4; 5; 6])
([1, 2, 3], [4, 5, 6])

julia> hcat(c...)
3×2 Matrix{Int64}:
1 4
2 5
3 6
julia> hcat(1, 2, [30 40], [5, 6, 7]') # accepts numbers
1×7 Matrix{Int64}:
1 2 30 40 5 6 7

julia> x = Matrix(undef, 3, 0) # x = [] would have created an Array{Any, 1}, but need an Array{Any, 2}
3×0 Matrix{Any}
julia> ans == [1 2 [30 40] [5, 6, 7]'] # syntax for the same operation
true

julia> hcat(x, [1; 2; 3])
3×1 Matrix{Any}:
1
2
3
julia> Float32[1 2 [30 40] [5, 6, 7]'] # syntax for supplying the eltype
1×7 Matrix{Float32}:
1.0 2.0 30.0 40.0 5.0 6.0 7.0

julia> vs = [[1, 2], [3, 4], [5, 6]]
3-element Vector{Vector{Int64}}:
[1, 2]
[3, 4]
[5, 6]
julia> ms = [zeros(2,2), [1 2; 3 4], [50 60; 70 80]];

julia> reduce(hcat, vs)
2×3 Matrix{Int64}:
1 3 5
2 4 6
julia> reduce(hcat, ms) # more efficient than hcat(ms...)
2×6 Matrix{Float64}:
0.0 0.0 1.0 2.0 50.0 60.0
0.0 0.0 3.0 4.0 70.0 80.0

julia> stack(ms) |> summary # disagrees on a vector of matrices
"2×2×3 Array{Float64, 3}"

julia> hcat(Int[], Int[], Int[]) # empty vectors, each of size (0,)
0×3 Matrix{Int64}

julia> hcat([1.1, 9.9], Matrix(undef, 2, 0)) # hcat with empty 2×0 Matrix
2×1 Matrix{Any}:
1.1
9.9
```
"""
hcat(X...) = cat(X...; dims=Val(2))
Expand All @@ -1928,34 +1927,45 @@ typed_hcat(::Type{T}, X...) where T = _cat_t(Val(2), T, X...)
"""
cat(A...; dims)

Concatenate the input arrays along the specified dimensions in the iterable `dims`. For
dimensions not in `dims`, all input arrays should have the same size, which will also be the
size of the output array along that dimension. For dimensions in `dims`, the size of the
output array is the sum of the sizes of the input arrays along that dimension. If `dims` is
a single number, the different arrays are tightly stacked along that dimension. If `dims` is
an iterable containing several dimensions, this allows one to construct block diagonal
matrices and their higher-dimensional analogues by simultaneously increasing several
dimensions for every new input array and putting zero blocks elsewhere. For example,
`cat(matrices...; dims=(1,2))` builds a block diagonal matrix, i.e. a block matrix with
`matrices[1]`, `matrices[2]`, ... as diagonal blocks and matching zero blocks away from the
diagonal.
Concatenate the input arrays along the dimensions specified in `dims`.

Along a dimension `d in dims`, the size of the output array is `sum(size(a,d) for
a in A)`.
Along other dimensions, all input arrays should have the same size,
which will also be the size of the output array along those dimensions.

If `dims` is a single number, the different arrays are tightly packed along that dimension.
If `dims` is an iterable containing several dimensions, the positions along these dimensions
are increased simultaneously for each input array, filling with zero elsewhere.
This allows one to construct block-diagonal matrices as `cat(matrices...; dims=(1,2))`,
and their higher-dimensional analogues.

The special case `dims=1` is [`vcat`](@ref), and `dims=2` is [`hcat`](@ref).
See also [`hvcat`](@ref), [`stack`](@ref), [`repeat`](@ref).

See also [`hcat`](@ref), [`vcat`](@ref), [`hvcat`](@ref), [`repeat`](@ref).
The keyword also accepts `Val(dims)`.

!!! compat "Julia 1.8"
For multiple dimensions `dims = Val(::Tuple)` was added in Julia 1.8.

# Examples
```jldoctest
julia> cat([1 2; 3 4], [pi, pi], fill(10, 2,3,1); dims=2)
julia> cat([1 2; 3 4], [pi, pi], fill(10, 2,3,1); dims=2) # same as hcat
2×6×1 Array{Float64, 3}:
[:, :, 1] =
1.0 2.0 3.14159 10.0 10.0 10.0
3.0 4.0 3.14159 10.0 10.0 10.0

julia> cat(true, trues(2,2), trues(4)', dims=(1,2))
julia> cat(true, trues(2,2), trues(4)', dims=(1,2)) # block-diagonal
4×7 Matrix{Bool}:
1 0 0 0 0 0 0
0 1 1 0 0 0 0
0 1 1 0 0 0 0
0 0 0 1 1 1 1

julia> cat(1, [2], [3;;]; dims=Val(2))
1×3 Matrix{Int64}:
1 2 3
```
"""
@inline cat(A...; dims) = _cat(dims, A...)
Expand Down Expand Up @@ -3064,7 +3074,7 @@ concatenated along the remaining dimensions.
For example, if `dims = [1,2]` and `A` is 4-dimensional, then `f` is called on `x = A[:,:,i,j]`
for all `i` and `j`, and `f(x)` becomes `R[:,:,i,j]` in the result `R`.

See also [`eachcol`](@ref), [`eachslice`](@ref), [`mapreduce`](@ref).
See also [`eachcol`](@ref) or [`eachslice`](@ref), used with [`map`](@ref) or [`stack`](@ref).

# Examples
```jldoctest
Expand All @@ -3084,7 +3094,7 @@ julia> A = reshape(1:30,(2,5,3))

julia> f(x::Matrix) = fill(x[1,1], 1,4); # returns a 1×4 matrix

julia> mapslices(f, A, dims=(1,2))
julia> B = mapslices(f, A, dims=(1,2))
1×4×3 Array{$Int, 3}:
[:, :, 1] =
1 1 1 1
Expand All @@ -3095,6 +3105,11 @@ julia> mapslices(f, A, dims=(1,2))
[:, :, 3] =
21 21 21 21

julia> f2(x::AbstractMatrix) = fill(x[1,1], 1,4);

julia> B == stack(f2, eachslice(A, dims=3))
true

julia> g(x) = x[begin] // x[end-1]; # returns a number

julia> mapslices(g, A, dims=[1,3])
Expand Down
6 changes: 4 additions & 2 deletions base/reduce.jl
Original file line number Diff line number Diff line change
Expand Up @@ -459,8 +459,10 @@ For empty collections, providing `init` will be necessary, except for some speci
neutral element of `op`.

Reductions for certain commonly-used operators may have special implementations, and
should be used instead: `maximum(itr)`, `minimum(itr)`, `sum(itr)`, `prod(itr)`,
`any(itr)`, `all(itr)`.
should be used instead: [`maximum`](@ref)`(itr)`, [`minimum`](@ref)`(itr)`, [`sum`](@ref)`(itr)`,
[`prod`](@ref)`(itr)`, [`any`](@ref)`(itr)`, [`all`](@ref)`(itr)`.
There are efficient methods for concatenating certain arrays of arrays
by calling `reduce(`[`vcat`](@ref)`, arr)` or `reduce(`[`hcat`](@ref)`, arr)`.

The associativity of the reduction is implementation dependent. This means that you can't
use non-associative operations like `-` because it is undefined whether `reduce(-,[1,2,3])`
Expand Down
6 changes: 6 additions & 0 deletions base/slicearray.jl
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,8 @@ the ordering of the dimensions will match those in `dims`. If `drop = false`, th
`Slices` will have the same dimensionality as the underlying array, with inner
dimensions having size 1.

See [`stack`](@ref)`(slices; dims)` for the inverse of `eachcol(A; dims::Integer, drop=true)`.

See also [`eachrow`](@ref), [`eachcol`](@ref), [`mapslices`](@ref) and [`selectdim`](@ref).

!!! compat "Julia 1.1"
Expand Down Expand Up @@ -131,6 +133,8 @@ end
Create a [`RowSlices`](@ref) object that is a vector of rows of matrix or vector `A`.
Row slices are returned as `AbstractVector` views of `A`.

For the inverse, see [`stack`](@ref)`(rows; dims=1)`.

See also [`eachcol`](@ref), [`eachslice`](@ref) and [`mapslices`](@ref).

!!! compat "Julia 1.1"
Expand Down Expand Up @@ -167,6 +171,8 @@ eachrow(A::AbstractVector) = eachrow(reshape(A, size(A,1), 1))
Create a [`ColumnSlices`](@ref) object that is a vector of columns of matrix or vector `A`.
Column slices are returned as `AbstractVector` views of `A`.

For the inverse, see [`stack`](@ref)`(cols)` or `reduce(`[`hcat`](@ref)`, cols)`.

See also [`eachrow`](@ref), [`eachslice`](@ref) and [`mapslices`](@ref).

!!! compat "Julia 1.1"
Expand Down