简体   繁体   English

matlab:矢量化4D矩阵和

[英]matlab : vectorize 4D matrix sum

I need to perform in MATLAB the following calculation: 我需要在MATLAB中执行以下计算:

where w and v are vectors with N elements and A is a four-dimensional matrix (N^4 elements). 其中w和v是具有N个元素的向量,A是四维矩阵(N ^ 4个元素)。 This can be achieved by the following pedantic code: 这可以通过以下迂腐代码来实现:

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

which is extemely slow. 这是非常慢的。 Is there any way to vectorize this kind of sum in MATLAB? 有没有办法在MATLAB中对这种求和进行矢量化?

Approach #1 方法#1

With few reshape 's and matrix multiplication - 几乎没有reshape矩阵乘法 -

A1 = reshape(A,N^3,N)*conj(v)
A2 = reshape(A1,N^2,N)*v
w = reshape(A2,N,N)*v

Approach #2 方法#2

With one bsxfun , reshape and matrix-multiplication - 使用一个bsxfunreshapematrix-multiplication -

A1 = reshape(A,N^3,N)*conj(v)
vm = bsxfun(@times,v,v.')
w = reshape(A1,N,N^2)*vm(:)

Benchmarking 标杆

This section compares runtimes for the two approaches listed in this post, first tested approach in Shai's post and original approach listed in the question. 本节比较了本文中列出的两种方法的运行时, Shai的帖子中首次测试的方法和问题中列出的原始方法。

Benchmarking Code 基准代码

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

Runtime Results 运行时结果

----------------------------------- 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.

Conclusions 结论

The second approach in this post seems to be giving about 80x speedup over the original approach. 这篇文章中的第二种方法似乎比原始方法提供了大约80x加速。

You can try using . 您可以尝试使用

Assuming v is an N -by-1 column vectors (otherwise, permutations should be modified a little bit). 假设vN -by-1列向量(否则,应该稍微修改排列)。

% sum over n (4th dim)
s4 = sum( bsxfun( @times, A, permute( conj(v), [4 3 2 1] ) ), 4 ); 

Now the interim result is only N -by- N -by- N . 现在中期结果只有N By- N by- N

% sum over m (3rd dim)
s3 = sum( bsxfun( @times, s4, permute( v, [3 2 1] ) ), 3 )

Continuing to the last sum 继续最后一笔

% sum over l (2nd dim)
w = s3*v; 

Coming to think about it, have you considered using dot in its multidim version? 考虑一下,您是否考虑在其多维版本中使用dot I did not test it, but it should work (maybe some minor corrections). 我没有测试它,但它应该工作(可能是一些小的修正)。

s4 = dot( A, permute( conj(v), [4 3 2 1] ), 4 );
s3 = dot( s4, permute( v, [3 2 1] ), 3 );
w = s3*v;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM