我需要在MATLAB中执行以下计算: 其中w和v是具有N个元素的向量,A是四维矩阵(N ^ 4个元素).这可以通过以下迂腐代码来实现: N=10;A=rand(N,N,N,N);v=rand(N,1);w=zeros(N,1);for pp=1:N for ll=1:N for mm=1:N
其中w和v是具有N个元素的向量,A是四维矩阵(N ^ 4个元素).这可以通过以下迂腐代码来实现:
N=10; A=rand(N,N,N,N); v=rand(N,1); w=zeros(N,1); for pp=1:N for ll=1:N for mm=1:N for nn=1:N w(pp)=w(pp)+A(pp,ll,mm,nn)*v(ll)*v(mm)*conj(v(nn)); end end end end
这是非常慢的.有没有办法在MATLAB中对这种求和进行矢量化?
方法#1少数reshape
和matrix multiplication –
A1 = reshape(A,N^3,N)*conj(v) A2 = reshape(A1,N^2,N)*v w = reshape(A2,N,N)*v
方法#2
使用一个bsxfun
,重塑和矩阵乘法 –
A1 = reshape(A,N^3,N)*conj(v) vm = bsxfun(@times,v,v.') w = reshape(A1,N,N^2)*vm(:)
标杆
本节比较了本文中列出的两种方法的运行时,Shai’s post中首次测试的方法和问题中列出的原始方法.
基准代码
N=100; A=rand(N,N,N,N); v=rand(N,1); disp('----------------------------------- With Original Approach') tic %// .... Code from the original post ...// toc disp('----------------------------------- With Shai Approach #1') tic s4 = sum( bsxfun( @times, A, permute( conj(v), [4 3 2 1] ) ), 4 ); s3 = sum( bsxfun( @times, s4, permute( v, [3 2 1] ) ), 3 ); w2 = s3*v; toc disp('----------------------------------- With Divakar Approach #1') tic A1 = reshape(A,N^3,N)*conj(v); A2 = reshape(A1,N^2,N)*v; w3 = reshape(A2,N,N)*v; toc disp('----------------------------------- With Divakar Approach #2') tic A1 = reshape(A,N^3,N)*conj(v); vm = bsxfun(@times,v,v.'); w4 = reshape(A1,N,N^2)*vm(:); toc
运行时结果
----------------------------------- With Original Approach Elapsed time is 4.604767 seconds. ----------------------------------- With Shai Approach #1 Elapsed time is 0.334667 seconds. ----------------------------------- With Divakar Approach #1 Elapsed time is 0.071905 seconds. ----------------------------------- With Divakar Approach #2 Elapsed time is 0.058877 seconds.
结论
这篇文章中的第二种方法似乎比原始方法提供了大约80倍的加速.