3

I have an N by 2 matrix A of indices of elements I want to get from a 2D matrix B, each row of A being the row and column index of an element of B that I want to get. I would like to get all of those elements stacked up as an N by 1 vector.

B is a square matrix, so I am currently using

N = size(B,1);
indices = arrayfun(@(i) A(i,1) + N*(A(i,2)-1), 1:size(A,1));
result = B(indices);

but, while it works, this is probing to be a huge bottleneck and I need to speed up the code in order for it to be useful.

What is the fastest way I can achieve the same result?

em70
  • 6,088
  • 6
  • 48
  • 80
  • 1
    BTW, it is [best not to use `i` as a variable name in Matlab](http://stackoverflow.com/questions/14790740/using-i-and-j-as-variables-in-matlab) – Shai Apr 25 '13 at 16:10
  • I had come across that, but it's a habit that's hard to kill after many years of C++... besides, everything I am currently working on is exclusively using numbers in R :) – em70 Apr 25 '13 at 16:55
  • 1
    @Shai: I would be less of a loosing battle if you tell people to stop using `i` for complex numbers and use `1i` instead :) – Amro Apr 25 '13 at 17:00

2 Answers2

6

How about

indices = [1 N] * (A'-1) + 1;
Shai
  • 111,146
  • 38
  • 238
  • 371
0

I can never remember if B(A(:,1), A(:,2)) works the way you want it to, but I'd try that to avoid the intermediate variable. If that does not work, try subs2ind.

Also, you can look at how you generated A in the first place. if A came about from the output of find, for example, it is faster to use logical indexing. i.e if

B( B == 2 )

Is faster than finding the row,col indexes that satisfy that condition, then indexing into B.

Shai
  • 111,146
  • 38
  • 238
  • 371
JonB
  • 350
  • 1
  • 7
  • 1
    I had tried sub2ind previously, and it took some 10times longer than my arrayfun solution :/ Logical indexing is also not an option in this case – em70 Apr 25 '13 at 16:01