-
-
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
BoundsError when indexing an array with 2d bit array #18271
Comments
Yes, this is intentional. With the new APL indexing behaviors, the shapes of the indices are significant, and so the meaning of indexing by a multidimensional logical array is a little muddled (unless it's the only index provided). See the discussion at #15431 (comment) and preceding comments which led to this decision if you're curious. I think this could be reverted to a deprecation warning to suggest |
In retrospect it would have been nicer to have this go through a deprecation, I'm a little surprised no one said anything earlier. But it is getting very late to put that in, and some of other closely related indexing changes don't really have deprecations. Could just document the behavior change as clearly as we can? |
Ok, I looked through the discussion. I'm still a bit sad and surprised that things like |
Maybe part of the problem there is that |
This is probably the strongest argument in favor of dropping dimensions from reductions. The harm to broadcasting is quite unfortunate, though. I'll post other discussion over at #16606. |
|
The restriction here is purely artificial, just aimed at making it easier to catch mistakes and giving us some leeway in deciding what to do in the future. Clearly, this wasn't an mistake. We could certainly remove this restriction. Or we could loosen it such that it allows arrays with only one non-singleton dimension. I kinda like the latter option. |
@andreasnoack, because you can also reduce over multiple dimensions at once, for example |
@mbauman, won't that be inconsistent with "the output dimensions are equal to the sum of the dimensions of the indices"? |
Yup, but logical indexing is already a fairly strange special case. It's a trade-off. I'm not convinced either way at the moment; just brainstorming possible solutions. |
Logical indexing with a non-vector does seem like a fairly strange and marginal case, so allowing/requiring boolean indexing with non-vectors with all but one dimension singular seems fairly sensible. On the other hand, I feel like we're going to get the "why doesn't produce a vector" question over and over again and the |
Maybe indexing with a one-element tuple, e.g. |
Fixes JuliaLang#18271. Allow multidimensional logical arrays as indices into a particular dimension so long as there is only one non-singleton dimension.
I don't think it's that uncommon, I've been using it pretty often in numpy and julia. I would be really sad if it's gone forever in Julia. :( |
Stefan meant that it already violates some of our ordinary "rules," and was supporting the fix that's already been merged in #18401. In other words, your example works again on master. |
I meant something different too - that I often do things like indexing 3d matrices with 2d BitArray and a normal index for the last dimension ( |
(but thanks for making my example work again!) |
That doesn't work for 0.4, either. Hmm. It's a completely reasonable operation to want to support. |
@timholy Ah, you are right - it doesn't work for 0.4, I got it mixed up with numpy, where it works. Would be really nice if 2d boolean indexing was supported :). |
Thanks for reporting it, @mmagnuski! It's not something I intended to break. Adding support for things like function findcartesian{N}(B::AbstractArray{Bool,N})
idxs = Vector{CartesianIndex{N}}()
for i in CartesianRange(indices(B))
B[i] && push!(idxs, i)
end
idxs
end
julia> A = rand(-5:5, 4, 3, 2)
4×3×2 Array{Int64,3}:
[:, :, 1] =
4 1 0
0 -2 5
0 -1 3
-1 -3 -3
[:, :, 2] =
5 -2 4
-3 -4 -4
-2 -3 5
-5 -2 0
julia> A[findcartesian(A[:,:,1] .> 0), 1] += 10;
A
4×3×2 Array{Int64,3}:
[:, :, 1] =
14 11 0
0 -2 15
0 -1 13
-1 -3 -3
[:, :, 2] =
5 -2 4
-3 -4 -4
-2 -3 5
-5 -2 0 |
@mbauman I like the trick with |
I'm afraid there are some weird edge cases in combining these two functionalities… particularly when there's no non-singleton dimensions. Here's a rather contrived example: julia> A = reshape([-2, 5, -4, -1, -4, 5], 1, 1, 2, 3)
A[A[:,:,1,2] .< 0, 1, 2] # This works on master! One singleton dimension is dropped, making it A[[true], 1, 2]
1-element Array{Int64,1}:
5
julia> A[findcartesian(A[:,:,1,2] .< 0), 1, 2] # This actually returns the element below 0 as intended.
1-element Array{Int64,1}:
-4 I don't think we can tell that case apart from the case where someone used a reduction and they wanted the singleton dimensions dropped. I think there exist less contrived examples, too. I think we need to make reductions drop dimensions, or we need to go through a deprecation cycle to instruct users to use |
I guess dropping singleton dimensions everywhere is the most consistent approach. That makes me want a concise syntax for keeping them all the more since now it's not just for slicing. |
I should say I like your |
Another option would be a binding intended for postfix multiplication — optimized multiplication with something that's effectively |
Yes, that's a good idea too. Seems to be a common way to save on parentheses. |
Fixes #18271. Allow multidimensional logical arrays as indices into a particular dimension so long as there is only one non-singleton dimension. (cherry picked from commit 5fa5b7f) ref #18401 Fixup inline comment (cherry picked from commit 2bbcd80) Update devdocs for bounds checking following #18401 I had forgotten that this behavior was documented in the developer section of the manual when authoring #18401. (cherry picked from commit b8406ff) ref #18552
This issue followed a bit of a meandering path that's a little hard to follow in retrospect. For clarity, let's call "ignoring singleton dimensions in logical indexing" the behavior that allows In response to this issue, I restored the 0.4 behavior to allow singleton dimensions in logical indices in #18401, but it was merged after 0.5 was branched and didn't make the cut for a backport. And so it was subsequently reverted in #18573, once again disallowing singleton dimensions in logical indexing. The plus side is that breaking this behavior allows us to move towards a much more general and more consistent interpretation of multidimensional logical indices, such that the additional dimensions in a logical mask actually represent indexing into additional dimensions into the source array. This generalizes the whole-array masking operations |
Thanks for the update @mbauman! |
Yes, that's my vision here, and I think it's the consensus. |
happy to hear that! 👍 |
The code below:
produces the following error on julia-0.5.0-rc3:
This used to work on julia 0.4 - is the change intended?
Doing
A[:, vec(b)]
works of course.The text was updated successfully, but these errors were encountered: