7

I have a 2D array, call it A. I have two other 2D arrays, call them ix and iy. I would like to create an output array whose elements are the elements of A at the index pairs provided by ix and iy. I can do this with a loop as follows:

for i=1:nx
    for j=1:ny
        output(i,j) = A(ix(i,j),iy(i,j));
    end
end

How can I do this without the loop? If I do output = A(ix,iy), I get the value of A over the whole range of (ix)X(iy).

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
Jason
  • 103
  • 1
  • 4
  • Be careful - you are using the ix array to provide the y coordinate and the iy array to provide the x. In MATLAB the first index is the y coordinate. The same goes for yout output matrix - you are using the wrong limits for the for loops. – Lubo Antonov Feb 20 '12 at 20:24
  • Good point, but it depends a bit on how he uses the data. If he doesn't care that displaying his matrix will show x up-down and y left-right, no fundamental problem with differing from that Matlab convention. But it sure is important to know, I agree. – Jonas Heidelberg Feb 21 '12 at 16:44

2 Answers2

11

A faster way is to use linear indexing directly without calling SUB2IND:

output = A( size(A,1)*(iy-1) + ix )

... think of the matrix A as a 1D array (column-wise order)

merv
  • 1,449
  • 3
  • 13
  • 25
3

This is the one-line method which is not very efficient for large matrices

reshape(diag(A(ix(:),iy(:))),[ny nx])

A clearer and more efficient method would be to use sub2ind. I've incorporated yuk's comment for situations (like yours) when ix and iy have the same number of elements:

newA = A(sub2ind(size(A),ix,iy));

Also, don't confuse x and y for i and j in notation - j and x generally represent columns and i and y represent rows.

Jacob
  • 34,255
  • 14
  • 110
  • 165