Is it possible to make this tiny loop faster?

6 visualizzazioni (ultimi 30 giorni)
It seems that it might be possible to make this loop faster. Does anyone have any thoughts? I have to call a loop like this millions of times in a larger workflow, and it is getting to be the slowest part of the code. I appreciate any insights!
a = 2; % constant
b = 3; % constant
n = 10; % number of elements of outputs c and s
% n could be up to 100
% preallocate and set the initial conditions
c = zeros(n,1);
s = c;
c(1) = 3; % set the initial condition for c
s(1) = 1; % set the initial condition for s
% run the loop
for i = 2:n
c(i) = a*c(i-1) -b*s(i-1);
s(i) = b*c(i-1) + a*s(i-1);
end
  2 Commenti
Image Analyst
Image Analyst il 16 Mag 2025
I ran that loop a million times with n=100 and it took only 0.33 seconds. How long does it take for you? How fast do you need it to be.
Also, what physical process is this supposed to simulate? I'm wondering because some of the values get up to 10^55 which is extremely large for any real world situation.
Christopher Smith
Christopher Smith il 17 Mag 2025
Good questions... this is part of a recursive fast multipole method that I'm working on speeding up. This loop is nested inside 3 others, so it can get called a bunch of times and if n is large it can take some time. This loop is pretty fast already, like you mentioned, but since it could get called so many times a small improvment could pay off. The a and b values I picked at first were arbitrary, but really they are going to be between -1 and 1. Also typical initial values of c and s are 1 and 0.5 respectively. One last thing I was thinking: if this loop could be turned into some kind of matrix operation then I can eliminate it altogether to get a speed up. I wasn't sure that was possible, so I thought I would put it out there to see if someone else had an idea. I appreciate the comments!

Accedi per commentare.

Risposta accettata

Matt J
Matt J il 18 Mag 2025
Modificato: Matt J il 18 Mag 2025
This saves considerable time for large n, but for small n, all bets are off.
a = .2; % constant
b = .3; % constant
n = 1e6; % number of elements of outputs c and s
x=[3;1];
timeit( @() loopMethod(a,b,x,n) )
ans = 0.1145
timeit( @() vectorizedMethod(a, b, x,n))
ans = 0.0209
function results = loopMethod(a,b,x,n)
% x=[c1;s1]
%
%results=[c1,c2,c3,....cn;
% s1,s2,s3,....sn]
A = [a, -b; b, a];
results=nan(2,n);
results(:,1)=x;
tmp=x;
for k = 2:n
tmp=A*tmp;
results(:,k)=tmp;
end
end
function results = vectorizedMethod(a, b, x,n)
% x=[c1;s1]
%
%results=[c1,c2,c3,....cn;
% s1,s2,s3,....sn]
z = a + 1i * b; % complex form of A
w = x(1) + 1i * x(2); % complex form of vector x
zAng=angle(z);
zMag=abs(z);
wAng=angle(w);
wMag=abs(w);
k = 1:n-1;
yMag=wMag*zMag.^k;
yAng=wAng+zAng.*k;
results = [x(1) yMag.*cos(yAng); x(2) yMag.*sin(yAng)]; % convert to 2xN real matrix
end

Più risposte (1)

Akira Agata
Akira Agata il 16 Mag 2025
Spostato: Voss il 16 Mag 2025
If you need to calculate this efficiently, I believe the following relationship can be utilized.
  7 Commenti
Walter Roberson
Walter Roberson il 17 Mag 2025

I think M = [a,-b;b,a]^(n-1) is taking a notable amount of time.

Torsten
Torsten il 17 Mag 2025
Modificato: Torsten il 17 Mag 2025
Maybe the analytical solution of the recurrence can save time - I didn't check it.
I assumed that the complete vectors c(1:n) and s(1:n) are required. If only c(n) and s(n) are needed, things will become much faster, of course.
c_init = 3;
s_init = 1;
a = 2; % constant
b = 3; % constant
n = 10; % number of elements of outputs c and s
F = cumprod([1;(a + 1i*b)*ones(n-1,1)]);
% N = (0:(n-1)).';
% F = (a + 1i*b).^N;
reF = real(F);
imF = imag(F);
c = c_init*reF - s_init*imF
s = s_init*reF + c_init*imF
I tested it and: oh dear, that's really slow !

Accedi per commentare.

Categorie

Scopri di più su Brain Computer Interfaces in Help Center e File Exchange

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by