Donnell Bayot
Donnell Bayot

Reputation: 23

Creating a diagonal matrix (higher dimension)

I have an n* m matrix, say A. I'd like to create the following m* m*n matrix, say B

for j=1:n
    B(:,:,j)=diag(A(j,:));
end

How do I do this without having to loop?

Thanks

Upvotes: 2

Views: 633

Answers (1)

Colin T Bowers
Colin T Bowers

Reputation: 18580

UPDATE: I've edited the question to fix the typos in the sample code.

I'm fairly sure your example code contains a couple of typos, since currently the matrix A serves no purpose, nor does your looping subscript j. However, it seems reasonably likely that what you actually are trying to ask is: How do I build a 3d array where each diagonal (moving along the 3rd dimension) is a row from A, without doing a loop?

If this is correct, then one answer is as follows:

%# A loop-less solution
Soln2 = zeros(M, M, N);
Soln2(bsxfun(@plus, (1:M+1:M*M)', (0:M^2:(N-1)*M^2))) = A';

Essentially all I've done is pre-allocate the solution 3d array, and then used bsxfun to construct a linear index of all the diagonals, moving along the 3rd dimension. I then assign the transpose of A (because you want rows not columns) to the linear index in the solution array.

Note, I've pasted some sample code for testing purposes below. Please verify that my interpretation of your loop-based solution is what you are really after.

%# Set some parameters and create a random matrix A
N = 3;
M = 4;
A = randi(5, N, M);

%# Your loop based solution
Soln1 = nan(M, M, N);
for n = 1:N
    Soln1(:,:,n) = diag(A(n,:));
end

%# A loop-less solution
Soln2 = zeros(M, M, N);
Soln2(bsxfun(@plus, (1:M+1:M*M)', (0:M^2:(N-1)*M^2))) = A';

Upvotes: 4

Related Questions