ベクトル化を交えた組み合わせ計算の方法

조회 수: 18 (최근 30일)
Shota Ino
Shota Ino 2023년 7월 1일
편집: Akira Agata 2023년 7월 7일
現在、多変数関数について、各変数を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

채택된 답변

Akira Agata
Akira Agata 2023년 7월 3일
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(:)]
ans = 243×6
1 1 1 1 1 1 2 1 1 1 1 2 3 1 1 1 1 3 1 2 1 1 1 2 2 2 1 1 1 4 3 2 1 1 1 6 1 3 1 1 1 3 2 3 1 1 1 6 3 3 1 1 1 9 1 1 2 1 1 2
  댓글 수: 6
Shota Ino
Shota Ino 2023년 7월 7일
F行列の出力結果は2次元です。
全ての組み合わせとは、F行列内の変数(上記であれば w, L, C)について取りうる値の組み合わせを全て求めたいと思っています。例えば、w, L, Cがそれぞれ5通りの値を取りうるなら、2次元のF行列の結果が5×5×5=125通り出力されるようなイメージです。
Akira Agata
Akira Agata 2023년 7월 7일
편집: Akira Agata 2023년 7월 7일
ご説明ありがとうございます。
簡単のため、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行列
w L C F1 F2 Fall _ _ _ ____________ ____________ ____________ 1 1 1 {2×2 double} {2×2 double} {2×2 double} 2 1 1 {2×2 double} {2×2 double} {2×2 double} 3 1 1 {2×2 double} {2×2 double} {2×2 double} 1 2 1 {2×2 double} {2×2 double} {2×2 double} 2 2 1 {2×2 double} {2×2 double} {2×2 double} 3 2 1 {2×2 double} {2×2 double} {2×2 double} 1 3 1 {2×2 double} {2×2 double} {2×2 double} 2 3 1 {2×2 double} {2×2 double} {2×2 double} 3 3 1 {2×2 double} {2×2 double} {2×2 double} 1 1 2 {2×2 double} {2×2 double} {2×2 double} 2 1 2 {2×2 double} {2×2 double} {2×2 double} 3 1 2 {2×2 double} {2×2 double} {2×2 double} 1 2 2 {2×2 double} {2×2 double} {2×2 double} 2 2 2 {2×2 double} {2×2 double} {2×2 double} 3 2 2 {2×2 double} {2×2 double} {2×2 double} 1 3 2 {2×2 double} {2×2 double} {2×2 double} 2 3 2 {2×2 double} {2×2 double} {2×2 double} 3 3 2 {2×2 double} {2×2 double} {2×2 double} 1 1 3 {2×2 double} {2×2 double} {2×2 double} 2 1 3 {2×2 double} {2×2 double} {2×2 double} 3 1 3 {2×2 double} {2×2 double} {2×2 double} 1 2 3 {2×2 double} {2×2 double} {2×2 double} 2 2 3 {2×2 double} {2×2 double} {2×2 double} 3 2 3 {2×2 double} {2×2 double} {2×2 double} 1 3 3 {2×2 double} {2×2 double} {2×2 double} 2 3 3 {2×2 double} {2×2 double} {2×2 double} 3 3 3 {2×2 double} {2×2 double} {2×2 double}

댓글을 달려면 로그인하십시오.

추가 답변 (1개)

sp6038sy
sp6038sy 2023년 7월 1일
変数の組み合わせを事前に計算し行列演算するのはどうでしょうか。
例) 多変数関数 の場合
syms A B Z;
% 多変数関数
Z = A.*B;
% 変数の組み合わせを計算
A = 1:3;
B = 1:3;
[A, B] = ndgrid(A, B)
A = 3×3
1 1 1 2 2 2 3 3 3
B = 3×3
1 2 3 1 2 3 1 2 3
% 多変数関数に代入
out = subs(Z)
out = 
  댓글 수: 1
Shota Ino
Shota Ino 2023년 7월 3일
回答ありがとうございます。
ZをA, Bの組み合わせからなる2次元配列にすることができました。ありがとうございました。しかし、C,D,Eの変数についてfor文で組み合わせ計算を実施する際にサイズ違いによるエラーが出てしまいました。
現在解決手段を模索中です

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Creating and Concatenating Matrices에 대해 자세히 알아보기

제품


릴리스

R2023a

Community Treasure Hunt

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

Start Hunting!