ベクトル化を交えた組み合わせ計算の方法
6 views (last 30 days)
Show older comments
現在、多変数関数について、各変数を1次元の配列として全ての組み合わせを計算しようとしています。
下記にコードを記しましたが、変数が多くなるにつれて計算に膨大な時間がかかってしまうため高速化したいです。
並列処理はfor文を複数使う際には適用できなかったため、ベクトル化をして、for文を減らせないか検討中です。
下記コードでA,B,Cの各配列から3×3×3のD,Eを変数とした3次元を作成し、計算することは可能でしょうか?
syms A B C D E;
A=1:1:5;
B=1:1:5;
C=1:1:5;
D=1:1:5;
E=1:1:5;
Z=A*B*C*D*E;
OUTPUT=zeros(5,5,5,5,5);
for i=1:3
% for j=1:3
% for k=1:3
% for l=1:3
% for m=1:3
% OUTPUT(i,j,k,l,m)=subs(Z,[A B C D E], [A(1,i) B(1,j) C(1,k) D(1,l) E(1,m)]);
% end
% end
% end
% end
% end
0 Comments
Accepted Answer
Akira Agata
on 3 Jul 2023
ndgrid を使う方法はいかがでしょうか?
たとえば簡単のため A~E をすべて 1:3 とすると、Z は以下のように計算できます。
% A~E すべての組み合わせに対して A*B*...*E を計算
[A, B, C, D, E] = ndgrid(1:3);
Z = A.*B.*C.*D.*E;
% 結果を確認
[A(:), B(:), C(:), D(:), E(:), Z(:)]
6 Comments
Akira Agata
on 7 Jul 2023
Edited: Akira Agata
on 7 Jul 2023
ご説明ありがとうございます。
簡単のため、w, L, C がそれぞれ 3 通り (1~3) 、合計 3^3 = 27通り出力されるようなケースを想定すると、以下のようになるかと思います (2通りの手法で出力してみました)。
% w, L, C の全パターンを作成
[w, L, C] = ndgrid(1:3);
% 方法1: pagemtimes を使って一気に計算
n = numel(w);
F1 = repmat([1 nan; 0 1], 1, 1, n);
F2 = repmat([1 0; nan 1], 1, 1, n);
F1(1, 2, :) = 1i*w(:).*L(:);
F2(2, 1, :) = 1i*w(:).*C(:);
Fall = pagemtimes(F1, F2); % -> Fall(:,:,k) が k番目の出力F行列
% 方法2: 後で確認しやすいテーブル型変数に整理しながら作成
tData = table(w(:), L(:), C(:), ...
'VariableNames', {'w', 'L', 'C'});
tData.F1 = arrayfun(@(x) [1 x; 0 1], 1i*tData.w.*tData.L, ...
'UniformOutput', false);
tData.F2 = arrayfun(@(x) [1 0; x 1], 1i*tData.w.*tData.C, ...
'UniformOutput', false);
tData.Fall = cellfun(@(x,y) x*y, tData.F1, tData.F2, ...
'UniformOutput', false);
disp(tData) % -> tData.Fall{k} が k番目の出力F行列
More Answers (1)
sp6038sy
on 1 Jul 2023
変数の組み合わせを事前に計算し行列演算するのはどうでしょうか。
例) 多変数関数 の場合
syms A B Z;
% 多変数関数
Z = A.*B;
% 変数の組み合わせを計算
A = 1:3;
B = 1:3;
[A, B] = ndgrid(A, B)
% 多変数関数に代入
out = subs(Z)
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!