Question

Let's say I have a matrix in MATLAB like

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

and I would like to obtain a matrix of the form

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

i.e. a matrix that is a concatenation of three diagonal matrices, with each having the columns of matrix A at their diagonals. I know how to do this using a for loop over the columns of A and then concatenating all the results but I am looking for a shorter way to do this. Please share your ideas.

Was it helpful?

Solution

B(repmat(eye(3),3,1)==1) = A;
reshape(B, [], 3)

OTHER TIPS

Here's a way using linear indexing:

B(sub2ind([9 3], 1:9, mod(0:8,3)+1))=A;
reshape(B,9,3)

If you want this to be generic, realize that each column of the original becomes a diagonal. Therefore, the number of rows in the original becomes the number of columns in the output, and 3 rows x cols becomes the number of rows. The rest of the answer doesn't change at all:

c = size(A,1);
r = size(A,1) * size(A,2); #% or prod(size(A));
B(sub2ind([r c], 1:r, mod(0:(r-1),c)+1)) = A;
B = sparse( 1:numel(A), repmat( 1:size(A,2), [1 size(A,1)] ),...
            A(:), numel(A), size(A,2));

should do the trick.

You can B = full(B); if you want a full matrix

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top