How to write a circulant matrix , where the elements are matrices? Thanks!
29 views (last 30 days)
Wouter on 9 May 2017
Suppose the inner matrices have size Nin and the outer matrix size Nout
qn/qm will give you the index of which inner matrix to use, and rn, rm which element within this inner matrix.
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.