各対角番号に対する対角和からなる配列
2 views (last 30 days)
Show older comments
写真のような正方行列Aを持っている際に、自身より右下の第k対角成分の和をとった行列Bを作成したいのですが、何か簡単に書く方法はないでしょうか。
![](https://www.mathworks.com/matlabcentral/answers/uploaded_files/1116945/image.png)
現在は縮小行列を作り、各縮小行列の第j番目の対角成分を取得する形で計算していますが、かなり遅いし効率も悪いなと感じています。
A = reshape(1:9,3,3);
B = zeros(3,3);
for i = 1:3
A_partial = A(i:end,i:end);
for j = 1:3-i+1
B(i,i+j-1) = sum(diag(A_partial,j-1));
B(i+j-1,i) = sum(diag(A_partial,-1*(j-1)));
end
end
A
B
2 Comments
Atsushi Ueno
on 3 Oct 2022
メモ:同じ主旨の問題がCodyに登録されました。逆の対角方向を選択するオプションも求められます。これを解くと他のCody参加者の回答を閲覧する事が出来ます。突飛なアイデアを持つ回答者が沢山いますよ。
Accepted Answer
NO MIYA
on 5 Sep 2022
Edited: NO MIYA
on 5 Sep 2022
もっと簡単な方法があると思いますが、とりあえずこんなのでどうでしょうか。
A⇒AA、B⇒BBと考えてください。
一応n×n(3<n)の正方行列に対応できるようにもしておきました。
padarrayを使うにはImage Processing Toolboxが必要なのですが、やっていることは配列の0埋めなので自作関数でいくらでもやりようがあると思います(結果、計算量が増えるかもしれませんが)
for文を回す回数が投稿者様のが二重ループで3(n)回以上なのに対し、下記プログラムは2(n-1)回で面倒な対角要素を省いたので最低限の改良はできたかと思います。
AA = reshape(1:9,3,3); % 基の正方行列
BB = AA; % 出力したい配列
n = size(AA,1); % 正方行列の1辺の長さ
%%% 処理
for i = 2:1:n
AA_plus = padarray(AA(i:end,i:end),[i-1,i-1],0,'post');
BB = BB + AA_plus;
end
BB
6 Comments
Atsushi Ueno
on 9 Sep 2022
@Yamada Taroさんの疑問に対しては「両者とも処理速度の面は気にせず回答した」事になります。
自分は処理速度ではなく単にシンプルな記述方法の提案でした(計算量も減らせますが)。スライスの代入よりメモリ上で連続した行列全体をコピーする方が速いと思いますが、0埋めにも計算量が必要なのでどっこいどっこいといったところでしょうか。(めんどいから検証する気が無い)
- 「自身より右下の第k対角成分」を判定しないと折り返し反対側まで加算してしまう
- これはfortranやCで実装する場合の話で、MATLABなら行列操作に任せるべき
- MATLABの行列操作もBLAS相当かそれ以上に高効率な実装のはずです(読めない)
- MATLABはまた静的型付けでないので、行列が連続したメモリ配置かどうか不明
そもそもMATLABはインタプリタなので、速度重視ならコンパイルすべきです。
A = ones(3,4);
h = size(A,1) + 1;
B = A;
for i = 1:numel(A)
B(i) = sum(A(i:h:end)); % 添字の大小が逆転する項は加算してはならないが実装していない
%(実装すると結局結構な計算量になるので処理速度は期待できない)
end
B % これでは左下の三角形が期待通りに計算されない
More Answers (1)
Hernia Baby
on 6 Sep 2022
Edited: Hernia Baby
on 6 Sep 2022
clc,clear;
A = reshape(1:9,3,3);
B = zeros(size(A));
キモとなる関数です
f = @(X,x) diag(flip(cumsum(flip(diag(X,x)))),x);
上記の関数を - (行番号 - 1) ~ 列番号 - 1 分行います
-1としているのは角っこは計算する必要がないからです。
時間も計測してみましょうかね
tic
for ii = -height(A)+1:width(A)-1
B = B + f(A,ii);
end
toc
確認してみましょう
B
See Also
Categories
Find more on Matrix Indexing in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!