-
-
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
Broadcast Array Indexing #19169
Comments
I know your request is much more general than your example, but in this very specific case I'd use This syntax has also been proposed as a "pointwise" indexing operation — that is, instead of vectorizing over the array being indexed, you vectorize over the indices (#2591). Personally, I think that's more in-line with vectorized function calls; your suggestion would seem surprising to me. |
@mbauman if (Actually, destructuring arrays like this is a very common thing to want to do, in some fields. Sometimes I even want something like |
It just seems complicated and surprising to me. By analogy to the This gets even worse with assignment. What parts of |
If For example, |
This seems reasonable to me. I'm trying to think of whether there is some other reasonable use for |
I think the difficulty stems from the fact that indices work element-wise into an array. That is, I typically think of collections of indices and one atomic source array. By broadcasting over both the source and the indices you're treating both parts as though they're both collections of things. This really only makes sense if the source is a collection of arrays. Personally, I find that a lot less useful. It's easiest to think about this with concrete examples. Pointwise indexing makes it trivial to extract the diagonal from a square matrix with Finally, I must say it's much easier to explain the behavior if the source array isn't a part of the broadcast operation. You broadcast the indices to a common size and index into the source. This works for both indexing and assignment. While the other semantic is really easy to implement, I'm not sure I know how to explain it without resorting to |
Isn't #2591 doable (and perhaps clearer) with a By which I mean something like diagonals = mat[i -> (i,i), 1:end] In fact what you really want is a diagonals = mat[i,i for i = 1:end] Would there be parsing issues with typed comprehensions here? Currently we try to construct I agree with @mbauman that it does seem that |
@andyferris I think that a nice way to deal with ambiguity would be to overload The type of indexing suggested in #2591 seems like a whole new brand of indexing, which should have a unique notation, such as |
I think I agree with @mbauman's assessment that broadcasting over the collection being indexed into is too confusing and not terribly common. The pointwise indexing operation described in #2591, otoh, seems fairly useful to me – I've certainly used ind2sub and sub2ind with linear indexing to accomplish this sort of thing before. These days we want to avoid linear indexing wherever possible, especially in generic code, so it would be good to have a syntax for this. The difference seems to be that this issue wants broadcasting |
Yeah, I think we're talking past each other with three different behaviors here. Correct me if I'm wrong:
I'm actually rather surprised that #2591 hasn't garnered more support, but perhaps you're right that folks have just been getting by with linear indexing. I don't think we need to bend over backwards to find a meaning for |
@mbauman @andyferris and I are referring to the same thing, namely the behavior that you assigned to him.
I want the singleton expansion that is offered with |
I'm all for #2591. It was more out of left field when it was proposed, but these syntaxes are perfectly analogous: f.(X...) => broadcast((x...)->f(x...), X...) # aka broadcast(f, X...)
A.[X...] => broadcast((x...)->A[x...], X...) When you write |
I completely disagree. |
@StefanKarpinski from that perspective,
|
Here's the problem with that point of view though: the thing to the left of the A.[X...] => broadcast(getindex, A, X...) # aka getindex.(A, X...)
f.(X...) => broadcast(call, f, X...) # implied by analogy ≠ real definition Except that |
Indexing is a different beast from calling a function. It's like calling a function with an argument on the left and the other arguments on the right. I'm not sure I follow your logic. Basically, if indexing were done as |
Calling a function and indexing into an array are not all that different. In Matlab, APL and other languages, they even have the same syntax (which has its own problems but makes a certain amount of sense). Moreover, in Julia 0.4 As it happens, |
This seems perfectly compelling to me: f.(X...) => broadcast((x...)->f(x...), X...) # aka broadcast(f, X...)
A.[X...] => broadcast((x...)->A[x...], X...) I'll withdraw my objection in the interest of moving forward. I assume this is also nice for The problem is that |
@StefanKarpinski You make a compelling case. I'm almost fully convinced that your approach is the way to go (not that it really matters). Though... this example that I'm thinking of is nagging at me, and I'd like to hear your thoughts on it. If we assign
I would like to access the diagonal elements of certain If we were to assign
(I know that this could be done with Using Thoughts? |
Yup. On the other hand, if we assign I typically only use collections of arrays when I don't know if all the arrays will be the same shape. Otherwise, I'll just use one higher dimensional array. And if the shapes of the arrays aren't all the same, I'm not sure I'd be able to index into them in a homogenous manner. There's no limit to the number of short-hand syntaxes that one can invent. The key is to find the middle-ground where it's both concise and understandable. |
@jecs Collections of collections are definitely tricky. I've been tempted to think about what @mbauman wrote
Typically, yes, but do you like it? I thought this was a pragmatic way of handling the fact that Granted, sometimes |
Either way here, I don't think we'll be able to allow fusion through to a computation on the indices. I'm using the definition that One of the things I would expect to work is I think we'll have to compute the indices first and then broadcast. This means that
But that's wrong, too! I didn't realize it when I came up with the toy example, but |
This syntax would be useful for JuMP. The use case I'm imagining would just require broadcasting over the indices and not the collection. |
Hi, just here to drop a comment that today I tried p = v..x where p was an array of objects that had field x, and I was sorely disappointed. I've been using p = getfield.(v, :x) entirely too long, and anyone who looks at my code and isn't super familiar with Julia has no idea that |
Today I was trying to use a |
For StructArray of StaticArrays, property access just works: |
I have an array
x::Array{ImmutableArray.Vector2}
.It would be cool to be able to broadcast indexing as is done with functions.
e.g.
x.[1]
,which would return the first element of each
Vector2
in my array.This is currently achievable with
getindex.(x,1)
or in the case of a range of indicesgetindex.(x,[range])
.The text was updated successfully, but these errors were encountered: