6

Consider a matrix M and a set of subscripts stored in columns I and J. I need to access the elements designated by I & J without converting them to linear indices (i.e. using sub2ind). E.g.

M = [1 2 3;4 5 6;7 8 9];
I = [1 1 1];
J = [1 2 3];

VALS = [1 2 3];

Also, doing the following is not feasible since I & J are huge :

VALS = diag(M(I,J));

And for demonstration, this is not what I'm looking for,

VALS = M(sub2ind(size(M),I,J));

Essentially sub2ind seems to be taking a lot of time and right now I'm looking for methods to access these elements without converting the subscripts to indices. Any other way is feasible as long as it's faster than the method using sub2ind.

Community
  • 1
  • 1
Jacob
  • 34,255
  • 14
  • 110
  • 165

1 Answers1

7

This may be faster than using SUB2IND:

[r,c] = size(M);  % Get the size of M
vals = M(I+r.*(J-1));  % Compute a linear index with vector operations
gnovice
  • 125,304
  • 15
  • 256
  • 359
  • 1
    On recent versions of Matlab, this may actually avoid a large memory allocation, because Matlab is usually smart enough to compute intermediate results without creating large temporaries, i.e. it'll do the indexing and assignment the way a person would do it in C. – Mr Fooz Jul 18 '09 at 13:08
  • That's actually the same as what `sub2ind` does except for the bounds checks. The speed benefit comes mainly from omitting the calls to `min` and `max` that those bounds checks perform on the indices. In contrast to what Mr Fooz wrote, in some tests I've performed in R2015b with some huge `I` and `J`, it turned out to be slightly more efficient to compute the linear index first like `ind=I+r.*(J-1)` and then `M(ind)`, instead of computing `M(I+r.*(J-1))` in one go. – Elmar Zander Mar 29 '17 at 08:25