Is it possible to make this tiny loop faster?

조회 수: 3 (최근 30일)
Christopher Smith
Christopher Smith 2025년 5월 15일
편집: Matt J 2025년 5월 18일
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
Image Analyst
Image Analyst 2025년 5월 16일
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 2025년 5월 17일
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!

댓글을 달려면 로그인하십시오.

채택된 답변

Matt J
Matt J 2025년 5월 18일
편집: Matt J 2025년 5월 18일
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

추가 답변 (1개)

Akira Agata
Akira Agata 2025년 5월 16일
이동: Voss 2025년 5월 16일
If you need to calculate this efficiently, I believe the following relationship can be utilized.
  댓글 수: 7
Walter Roberson
Walter Roberson 2025년 5월 17일

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

Torsten
Torsten 2025년 5월 17일
편집: Torsten 2025년 5월 17일
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 !

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Brain Computer Interfaces에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by