使用arrayfun在Matlab中更快地进行for循环?

tim*_*tim 3 arrays parallel-processing matlab

目前我有以下部分代码:

for i = 2:N-1
  res(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
end
Run Code Online (Sandbox Code Playgroud)

其中变量k,m,c和e是大小为N的向量,x是大小为2*N的向量.使用像arrayfun这样的东西有没有办法更快地做到这一点!?我无法弄清楚这一点:(我特别想通过以后在GPU上运行来加快速度,因此,arrayfun也会有所帮助,因为matlab不支持并行化for循环而且我不想买夹克包...非常感谢!

Chr*_*oph 6

您不必使用arrayfun.如果使用使用一些智能索引,它的工作原理:

    clear all

    N=20;
    k=rand(N,1);
    m=rand(N,1);
    c=rand(N,1);
    e=rand(N,1);
    x=rand(2*N,1);

    % for-based implementation
    %Watch out, you are not filling the first element of forres!
    forres=zeros(N-1,1); %Initialize array first to gain some speed.
    for i = 2:N-1
      forres(i) = k(i)/m(i)*x(i-1) -(c(i)+c(i+1))/m(i)*x(N+i) +e(i+1)/m(i)*x(i+1);
    end

    %vectorized implementation
    parres=k(2:N-1)./m(2:N-1).*x(1:N-2) -(c(2:N-1)+c(3:N))./m(2:N-1).*x(N+2:2*N-1) +e(3:N)./m(2:N-1).*x(3:N);

    %compare results; strip the first element from forres
    difference=forres(2:end)-parres %#ok<NOPTS>
Run Code Online (Sandbox Code Playgroud)


Edr*_*ric 5

首先,MATLAB通过PARFOR支持并行循环.但是,由于计算量与您正在读取和写入的数据量相比较小,因此加速此类计算的可能性不大.

要重构GPUArray" arrayfun "的内容,您需要使循环体中的所有数组引用引用循环迭代,并使循环遍及整个范围.您应该能够通过偏移某些数组并使用虚拟值填充来实现此目的.例如,您可以在前面添加所有数组NaN,并替换x(i-1)为新变量x_1 = [x(2:N) NaN]