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

Add insertdims method which is inverse to dropdims #45793

Merged
merged 29 commits into from
Aug 2, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
9903e42
Add insertdims
roflmaostc Jun 23, 2022
0f93207
Update abstractarraymath.jl
roflmaostc Jun 23, 2022
bd6e45e
Fix some whitespaces and doctest [skip ci]
roflmaostc Jun 24, 2022
f4087a2
Handle merge [skip ci]
roflmaostc Jun 24, 2022
50ae007
Merge branch 'JuliaLang:master' into master
roflmaostc May 30, 2024
4f53621
Fix bug in _foldoneto call
roflmaostc May 30, 2024
1196b8f
Add test for multiple singleton dimensions at one dim
roflmaostc May 31, 2024
6f986dc
Update base/abstractarraymath.jl
roflmaostc Jul 25, 2024
16e0203
Update base/abstractarraymath.jl
roflmaostc Jul 25, 2024
cf23193
Update base/abstractarraymath.jl
roflmaostc Jul 25, 2024
6057e22
Add docs
roflmaostc Jul 25, 2024
84d0693
Update base/abstractarraymath.jl
roflmaostc Jul 25, 2024
aa51242
Merge branch 'JuliaLang:master' into master
roflmaostc Jul 25, 2024
8648d84
Add news
roflmaostc Jul 25, 2024
080c83c
Fix merge mistake
roflmaostc Jul 26, 2024
ec383d9
Rebase [skip ci]
roflmaostc Jul 27, 2024
66d0561
Update test/arrayops.jl [skip ci]
roflmaostc Jul 27, 2024
bdb3258
Update base/abstractarraymath.jl
roflmaostc Jul 27, 2024
0ddee55
Update comment in code [skip ci]
roflmaostc Jul 27, 2024
76b31f7
Remove parts in docstring [skip ci]
roflmaostc Jul 27, 2024
490b103
Adapt docstring
roflmaostc Jul 27, 2024
98283db
Remove trailing whitespace
roflmaostc Jul 27, 2024
c321d51
Remove trailing whitespace in test [skip ci]
roflmaostc Jul 27, 2024
2a9e3ac
Update base/abstractarraymath.jl [skip ci]
roflmaostc Jul 27, 2024
d7cb35c
Rewrite doc [skip ci]
roflmaostc Jul 27, 2024
514b4fc
Update test/arrayops.jl
roflmaostc Aug 1, 2024
4f07e18
Update test/arrayops.jl
roflmaostc Aug 1, 2024
cfa1465
Update base/abstractarraymath.jl
roflmaostc Aug 1, 2024
9f174b7
Update base/abstractarraymath.jl
roflmaostc Aug 1, 2024
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
76 changes: 76 additions & 0 deletions base/abstractarraymath.jl
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,82 @@ function _dropdims(A::AbstractArray, dims::Dims)
end
_dropdims(A::AbstractArray, dim::Integer) = _dropdims(A, (Int(dim),))


