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

조회 수: 9 (최근 30일)
Yunhui He
Yunhui He 2017년 5월 9일
편집: Matt J 2017년 5월 9일
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!

답변 (3개)

Wouter
Wouter 2017년 5월 9일
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 2017년 5월 9일
편집: Chris Turnes 2017년 5월 9일
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
Chris Turnes
Chris Turnes 2017년 5월 9일
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]);

댓글을 달려면 로그인하십시오.


Matt J
Matt J 2017년 5월 9일
편집: Matt J 2017년 5월 9일
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) );

카테고리

Help CenterFile Exchange에서 Matrix Indexing에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by