简体   繁体   中英

Speed up matlab code with backward multiplication using vectorization

I need to decrease the runtime of the following piece of code written in 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

The slowest steps are the calculations of y(i+1,2) and y(i+1,3) (because they require all the previous y(:,2:3) values). How can I speed up this code by vectorization and/or using a GPU?

EDIT: a is given by

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

and f is some function like:

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

Note that I do NOT have DSP knowledge. I hope someone can write a better answer or correct mine.

If you can tolerate some approximations:

You can see that ratio a(i+1)/a(i) tends towards 1. This means that you can calculate a*y exactly for the first N elements (N depending on your desired accuracy), then add N+1-th element to variable AY and decrease variable AY by a magic factor depending on i . That way you can save yourself a lot of multiplications at the cost of this AY being somewhat inaccurate estimate of the actual product.

Your y(i,2) would then be somewhat like ( 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);

Magic factor would depend on N and perhaps also i. Precalculate R=a(2:end)./a(1:end-1); and use MF(N, i>N) = R(N+(iN)/2) - so take the middle ratio for the elements you are approximating.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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