Block sub diagonals matrix
5 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
I have known how to build a block main diagonals matrix. But I also need to fill the sub diagonals.
For example,
A=rand(3,3,5);
B=rand(3,3,5);
C=rand(3,3,5);
and I want to build a matrix D like,
D=[A(:,:,1),B(:,:,1),0,...,0
C(:,:,1),A(:,:,2),B(:,:,2),...,0
C(:,:,2),A(:,:,3),B(:,:,3),...,0
...
A(:,:,5)]
D is 15×15
And A(:,:,i) is main diagonal, B and C is sub diagonals.
Kindly help me with this.
0 commentaires
Réponse acceptée
DGM
le 20 Fév 2022
If my interpretation is correct, this should be one method:
bksize = [2 2]; % smaller for example
A = ones(bksize);
B = 11*A;
C = 111*A;
blocks = {zeros(size(A)) A B C}; % this makes the blocks indexable
map = toeplitz([2 4 1 1 1],[2 3 1 1 1]); % a map of the block locations
D = cell2mat(reshape(blocks(map),size(map))) % the block array
If the blocks are 3D, that can be done without changing anything.
bksize = [2 2 3]; % 3D blocks
A = ones(bksize);
B = 11*A;
C = 111*A;
blocks = {zeros(size(A)) A B C};
map = toeplitz([2 4 1 1 1],[2 3 1 1 1]);
D = cell2mat(reshape(blocks(map),size(map)))
3 commentaires
DGM
le 20 Fév 2022
Modifié(e) : DGM
le 20 Fév 2022
Sorry about the misunderstanding.
I don't know about the efficiency of the method given, but I'd imagine it's fair enough. I don't work with sparse tools, so offhand I don't know if there would be significant advantages or at what scale those advantages manifest. The only way to know would be to test various methods with different size inputs.
EDIT:
This is the above method versus a slightly modified version. On my hardware, the modified version is faster for smaller arrays, but reaches equivalence for about a 6000x6000 output size.
% prepare inputs
A = rand(3,3,100);
B = A*11;
C = A*111;
% original method
a = timeit(@() testA(A,B,C))
% avoiding mat2cell calls
b = timeit(@() testB(A,B,C))
% time ratio
a/b
function testA(A,B,C)
[k,l,m] = size(A);
A = mat2cell(A,k,l,ones(1,m));
B = mat2cell(B,k,l,ones(1,m));
C = mat2cell(C,k,l,ones(1,m));
blocks = [{zeros(k,l)},A(:)',B(:)',C(:)'];
map = diag(1:m,0)+diag(m+1:(2*m-1),1)+diag((2*m+2):3*m,-1)+1;
D = cell2mat(reshape(blocks(map),size(map)));
end
function testB(A,B,C)
[k,l,m] = size(A);
A = reshape(A,k,[]);
B = reshape(B,k,[]);
C = reshape(C,k,[]);
blocks = mat2cell([zeros(k,l) A B C],k,l*ones(1,m*3+1));
map = diag(1:m,0)+diag(m+1:(2*m-1),1)+diag((2*m+2):3*m,-1)+1;
D = cell2mat(reshape(blocks(map),size(map)));
end
Plus de réponses (0)
Voir également
Catégories
En savoir plus sur Operating on Diagonal Matrices dans Help Center et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!