How can I improve this really slow code, which consists of several nested for loops?

Hi,
So I've written these nested for loops, but it takes a very long time to execute this code:
for T = linspace( 1, 5, 10 )
for xdot_0 = linspace( -3, 3, 10 )
for ydot_0 = linspace( 16, 20, 10 )
for thetadot_0 = linspace( -5, 0, 10 )
z = DifferenceMap( xdot_0, ydot_0, thetadot_0, T );
if norm(z) < 1e-3
disp( xdot_0, ydot_0, thetadot_0, T )
disp( z )
end
end
end
end
end
The DifferenceMap( ) function calls another function that gives solutions from the ode45 solver at final time, T.
Is there a better way to write this code so that it's faster?
Thanks,

4 Comments

it really depends on the specifics of DifferenceMap. A few possibilities:
  • change one of the loops (probably outermost) to a parfor
  • look into parallelizing DifferenceMap
  • look into parallel versions of ode45 (no familiarity here, but I'd be surprised if there isn't anything)
T is a vector and loop index. It's also used as last input argument to the function DifferrenceMap.
Did you use any indefinite conditions for while or for loops inside the function ?
Hi Sindar,
Should I do both -- use a parfor and look into paralleizing DifferenceMap -- or are there "diminishing returns", so that doing one of the two is the best I can hope for? (In any case, I'll start reading up on both suggestions.)
Thanks,
There are definitely diminishing returns. parfor is easy to implement, but if you figure out lower-level parallelization (esp. vectorization), it has a good chance to be more effective

Sign in to comment.

 Accepted Answer

If you can, arrange DifferenceMap to accept a vector of T values. In the ode45() call, instead of passing in the two-element vector [0 T] for scalar T, pass in [0 vector_of_T] . ode45() will report back results at only those times. Discard the first row (corresponding to T = 0) and the rest of the rows hold the results required for each of the values in the vector of T values.
At present, your code is evaluating the same system of ode equations for a number of different T values, but at quite different times -- you do not do T = 1.4 until you have finished all of the T = 1 cases. But in order to simulate to T = 1.4, ode45 would have to integrate starting from scratch, from 0, re-doing the integrations done for time 0 to 1. And then eventually T would become 1.9 and ode45 would have to integrate the same system from scratch again, going all the way through starting from 0 to 1.4 .
My proposal is to do all the times in the same call for a given configuration, so that within the same call after making the prediction for T = 1, it would be able to use the data it already has in order to move on to T = 1.4, and through to T = 1.9 and so on, not needing to re-do the [0 1], [0 1.4] and so on integrations.

3 Comments

Hi Walter,
This is very interesting. Then that means I can remove the for loop for T, correct?
Should I also specify a step size for ode45, or let the solver do its thing with the adaptive time-stepping?
Thanks,
Right, you would remove the T loop.
You should let the solve use adaptive time steps.
Ok, I'll try this. Thanks Walter - have a great day / evening.

Sign in to comment.

More Answers (0)

Categories

Find more on Parallel Computing Toolbox in Help Center and File Exchange

Products

Release

R2017a

Asked:

on 28 Sep 2020

Commented:

on 29 Sep 2020

Community Treasure Hunt

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

Start Hunting!