-
Notifications
You must be signed in to change notification settings - Fork 43
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
Extending Base.stack for DimArrays #645
base: main
Are you sure you want to change the base?
Changes from 6 commits
4ea5e40
ec3b2cf
0b762ce
6affd9b
ac3affc
83ace60
e6cfb1b
ce16068
bdf151f
7a4cf26
3314852
0ac2eb0
884ab68
c369d06
2c7b8b9
cf57f86
0a278a6
f41f424
d9ee5e7
9b3b3b7
25dc8a2
e2aeb0e
39c78e8
16c205a
15cc9fd
52ce34a
f868ddf
911acda
9517d16
b329519
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -547,6 +547,86 @@ $message on dimension $D. | |
To fix for `AbstractDimArray`, pass new lookup values as `cat(As...; dims=$D(newlookupvals))` keyword or `dims=$D()` for empty `NoLookup`. | ||
""" | ||
|
||
function Base._typed_stack(::Colon, ::Type{T}, ::Type{S}, A, Aax=_iterator_axes(A)) where {T,S<:AbstractDimArray} | ||
origdims = map(dims, A) | ||
_A = parent.(A) | ||
t = eltype(_A) | ||
_A = Base._typed_stack(:, T, t, A) | ||
|
||
if !comparedims(Bool, origdims...; | ||
order=true, val=true, warn=" Can't `stack` AbstractDimArray, applying to `parent` object." | ||
) | ||
return _A | ||
else | ||
DimArray(_A, (first(origdims)..., AnonDim())) | ||
rafaqz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
end | ||
|
||
function Base._dim_stack(newdim::Integer, ::Type{T}, ::Type{S}, A) where {T,S<:AbstractDimArray} | ||
origdims = dims.(A) | ||
_A = parent.(A) | ||
t = eltype(_A) | ||
_A = Base._dim_stack(newdim, T, t, A) | ||
|
||
if !comparedims(Bool, origdims...; | ||
order=true, val=true, warn=" Can't `stack` AbstractDimArray, applying to `parent` object." | ||
) | ||
return _A | ||
end | ||
|
||
newdims = first(origdims) | ||
newdims = ntuple(length(newdims) + 1) do d | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is this type-stable? |
||
if d == newdim | ||
AnonDim() | ||
else # Return the old dimension, shifted across once if it comes after the new dim | ||
newdims[d-(d>newdim)] | ||
end | ||
end | ||
DimArray(_A, newdims) | ||
rafaqz marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
|
||
""" | ||
Base.stack([dim::Dimension], A::AbstractVector{<:AbstractDimArray}; dims=nothing) | ||
|
||
Stack arrays along a specified axis `dims`, while preserving the dimensional | ||
information of other axes. | ||
If the optional `Dimension` argument `dim` is supplied, it must have | ||
`length(dim) == length(A)`; the resulting axis `dims` is given the dimension `dim`. | ||
If `dim` is not supplied, the new dimension will be an `AnonDim`. | ||
|
||
# Examples | ||
```julia-repl | ||
julia> da = DimArray([1 2 3; 4 5 6], (X(10:10:20), Y(300:-100:100))); | ||
julia> db = DimArray([6 5 4; 3 2 1], (X(10:10:20), Y(300:-100:100))); | ||
|
||
# Stack along a new dimension `Z` | ||
julia> dc = stack(Z(1:2), [da, db], dims=3) | ||
╭─────────────────────────╮ | ||
│ 2×3×2 DimArray{Int64,3} │ | ||
├─────────────────────────┴──────────────────────────────── dims ┐ | ||
↓ X Sampled{Int64} 10:10:20 ForwardOrdered Regular Points, | ||
→ Y Sampled{Int64} 300:-100:100 ReverseOrdered Regular Points, | ||
↗ Z 1:2 | ||
└────────────────────────────────────────────────────────────────┘ | ||
|
||
julia> dims(dc, 3) == Z(1:2) | ||
true | ||
julia> parent(dc) == stack(map(parent, [da, db]), dims=3) | ||
true | ||
``` | ||
""" | ||
function Base.stack(dim::Dimension, A::AbstractVector{<:AbstractDimArray}; dims=nothing, kwargs...) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whats the idea with The tests also don't hit this code. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not pass This method signature is a bit strange , we usually try not to add varients on Base methods, we just allow |
||
B = Base.stack(A; dims, kwargs...) | ||
newdims = ntuple(ndims(B)) do d | ||
if d == dims # Use the new provided dimension | ||
dim | ||
else | ||
DimensionalData.dims(B, d) | ||
end | ||
end | ||
rebuild(B; dims=newdims) | ||
end | ||
|
||
function Base.inv(A::AbstractDimArray{T,2}) where T | ||
newdata = inv(parent(A)) | ||
newdims = reverse(dims(A)) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
How stable do you think these methods are... could we add a method to
Base.stack
instead? What do we gain from touching these internals?I know we use internals elsewhere, but we should stop:
#522