1

I have 2 matrices as follows:

a_lab = [4, 3, 5, 6, 7, 1;
    1, 2, 3, 4, 6, 1;
    4, 5, 3, 2, 1, 5];

a = [0.6, 0.4, 0.1, 0.05, 0.01, 0.2; 
    0.16, 0.4, 0.1, 0.15, 0.01, 0.22; 
    0.6, 0.24, 0.11, 0.05, 0.11, 0.2];

I sort 'a' row-wise and obtain the indices:

[a_sorted, idx] = sort(a, 2, 'descend');

0.6000    0.4000    0.2000    0.1000    0.0500    0.0100
0.4000    0.2200    0.1600    0.1500    0.1000    0.0100
0.6000    0.2400    0.2000    0.1100    0.1100    0.0500

I now want to sort a_lab using idx, so the matrices a and a_lab stay in registration. I can sort one row of a_lab using one row of idx, like this:

a_lab_sorted = a_lab(1, idx(1, :));

But, how can I sort all rows of a_lab in one go (without a for loop)? This:

a_lab_sorted = a_lab(:, idx);

...is not correct, it produces a 3x18 matrix. Thanks.


The other question suggested as a duplicate uses a for loop. I am asking for a non-loop solution. Thanks.

Chris Parry
  • 2,937
  • 7
  • 30
  • 71

3 Answers3

1

You can simply add the length of your row to each row of your idx index matrix.

So

s       = size(a_lab);
idx_lab = idx + [0:s(2):(s(1)-1)*s(2)]' % so, idx + [0;6;12]

a_lab_sorted = a_lab(idx_lab);

Using the fact that MATLAB allows you to process all of the values in a matrix using a single arithmetic operator or function.

A =    1   0   0
       0   1   0
       0   0   1

A =    A+1

A =    2   1   1
       1   2   1
       1   1   2
obchardon
  • 10,614
  • 1
  • 17
  • 33
1

You can use a combination of sub2ind and repmat like this:

[m,n] = size(idx);
a_lab_sorted2 = a_lab(sub2ind([m n],repmat(1:m,n,1).',idx))

The indexes for the columns are given by idx and repmat(1:m,n,1).' gives you the indexes of the colums as follows:

 1     1     1     1     1     1
 2     2     2     2     2     2
 3     3     3     3     3     3

These can now be converted by sub2ind which gives you a matrix of linear indexes. With that matrix, you can get your a_lab_sorted.


This answer is based on Andrew Janke's answer here.

Community
  • 1
  • 1
Matt
  • 12,848
  • 2
  • 31
  • 53
0

You need to convert idx to a linear index:

a_lab_sorted = a_lab(bsxfun(@plus, (1:size(a,1)).', (idx-1)*size(a,1)));
Luis Mendo
  • 110,752
  • 13
  • 76
  • 147