-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
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 squeeze(A)
method to squeeze all singleton dimensions
#22000
Conversation
base/abstractarraymath.jl
Outdated
``` | ||
""" | ||
function squeeze(A::AbstractArray) | ||
singleton_dims = [d for d in 1:ndims(A) if size(A, d) == 1] |
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.
Maybe using a generator would be more efficient here?
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.
Although it doesn't effect performance that much (we need to collect the generator output before passing it to squeeze(A, dims)
in all cases) it is useless to create a temporary array, so I've done away with that, thanks.
1 3 | ||
2 4 | ||
``` | ||
""" |
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.
Perhaps add a warning re. the potential pitfalls of this method?
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.
I'm not sure what I would write? This function is incredibly straightforward; it removes all singleton dimensions.
Looking back over the previous discussion, it looks like the concern is that you may pass in an NxMxL
matrix expecting L
to equal 1, but then being surprised when M
also happened to equal 1 and thus the result is a 1-dimensional array. I'm not sure how to make the docstring more explicit that such a thing will happen; that is, after all, the entire point of this function.
I still don't think we should have this – it is inherently type unstable and will be an inevitable cause of buggy corner cases. Instead, I've previously proposed |
The type instability is kind of the point; I have code that takes in a variable that on 0.5 ends up being a Half of the whole reason I'm proposing this is because the Personally, most of the reason I want this kind of a function is to enforce type stability, rather than create type instability. I want to accept Vectors, 1xN matrices, Nx1 matrices, etc.... and convert all of them to a Vector. Or I want to accept Matrices, NxMx1 tensors, etc..... and convert all of them to a Matrix. In a sense, I care less about what dimensions I'm starting with, and more about what dimensions I end with, so maybe we should attack this the other way around and come up with a smart way of squeezing with a deterministic return type, but in such a way that doesn't require me to perfectly determine the input dimensions so that I don't have to special-case on whether its a column vector or a row-vector, etc... |
This is exactly what |
(I'm beginning to labour this point - but since frequently Nx1 or 1xN matrices or row vectors are desired shapes in similar situations, functions for these in anology to |
@staticfloat, just to clarify: it's not possible to have In contrast, |
Maybe a nn(A, (1,3)) == A[:,1,:] # or error if size(A,n) ≠ 1 for any n ∉ {1, 3} By making duplicate dimensions in |
This is close, and I will tend to use it, but Perhaps what I really want is the inverse of #21977, so that I can just give a higher-order tensor to a |
Hm, then maybe a decent spelling is something like |
Yeah, I like that a lot. Let's define it to remove dimensions from right to left, so e.g. |
It could also be useful for that function to add singleton dimensions when needed: |
|
|
Having a wider range of conversions or constructors that follow this behavior certainly would solve this problem. Though I'm not sure specifying the type is exactly what you want - really you want something that hooks into the |
It's one thing to |
Right - I agree, a method for |
For the sake of bikeshedding, one possible name for the inverse of |
|
Another option for all this might be specialized index types:
This is completely doable since we can dispatch on function types. |
That's a really neat idea but it seems kind of obscure to me. |
The main advantage is that it tells you which dimensions to "inflate." Say you want to convert a matrix into a 5-tensor, how do you specify which dimensions should be singletons? |
APL indexing a dimension with column/row matrices also inserts a singleton dimension. Maybe we can utilise this somehow? |
This is what numpy's Interestingly, when I saw you passing functions to indexing as an email preview — without any other context — my first thought was that you might have been proposing a new idiom for specifying reductions. See #16606 for that digression. |
I'm going to close this in favor of #23500 |
This simple definition makes it easier to write reductions that drops the dimensions over which they reduce. Fixes JuliaLang#16606, addresses part of the root issue in JuliaLang#22000.
This addresses #11838, which gave me hope that this might be accepted. I'm not sure I agree with the "the user may accidentally shoot themselves in the foot" argument; it seems to me that this function does something useful (that at least a few people want) and the behavior is very straightforward, and so isn't something to cause much surprise.
The only surprising thing about this implementation is that passing in an array with nothing but singleton dimensions returns a zero-dimensional array:
Of course, this is what happens with the old squeeze as well: