0

I have a situation analogous to the following

z = magic(3)  % Data matrix

y = [1 2 2]' % Column indices

So,

z =      
       8 1 6               
       3 5 7      
       4 9 2

y represents the column index I want for each row. It's saying I should take row 1 column 1, row 2 column 2, and row 3 column 2. The correct output is therefore 8 5 9.

I worked out I can get the correct output with the following

x = 1:3;
for i = 1:3
    result(i) = z(x(i),y(i));
end

However, is it possible to do this without looping?

rayryeng
  • 102,964
  • 22
  • 184
  • 193
  • 1
    Relevant read: [Linear indexing, logical indexing, and all that](http://stackoverflow.com/questions/32379805/linear-indexing-logical-indexing-and-all-that) – Adriaan Sep 05 '16 at 15:15

2 Answers2

1

there are many ways to do this, one interesting way is to directly work out the indexes you want:

 v = 0:size(y,2)-1; %generates a number from 0 to the size of your y vector -1
 ind = y+v*size(z,2); %generates the indices you are looking for in each row
 zinv = z';
 zinv(ind) 

 >> ans =

 8     5     9
GameOfThrows
  • 4,510
  • 2
  • 27
  • 44
  • Using `sub2ind` may be easier to read.... but your code is essentially doing what `sub2ind` is doing. – rayryeng Sep 06 '16 at 06:14
1

Two other possible ways I can suggest is to use sub2ind to find the linear indices that you can use to sample the matrix directly:

z = magic(3);
y = [1 2 2];
ind = sub2ind(size(z), 1:size(z,1), y);
result = z(ind);

We get:

>> result

result =

     8     5     9

Another way is to use sparse to create a sparse matrix which you can turn into a logical matrix and then sample from the matrix with this logical matrix.

 s = sparse(1:size(z,1), y, 1, size(z,1), size(z,2)) == 1; % Turn into logical
 result = z(s);

We also get:

>> result

result =

     8
     5
     9

Be advised that this only works provided that each row index linearly increases from 1 up to the end of the rows. This conveniently allows you to read the elements in the right order taking advantage of the column-major readout that MATLAB is based on. Also note that the output is also a column vector as opposed to a row vector.

The link posted by Adriaan is a great read for the next steps in accessing elements in a vectorized way: Linear indexing, logical indexing, and all that.

Community
  • 1
  • 1
rayryeng
  • 102,964
  • 22
  • 184
  • 193