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

31 Ansichten (letzte 30 Tage)
Yunhui He
Yunhui He am 9 Mai 2017
Bearbeitet: Matt J am 9 Mai 2017
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!

Antworten (3)

Wouter
Wouter am 9 Mai 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 am 9 Mai 2017
Bearbeitet: Chris Turnes am 9 Mai 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 Kommentar
Chris Turnes
Chris Turnes am 9 Mai 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]);

Melden Sie sich an, um zu kommentieren.


Matt J
Matt J am 9 Mai 2017
Bearbeitet: Matt J am 9 Mai 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) );

Kategorien

Mehr zu Mathematics finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by