How can I replace the values from a diagonal submatrix?

Let us suppose I have a square matrix (6x6 for example). I need to raplace the diagonal square submatrices (2x2) by zeros:
Original matrix:
[12 89 64 125 98 856
15 56 36 874 320 523
6 54 54 692 703 147
8 128 65 632 904 236
98 78 74 541 106 569
5 69 71 446 205 832]
Final matrix:
[0 0 64 125 98 856
0 0 36 874 320 523
6 54 0 0 703 147
8 128 0 0 904 236
98 78 74 541 0 0
5 69 71 446 0 0]

 Respuesta aceptada

>> A=rand(6)
A =
0.8147 0.2785 0.9572 0.7922 0.6787 0.7060
0.9058 0.5469 0.4854 0.9595 0.7577 0.0318
0.1270 0.9575 0.8003 0.6557 0.7431 0.2769
0.9134 0.9649 0.1419 0.0357 0.3922 0.0462
0.6324 0.1576 0.4218 0.8491 0.6555 0.0971
0.0975 0.9706 0.9157 0.9340 0.1712 0.8235
>> A(logical(kron(eye(length(A)/2),ones(2))))=0
A =
0 0 0.9572 0.7922 0.6787 0.7060
0 0 0.4854 0.9595 0.7577 0.0318
0.1270 0.9575 0 0 0.7431 0.2769
0.9134 0.9649 0 0 0.3922 0.0462
0.6324 0.1576 0.4218 0.8491 0 0
0.0975 0.9706 0.9157 0.9340 0 0
>>

Más respuestas (2)

>> A=rand(6)
A =
0.8143 0.6160 0.9172 0.0759 0.5688 0.3112
0.2435 0.4733 0.2858 0.0540 0.4694 0.5285
0.9293 0.3517 0.7572 0.5308 0.0119 0.1656
0.3500 0.8308 0.7537 0.7792 0.3371 0.6020
0.1966 0.5853 0.3804 0.9340 0.1622 0.2630
0.2511 0.5497 0.5678 0.1299 0.7943 0.6541
>> m=size(A,1);
>> A([1:m+1:end 2:2*m+2:end 1+m:2*m+2:end])=0
A =
0 0 0.9172 0.0759 0.5688 0.3112
0 0 0.2858 0.0540 0.4694 0.5285
0.9293 0.3517 0 0 0.0119 0.1656
0.3500 0.8308 0 0 0.3371 0.6020
0.1966 0.5853 0.3804 0.9340 0 0
0.2511 0.5497 0.5678 0.1299 0 0
>>

1 comentario

This is the most efficient version, because it does not create a large index matrix :
A = rand(1e4);
tic;
A([1:m+1:end 2:2*m+2:end 1+m:2*m+2:end]) = 0;
toc
tic;
A(logical(kron(eye(length(A)/2),ones(2)))) = 0;
toc
tic;
C = repmat({ones(2, 2)}, 1, length(A) / 2);
D = blkdiag(C{:});
A(D == 1) = 0;
toc
% Elapsed time is 0.001411 seconds.
% Elapsed time is 0.794268 seconds.
% Elapsed time is 0.292421 seconds.

Iniciar sesión para comentar.

Jan
Jan el 28 de Dic. de 2020
Editada: Jan el 30 de Dic. de 2020
[EDITED] Fixed problem with logical indexing
A = rand(6, 6);
C = repmat({ones(2, 2)}, 1, length(A) / 2);
D = blkdiag(C{:});
A(D == 1) = 0
Note: With the former version creating C by {true(2,2)}, blkdiag was horribly slow:
tic;
C = repmat({true(2, 2)}, 1, 1000);
D = blkdiag(C{:});
toc
% Elapsed time is 8.952844 seconds. MATLAB 2018b
For non-numeric inputs blkdiag create the output iteratively by a growing array. Cruel.

7 comentarios

Hugo Campos Romero
Hugo Campos Romero el 30 de Dic. de 2020
Editada: Hugo Campos Romero el 30 de Dic. de 2020
Thank you very much for your help.
Anyway, it appears to be an issue when doing A(D)=0. It appears this error message "Array indices must be positive integers or logical values".
Jan's code works fine (it just have one wrong parenthesis in C construction), since C and D are logical
>> A = rand(6, 6);
C = repmat({true(2, 2)}, 1, length(A) / 2);
D = blkdiag(C{:});
A(D) = 0
A =
0 0 0.7094 0.1190 0.7513 0.5472
0 0 0.7547 0.4984 0.2551 0.1386
0.9502 0.1869 0 0 0.5060 0.1493
0.0344 0.4898 0 0 0.6991 0.2575
0.4387 0.4456 0.6551 0.5853 0 0
0.3816 0.6463 0.1626 0.2238 0 0
Thank you very much too Bruno. I tried again but I do not know why that message appears only to me. I attach an image. I have just tried it in a new workspace, so its not a problem of having variables with the same name. Maybe I should check for updates or reinstall.
What MATLAB version are you using? May be blkdiag has changed.
Mine is R2020b.
I am using an older version (2018a), but I am just going to update (one positive thing about COVID-19 is that my Institution have bought new licences for everyone). I will let you know if updating solves the error.
Bruno Luong
Bruno Luong el 30 de Dic. de 2020
Editada: Bruno Luong el 30 de Dic. de 2020
I confirm, MATLAB version matters when use blkdiag with logical data.
You can change the last statement to
A(logical(D)) = 0
so it can work on older version.
Perfect, thank you both. I tried A(logical(D)) and it worked. I have also uptaded to R2020b so no further issues.

Iniciar sesión para comentar.

Preguntada:

el 28 de Dic. de 2020

Editada:

Jan
el 30 de Dic. de 2020

Community Treasure Hunt

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

Start Hunting!

Translated by