1
votes

I have to shift certain rows in matlab. Like let say I have a matrix of size 50x50. And I have to shift certain rows lets say 15,18,45.. to the top and the remaining rows at the bottom. How can I accomplish this in matlab?

4

4 Answers

2
votes

Have you tried the circshift function? Something like this could help:

A = [1:8; 11:18; 21:28; 31:38; 41:48]
A =
     1     2     3     4     5     6     7     8
    11    12    13    14    15    16    17    18
    21    22    23    24    25    26    27    28
    31    32    33    34    35    36    37    38
    41    42    43    44    45    46    47    48
B = circshift(A, [3, 0])
B =
    21    22    23    24    25    26    27    28
    31    32    33    34    35    36    37    38
    41    42    43    44    45    46    47    48
     1     2     3     4     5     6     7     8
    11    12    13    14    15    16    17    18
2
votes

This is a problem that can be quite easily solved with the help of some simple indexing:

Matrix = [ 1   101   201   301
 2   102   202   302
 3   103   203   303
 4   104   204   304
 5   105   205   305
 6   106   206   306
 7   107   207   307
 8   108   208   308
 9   109   209   309
10   110   210   310];

rowsOnTop = [1 8 4];
rowsBelow = true(size(Matrix,1),1);
rowsBelow(rowsOnTop) = false;

Modified = [Matrix(rowsOnTop,:); Matrix(rowsBelow,:)]

Modified =

     1   101   201   301
     8   108   208   308
     4   104   204   304
     2   102   202   302
     3   103   203   303
     5   105   205   305
     6   106   206   306
     7   107   207   307
     9   109   209   309
    10   110   210   310
0
votes

I understood that you want to move certain rows of matrix to the top and keep the rest on its place. For that you can use this:

Example matrix:

Matrix = [ 1:10; 101:110; 201:210; 301:310 ]';

Matrix =

 1   101   201   301
 2   102   202   302
 3   103   203   303
 4   104   204   304
 5   105   205   305
 6   106   206   306
 7   107   207   307
 8   108   208   308
 9   109   209   309
10   110   210   310

Here's the code:

RowsVector = [ 3, 5, 8 ];

Edit: new better solution (presented here first because it's better).

NewMatrix = Matrix(cell2mat(arrayfun(@(x) x:size(Matrix,1):prod(size(Matrix)), [ RowsVector, setdiff(1:size(Matrix, 1), RowsVector) ]', 'UniformOutput', false)));

NewMatrix =

 3   103   203   303
 5   105   205   305
 8   108   208   308
 1   101   201   301
 2   102   202   302
 4   104   204   304
 6   106   206   306
 7   107   207   307
 9   109   209   309
10   110   210   310

Edit: the rest of the answer is related to a [limited] older solution.

% RowsVector must be sorted, otherwise the reordering will fail.

Edit: fixed a bug with unordered RowsVector input.

RowsVector = sort(RowsVector);

for RowIndex = 1:size(RowsVector, 2)
    row = RowsVector(RowIndex);
    Matrix = vertcat(Matrix(row,:), Matrix);
    Matrix(row+1,:) = [];
end

This is the result:

Matrix =

 8   108   208   308
 5   105   205   305
 3   103   203   303
 1   101   201   301
 2   102   202   302
 4   104   204   304
 6   106   206   306
 7   107   207   307
 9   109   209   309
10   110   210   310
0
votes

I'd solve this by defining a row permutation matrix to produce the desired result. If Matlab has a built-in function for this it escapes me, so I wrote one:

function P = rowpermat(vec)
P = zeros(length(vec));
for i = 1:length(vec)
    P(i,vec(i)) = 1;
end

If vec is a permutation of 1:n this function will return a matrix which permutes the rows of an nxn matrix 1->vec(1), 2->vec(2), ... Note the absence of error checking and the like so use this in production code at your own risk.

In this case, if A is the matrix to permute, you might write:

rowpermat([15, 18, 45, 1:14,16:17,19:44,46:50])*A