繁体   English   中英

使用矢量化通过反向乘法加速 matlab 代码

[英]Speed up matlab code with backward multiplication using vectorization

我需要减少以下用 Matlab 编写的代码的运行时间:

dt = 0.001; dt05 = dt^0.5; length_t = 1.0e6;
%a: array containing length_t elements
y0 = [1.5 2.0 1.0];y = zeros(length_t,3);y(1,:) = y0;

for i = 1:length_t-1
     dy = f(y(i,:); %call to some function    
     y(i+1,1) =  y(i,1) + dt*dy(1) ; 
     y(i+1,2) =  y(1,2) + a(1:i)*(y(i:-1:1,2)-y(1,2))  + dt05*dy(2) ;
     y(i+1,3) =  y(1,3) + a(1:i)*(y(i:-1:1,3)-y(1,3))  + dt05*dy(3) ;
end

最慢的步骤是 y(i+1,2) 和 y(i+1,3) 的计算(因为它们需要所有之前的 y(:,2:3) 值)。 如何通过矢量化和/或使用 GPU 来加速此代码?

编辑: a 由

a(1) = 0.5; a (2:length_t) = cumprod( (1-((1+a(1))./(2:length_t))) )*a(1);

f 是一些 function ,例如:

function dy = f(y)
  k12 = 1.0;  k02 = 2.0;
  dy(1) =  - k12*y(1)*y(2);
  dy(2) =    k12*y(1) - k02*y(2);
  dy(3) = (k12+k02)*(y(1)+y(2)+y(3));
  dy = [dy(1) dy(2) dy(3)];
end

请注意,我没有DSP 知识。 我希望有人可以写一个更好的答案或更正我的答案。

如果您可以容忍一些近似值:

您可以看到比率a(i+1)/a(i)趋于 1。这意味着您可以精确计算前 N 个元素的 a*y(N 取决于您所需的精度),然后添加 N+1- th 元素到变量AY并根据i将变量AY减少一个魔术因子。 这样,您可以节省大量乘法,但代价是 AY 对实际产品的估计有些不准确。

你的y(i,2)会有点像( csa = cumsum(a); ):

y(i,2) = a(1:N) * y(i:-1:i-N) + AY + dt05_thingy + (1-csa(i))*y(1,2); 
y(i,3) = ...
AY = AY*MF(i,N) + a(N)*y(i-N);

魔术因子取决于 N,也许还取决于 i。 预先计算R=a(2:end)./a(1:end-1); 并使用MF(N, i>N) = R(N+(iN)/2) - 所以对要近似的元素取中间比率。

暂无
暂无

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

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