[英]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.