下面的循环可以矢量化吗?循环中的每次迭代形成一个外部产品,然后对称并将结果存储为矩阵中的列.预计m很大(例如,1e4)并且s很小(例如10). % U and V are m-by-s matricesA = zeros(s^2, m); % preall
% 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.使用bsxfun(这是如何完成它的很多乐趣):
% the outer product A = bsxfun( @times, permute( U, [1 3 2] ), permute( V, [ 1 2 3 ] ) ); % symmetrization A = .5 * ( A + permute( A, [1 3 2] ) ); % to vector (per product) B = reshape( A, [m s^2] )';
基准测试结果(我的机器):
>原始方法(迭代大昏暗):
Elapsed time is 0.217695 seconds.
>“新”方法(迭代较小的暗淡):
Elapsed time is 0.037538 seconds.
>有趣的bsxfun:
Elapsed time is 0.021507 seconds.
正如你所看到的,bsxfun需要~2 / 3 – 最快循环的1/2时间……
bsxfun不是很有趣吗?