How to write a circulant matrix , where the elements are matrices? Thanks!

12 views (last 30 days)
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!

Answers (3)

Wouter
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.

Chris Turnes
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
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]);

Sign in to comment.


Matt J
Matt J on 9 May 2017
Edited: Matt J on 9 May 2017
N=5; %size of circulant matrix
blocks={A,B,C,D,...}; %list of sub-matrices as cell array
idx = toeplitz(1:N,[1,N:-1:2]) ;
blockmatrix = cell2mat( blocks(idx) );

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!