user3200392
user3200392

Reputation: 615

speeding up some for loops in matlab

Basically I am trying to solve a 2nd order differential equation with the forward euler method. I have some for loops inside my code, which take considerable time to solve and I would like to speed things up a bit. Does anyone have any suggestions how could I do this?

And also when looking at the time it takes, I notice that my end at line 14 takes 45 % of my total time. What is end actually doing and why is it taking so much time?

Here is my simplified code:

t = 0:0.01:100;
dt = t(2)-t(1);
B = 3.5 * t;
F0 = 2 * t;

BB=zeros(1,length(t));  % Preallocation
x = 2;                  % Initial value
u = 0;                  % Initial value

for ii = 1:length(t)
    for kk = 1:ii
        BB(ii) = BB(ii) + B(kk) * u(ii-kk+1)*dt;    % This line takes the most time
    end                                             % This end takes 45% of the other time
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * (F0(ii) - BB(ii));
end

Running the code it takes me 8.552 sec.

Upvotes: 2

Views: 119

Answers (3)

nkjt
nkjt

Reputation: 7817

You can remove the inner loop, I think:

for ii = 1:length(t)
    for kk = 1:ii
        BB(ii) = BB(ii) + B(kk) * u(ii-kk+1)*dt;    % This line takes the most time
    end                                             % This end takes 45% of the other time
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * (F0(ii) - BB(ii));
end

So BB(ii) = BB(ii) (zero at initalisation) + sum for 1 to ii of BB(kk)* u(ii-kk+1).dt

but kk = 1:ii, so for a given ii, ii-kk+1 → ii-(1:ii) + 1ii:-1:1

So I think this is equivalent to:

for ii = 1:length(t)

    BB(ii) = sum(B(1:ii).*u(ii:-1:1)*dt);
    x(ii+1) = x(ii) + dt*u(ii);
    u(ii+1) = u(ii) + dt * (F0(ii) - BB(ii));

end

It doesn't take as long as 8 seconds for me using either method, but the version with only one loop is about 2x as fast (the output of BB appears to be the same).

Upvotes: 3

lennon310
lennon310

Reputation: 12709

Is the sum loop of B(kk) * u(ii-kk+1) just conv(B(1:ii),u(1:ii),'same')

Upvotes: 1

ben
ben

Reputation: 1390

The best way to speed up loops in matlab is to try to avoid them. Try if you are able to perform a matrix operation instead of the inner loop. For example try to break the calculation you do there in small parts, then decide, if there are parts you can perform in advance without knowing the results of the next iteration of the loop.

to your secound part of the question, my guess:: The end contains the check if the loop runs for another round and this check by it self is not that long but called 50.015.001 times!

Upvotes: 0

Related Questions