4つの配列の要素を成​分に持つ行列の固有値​を求めるスクリプトの​ベクトル化

2 views (last 30 days)
Mamoru Takahashi
Mamoru Takahashi on 27 Mar 2020
Commented: Mamoru Takahashi on 30 Mar 2020
A,B,C,Dの4つの配列があり,それぞれ10*10*10 doubleのサイズをもっています.
これらの配列の同じ位置にある値どうしで行列をつくり,
その固有値を求めようとしています.
得られた固有値は新たに10*10*10サイズの配列に格納します.
スクリプトで記すと次のようになります.
eig_l = zeros(10,10,10);
eig_s = zeros(10,10,10);
% eig_l > eig_s
for i=1:10
for j=1:10
for k=1:10
M = [A(i,j,k) B(i,j,k); C(i,j,k) D(i,j,k)];
eigM = sort(eig(E));
eig_l(i,j,k) = eigM(1);
eig_s(i,j,k) = eigM(2);
end
end
end
このスクリプトは3重のforループを使用しており非常に効率が悪いので,なんとかベクトル化できないかと考えております.
いい方法はありますでしょうか?

Accepted Answer

Kenta
Kenta on 28 Mar 2020
clear;clc
A=randi(100,[100 100 100]);
B=randi(100,[100 100 100]);
C=randi(100,[100 100 100]);
D=randi(100,[100 100 100]);
eig_l = zeros(100,100,100);
eig_s = zeros(100,100,100);
E=[reshape(A(:),[1 1 1000000]),reshape(B(:),[1 1 1000000]);reshape(C(:),[1 1 1000000]),reshape(D(:),[1 1 1000000])];
c = num2cell(E,[1 2]);
sc=squeeze(c);
tic
M=cellfun(@eig, sc, 'UniformOutput', false);
toc
eigM = sort(reshape(cell2mat(M),[2 1000000]));
こんにちは、cellfunやarrayfunを使えばforを使わずに書くことができます。ただ、計算時間自体は、今回のものは数秒でできるようなので、あまり大きな影響はないかもしれません。
試しに、1から100までのループを3回繰り返した場合のコードをfor文を使わずに書くと上のようになります。
indexを利用して書くとfor文を使わずにかけることが多いです
  1 Comment
Mamoru Takahashi
Mamoru Takahashi on 30 Mar 2020
ご教示ありがとうございます!
実際にこちらで解決したい問題は10^3ではなく256^3の固有値でしたので
なんとか高速化したかったのです.
上記,さっそく試用させていただきます.

Sign in to comment.

More Answers (0)

Categories

Find more on 線形代数 in Help Center and File Exchange

Products


Release

R2018b

Community Treasure Hunt

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

Start Hunting!