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

Shortcut for sub2ind indexing #6339

Closed
leviboyles opened this issue Mar 31, 2014 · 5 comments
Closed

Shortcut for sub2ind indexing #6339

leviboyles opened this issue Mar 31, 2014 · 5 comments

Comments

@leviboyles
Copy link

I frequently find myself using the sub2ind function in my work, so I created a handy shortcut so that

A[(x, y)] = [A[x[1], y[1]], A[x[2], y[2]] ..] 

That is the indices of x and y are matched in pairs. The code that allows this is

function getindex{T, N}(A::AbstractArray{T,N}, subscript_tuple::Tuple )
    @assert N == length(subscript_tuple)
    for k = 2:length(subscript_tuple)
        @assert length(subscript_tuple[1]) == length(subscript_tuple[k])
    end

    inds = sub2ind(size(A), subscript_tuple...)
    A[inds]
end

function setindex!{T, N}(A::AbstractArray{T,N}, x, subscript_tuple::Tuple )
    @assert N == length(subscript_tuple)
    for k = 2:length(subscript_tuple)
        @assert length(subscript_tuple[1]) == length(subscript_tuple[k])
    end

    inds = sub2ind(size(A), subscript_tuple...)
    A[inds] = x
end

I think this (or some similar syntax) would be useful to many people, and perhaps could be included in base. Right now this definition raises warnings that it conflicts with SharedArray.

@JeffBezanson
Copy link
Member

A more efficient way to do this would be [A[x[i],y[i]] for i in 1:length(x)].
We might want to reserve indexing with tuples for something else in the future.

@leviboyles
Copy link
Author

Fair enough. One thing about array comprehensions is that only the most basic arguments will give an Array with the correct type. For the one above I get an Array{Any}.

@carlobaldassi
Copy link
Member

One thing about array comprehensions is that only the most basic arguments will give an Array with the correct type. For the one above I get an Array{Any}.

I assume you ran the code directly in the REPL prompt? Type inference is much harder there, with global variables; testing within a function normally gives better results (almost surely in this case).
At any rate, you can force the type of the comprehension by putting the type before the brackets, e.g. like this:

(eltype(A))[A[x[i],y[i]] for i in 1:length(x)]

@toivoh
Copy link
Contributor

toivoh commented Apr 1, 2014

It seems to me that this is a special case of broadcast_getindex. I.e. what you write as A[(x,y)] would be equivalent to

broadcast_getindex(A, x, y)

I suggested in #2591 to add syntax for this as

A.[x, y]

but this seems to be the first time in a while that someone has asked for something like this :)

@leviboyles
Copy link
Author

Ah I forgot that type inference is harder in the REPL. Sorry! I think I will switch to broadcast_getindex. Thanks everyone for the help.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants