Block sub diagonals matrix

3 visualizaciones (últimos 30 días)
剑豪 戴
剑豪 戴 el 20 de Feb. de 2022
Editada: 剑豪 戴 el 21 de Feb. de 2022
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.

Respuesta aceptada

DGM
DGM el 20 de Feb. de 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
D = 10×10
1 1 11 11 0 0 0 0 0 0 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 0 0 0 0 0 0 111 111 1 1
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)))
D =
D(:,:,1) = 1 1 11 11 0 0 0 0 0 0 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 0 0 0 0 0 0 111 111 1 1 D(:,:,2) = 1 1 11 11 0 0 0 0 0 0 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 0 0 0 0 0 0 111 111 1 1 D(:,:,3) = 1 1 11 11 0 0 0 0 0 0 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 11 11 0 0 0 0 111 111 1 1 11 11 0 0 0 0 0 0 111 111 1 1 0 0 0 0 0 0 111 111 1 1
  3 comentarios
DGM
DGM el 20 de Feb. de 2022
Editada: DGM el 20 de Feb. de 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))
a = 0.0095
% avoiding mat2cell calls
b = timeit(@() testB(A,B,C))
b = 0.0040
% time ratio
a/b
ans = 2.3716
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
剑豪 戴
剑豪 戴 el 21 de Feb. de 2022
Editada: 剑豪 戴 el 21 de Feb. de 2022
Thanks! Your advanced method worked nice for me! But in the end, I need to do x=D\b in linear equation system. Maybe sparse will be better.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Operating on Diagonal Matrices en Help Center y File Exchange.

Etiquetas

Community Treasure Hunt

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

Start Hunting!

Translated by