"""
insertdims(A; dims)

Return an array with the same data as `A`, but with singleton dimensions specified by
`dims` inserted.
The dimensions of `A` and `dims` must be contiguous.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What does "contiguous" mean here? Does it refer to dims? But dims=(1, 3) in the examples aren't contiguous.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Of A and dims together.
insertdims([1,2,3], dims=(3,)) would be invalid because it jumps over the second dimension.

Copy link
Member

@mbauman mbauman Jul 26, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do think this could be worded slightly better and could help address the other point simultaneously. Maybe:

Suggested change
The dimensions of `A` and `dims` must be contiguous.
The new singleton dimensions are inserted immediately before the specified `dims`. The `dims` may repeat, all must be in `1:ndims(A)+1`, and they must be in sorted order.

If dimensions occur multiple times in `dims`, several singleton dimensions are inserted.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
If dimensions occur multiple times in `dims`, several singleton dimensions are inserted.
If dimensions occur multiple times in `dims`, several singleton dimensions are inserted after the requested position.

?


The result shares the same underlying data as `A`, such that the
result is mutable if and only if `A` is mutable, and setting elements of one
alters the values of the other.

See also: [`reshape`](@ref), [`dropdims`](@ref), [`vec`](@ref).

# Examples
```jldoctest
julia> a = [1 2; 3 4]
2×2 Matrix{Int64}:
1 2
3 4

julia> b = insertdims(a, dims=(1,1))
1×1×2×2 Array{Int64, 4}:
[:, :, 1, 1] =
1

[:, :, 2, 1] =
3

[:, :, 1, 2] =
2

[:, :, 2, 2] =
4

julia> b = insertdims(a, dims=(1,2))
1×2×1×2 Array{Int64, 4}:
[:, :, 1, 1] =
1 3

[:, :, 1, 2] =
2 4

julia> b = insertdims(a, dims=(1,3))
1×2×2×1 Array{Int64, 4}:
[:, :, 1, 1] =
1 3

[:, :, 2, 1] =
2 4

julia> b[1,1,1,1] = 5; a
2×2 Matrix{Int64}:
5 2
3 4
```
roflmaostc marked this conversation as resolved.
Show resolved Hide resolved
roflmaostc marked this conversation as resolved.
Show resolved Hide resolved
"""
insertdims(A; dims) = _insertdims(A, dims)
function _insertdims(A::AbstractArray{T, N}, dims::Tuple{Vararg{Int64, M}}) where {T, N, M}
roflmaostc marked this conversation as resolved.
Show resolved Hide resolved
maximum(dims) ≤ ndims(A)+1 || throw(ArgumentError("The largest entry in dims must be ≤ ndims(A) + 1."))
1 ≤ minimum(dims) || throw(ArgumentError("The smallest entry in dims must be ≥ 1."))
issorted(dims) || throw(ArgumentError("dims=$(dims) are not sorted"))
roflmaostc marked this conversation as resolved.
Show resolved Hide resolved

# n is the current index where we maybe insert
ax_n = _foldoneto(((ds, n, dims), _) ->
dims != Tuple(()) && n == first(dims) ?
((ds..., Base.OneTo(1)), n, tail(dims)) :
((), 1, dims), Val(ndims(A) + length(dims)))
# we need only the new shape
reshape(A, ax_n[1])
mbauman marked this conversation as resolved.
Show resolved Hide resolved
end
_insertdims(A::AbstractArray, dim::Integer) = _insertdims(A, (Int(dim),))



## Unary operators ##

"""
Expand Down
1 change: 1 addition & 0 deletions base/exports.jl
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,7 @@ export
indexin,
argmax,
argmin,
insertdims,
invperm,
invpermute!,
isassigned,
Expand Down
11 changes: 11 additions & 0 deletions test/arrayops.jl
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,17 @@ end
@test_throws ArgumentError dropdims(a, dims=4)
@test_throws ArgumentError dropdims(a, dims=6)


a = rand(8, 7)
@test @inferred(insertdims(a, dims=1)) == @inferred(insertdims(a, dims=(1,))) == reshape(a, (1, 8, 7))
@test @inferred(insertdims(a, dims=(1, 3))) == reshape(a, (1, 8, 7, 1))
@test @inferred(insertdims(a, dims=(1, 2, 3))) == reshape(a, (1, 8, 1, 7, 1))
@test_throws UndefKeywordError insertdims(a)
@test_throws ArgumentError insertdims(a, dims=0)
@test_throws ArgumentError insertdims(a, dims=(1, 2, 1))
@test_throws ArgumentError insertdims(a, dims=4)
@test_throws ArgumentError insertdims(a, dims=6)

sz = (5,8,7)
A = reshape(1:prod(sz),sz...)
@test A[2:6] == [2:6;]
Expand Down
Loading