Permutation Matrix to change representation from column major to row major in Matlab

638 views Asked by At

I have a 2D array in Matlab that needs to be converted to 1D, and Matlab uses column major representation for the conversion. However, I'd like to use a doubly stochastic matrix to convert the representation to row major.

For example, I have the following 2D array:

M = [1,2,3;4,5,6]

If I use reshape to represent it in 1D

v1 = reshape(M,size(M,1)*size(M,2),1)

I get a column major representation:

v1 = [1,4,2,5,3,6]

However, I'd like to use a permutation matrix like this:

A = [1,0,0,0,0,0;
    0,0,1,0,0,0;
    0,0,0,0,1,0;
    0,1,0,0,0,0;
    0,0,0,1,0,0;
    0,0,0,0,0,1];

so that I get the following row major representation:

v2 = [1,2,3,4,5,6]'

by doing

v2 = A*v1

I know that I can get v2 by just doing

v2 = reshape(M',size(M,1)*size(M,2),1)

But I am particular about generating the permutation matrix in order to convert to row major representation.

If someone could help me generate this permutation matrix, it would really help. Thanks in advance!

2

There are 2 answers

0
Cris Luengo On

You can create your matrix A using linear indexing. Elements in a matrix can be indexed with one index, they are then addressed column-wise, in the same order in which they appear when reshaping the matrix to a vector.

You need to set an element in each odd column, where the element is one down from the previous column:

n = numel(M);
A = zeros(n,n);
A(1:2*n+1:end) = 1;

And also one in each even column in a similar way:

A(n+n/2+1:2*n+1:end) = 1;

This works for all matrices M with two rows. For a matrix with m rows:

[m,k] = size(M);
n = numel(M); % == m*k
index = 1:m*n+1:n*n;
offset = 0:n+k:m*n;
index = index + offset'; % requires newer MATLAB
A = zeros(n,n);
A(index(:)) = 1;

If the line that requires newer version of MATLAB gives you an error, replace with bsxfun(@plus,index,offset').

1
Luis Mendo On

You can use the following:

M = [1 2 3; 4 5 6];
ind = reshape(1:numel(M), size(M,1), []).';
A = accumarray([(1:numel(M)).' ind(:)], 1);

Note also that your code

v2 = reshape(M',size(M,1)*size(M,2),1)

will fail if M is complex. To transpose, use .' instead of '.