How to write a circulant matrix , where the elements are matrices? Thanks!
9 views (last 30 days)
Show older comments
Hi, I want to write a circulant matrix and the element in the matrix is a matrix again. Is there simple way to do it. For example, if I want to write block-diag matrix, it is easy, but how can extend this to the circulant case.
Thanks in advance!
0 Comments
Answers (3)
Wouter
on 9 May 2017
Suppose the inner matrices have size Nin and the outer matrix size Nout
for n=1:Nout
for m=1:Nout
[qn,rn]=quorem(n,Nin);
[qm,rm]=quorem(m,Nin);
outermatrix(n,m)=...
end
end
qn/qm will give you the index of which inner matrix to use, and rn, rm which element within this inner matrix.
0 Comments
Chris Turnes
on 9 May 2017
Edited: Chris Turnes
on 9 May 2017
Supposing the matrices you want to use in a circulant pattern are stored as a M x N x K array (where M x N is the size of each individual matrix block and you want a K x K circulant pattern), then one way to do it is as follows:
% Original matrix
A = randn(M,N,K);
% Coefficients for block circulant
Ac = permute(A, [1 3 2]);
Ac = cat(2, Ac(:, 2:K, :), Ac);
% Create the block-circulant matrix using convn
I = reshape(eye(K), [1 K 1 K]);
C = convn(I, Ac);
C = reshape(C(:, K:(2*K-1), :, :), [M*K, N*K]);
This isn't the most memory efficient way to do it, but it's probably the fastest unless you start playing games with fftn. The idea here is to first permute A so that the "block" dimension is 2nd out of 3. Then, you extend Ac so that it's M x 2K-1 x N in such a way that the center portion of the convolution will give you a block circulant matrix. Next, you create an identity matrix to convolve against -- but you only want it to have non-scalar size in the block dimension, so it is reshaped to a 1 x K x 1 x K. Then you call convn and select the central M x K x N x K block. Once that's done, you can reshape it as an MK x NK matrix and you have your block circulant.
You don't have to permute A -- you can instead keep everything the dimension it is and permute C at the end. But, you'll be permuting a larger array, so I think it's preferable to work on the coefficient array in the beginning.
1 Comment
Chris Turnes
on 9 May 2017
Alternatively, if you don't feel like jumping through these hoops, just loop and use circshift:
C = zeros(M, K, N, K);
Ac = permute(A, [1 3 2]);
for i = 1:K
C(:,:,:,i) = circshift(Ac, (i-1), 2);
end
C = reshape(C, [M*K, N*K]);
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!