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]
採用された回答
その他の回答 (2 件)
Bruno Luong
2020 年 12 月 28 日
>> 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 件のコメント
Jan
2020 年 12 月 30 日
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.
[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 件のコメント
Hugo Campos Romero
2020 年 12 月 30 日
編集済み: Hugo Campos Romero
2020 年 12 月 30 日
Bruno Luong
2020 年 12 月 30 日
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
Hugo Campos Romero
2020 年 12 月 30 日
Bruno Luong
2020 年 12 月 30 日
What MATLAB version are you using? May be blkdiag has changed.
Mine is R2020b.
Hugo Campos Romero
2020 年 12 月 30 日
Bruno Luong
2020 年 12 月 30 日
編集済み: Bruno Luong
2020 年 12 月 30 日
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.
Hugo Campos Romero
2020 年 12 月 30 日
カテゴリ
ヘルプ センター および File Exchange で Parametric Modeling についてさらに検索
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!
