以下のループはベクトル化できますか? ループ内の各反復は外積を形成し、対称化し、結果を行列の列として格納します。m
大きい (例: 1e4) とs
小さい (例: 10)と予想されます。
% U and V are m-by-s matrices
A = zeros(s^2, m); % preallocate
for k = 1:m
Ak = U(k,:)' * V(k,:);
Ak = (Ak + Ak')/2;
A(:, k) = Ak(:);
end
編集
ここでは、3 つの異なる方法の比較を示します。大きな次元m
を反復する、小さな次元を反復するs
、およびbsxfun
ベース ソリューション (受け入れられた最速の答え) です。
s = 5; m = 100000;
U = rand(m, s);
V = rand(m, s);
% Iterate over large dimension
tic
B = zeros(s^2, m);
for k = 1:m
Ak = U(k,:)' * V(k,:);
Ak = (Ak + Ak')/2;
B(:, k) = Ak(:);
end
toc
% Iterate over small dimension
tic
A = zeros(s, s, m);
for i = 1:s
A(i,i,:) = U(:, i) .* V(:, i);
for j = i+1:s
A(i,j,:) = (U(:,i).*V(:,j) + U(:, j).*V(:, i))/2;
A(j,i,:) = A(i,j,:);
end
end
A = reshape(A, [s^2, m]);
toc
% bsxfun-based solution
tic
A = bsxfun( @times, permute( U, [1 3 2] ), permute( V, [ 1 2 3 ] ) );
A = .5 * ( A + permute( A, [1 3 2] ) );
B = reshape( A, [m, s^2] )';
toc
時間の比較は次のとおりです。
Elapsed time is 0.547053 seconds.
Elapsed time is 0.042639 seconds.
Elapsed time is 0.039296 seconds.