9

I have a matrix, for example

A = [ 1 2 3; 4 5 6; 7 8 9] ;

and a vector of size 1x3 which specifies which element in each row is the one I'm looking for - i.e. If

vector = [ 1 2 1 ]

then the desired output is

[ 1 5 7 ]

since 1 is the 1'st element in the 1'st row, 5 is the 2'nd in the 2'nd row, and 7 is the 1'st element in the 3'rd row.

How do I achieve this? Couldn't find a built in function to do this, which surprised me.

gnovice
  • 125,304
  • 15
  • 256
  • 359
dan
  • 93
  • 3
  • 1
    Related: [Accessing values using subscripts without using sub2ind](http://stackoverflow.com/questions/1146719/accessing-values-using-subscripts-without-using-sub2ind) – gnovice Jan 31 '11 at 15:46

4 Answers4

8

MATLAB provides the SUB2IND function to convert rows/columns subscripts to linear indices:

>> A = [1 2 3; 4 5 6; 7 8 9];
>> idx = sub2ind(size(A),1:3,[1 2 1]);  %# rows: [1 2 3], cols: [1 2 1]
>> A(idx)
     1     5     7
Amro
  • 123,847
  • 25
  • 243
  • 454
6

First of all, the indexes in Matlab go from top to bottom.
So in your case A[1] = 1 , A[2] = 4 , A[3] = 7

That said, it would be easier to work on A' , because its a bit more trivial.

B = A';

B((vector + [0:2].* 3))
Yochai Timmer
  • 48,127
  • 24
  • 147
  • 185
  • From the documentation: *"A(:) is all the elements of A, regarded as a single column."*. As a side note in order to understand the indexing. – zellus Jan 30 '11 at 11:46
5

It's a bit ugly, but diag(A(1:3,[1 2 1])) will do the trick.

user57368
  • 5,675
  • 28
  • 39
0

Here's a variation of Yochai's answer but without the transpose (this is also basically what SUB2IND does in Amro's answer):

 output = A((1:3)+3.*(vector-1));

Or for an array A of an arbitrary size:

 nRows = size(A,1);
 output = A((1:nRows)+nRows.*(vector-1));
Community
  • 1
  • 1
gnovice
  • 125,304
  • 15
  • 256
  • 359