Hello,
I have been looking for ways to speed up my code because sometimes I spend some hours at running once MATLAB. I've read: http://blogs.mathworks.com/loren/2008/06/25/speeding-up-matlab-applications/ But it's all about "for" loops (spectacular post, BTW). The problem is that I mainly have "while" loops so I don't get how could I vectorize them. The main problem is that I call another function I've made inside my "while" loop, and that function has another "while" which calls another function with another "while".
I would appreciate any tip. Here you have part of one of my functions, if you want an example:
PSspan = [t0 t0+increment];
[resu] = nInt(ab,PSspan,hmax,tol);
[resu] = ham(resu);
[resuPol] = convPol(resu);
while iPS<nPS && loop<loopLimit
loop=loop+1; if mod(loop,250)==0; display(loop); end
ab=resu(2:5,end);
t0=resu(1,end); PSspan=[t0 t0+increment];
[resu] = nInt(ab,PSspan,hmax,tol);
[resu] = ham(resu);
[resuPol] = convPol(resu);
%Comprovació de si s'ha arribat a PS per thetaP
switch tipusCoord
case 'Cartesianes';
p=resu(variablePS,1);
q=resu(variablePS,end);
ctrl=resu(vControl,1);
case 'Polars';
p=resuPol(variablePS,1);
q=resuPol(variablePS,end);
ctrl=resuPol(vControl,1);
end
if p*q<0 && ctrl>0
%Poincaré section
iPS=iPS+1; display(iPS); loop=0;
[ coordCart, coordPol ] = BiseccioMod( resu , hmax, tipusCoord, variablePS );
resuPS(:,iPS)=coordCart; resuPSPol(:,iPS)=coordPol;
end
end

4 commentaires

Jon
Jon le 1 Août 2015
Modifié(e) : Jon le 1 Août 2015
I didn't look at your code carefully, but in my experience, while loops are more difficult to vectorize since you're looking for a condition to be met before changing behavior. In other words, you don't know a priori how many iterations are needed. Oftentimes, as you've seen in the blog, for loops can be completely replaced by a single vectorized line of code because they don't have this limitation.
One way around this is (could be) to vectorize the code in the while loop for a large swath of iterations, then check the results to see if your while conditions are met. If you make the initial swath large enough, you only need one iteration. Then you delete the results beyond the iteration that met your criteria.
One of the biggest speed-eaters is failure to pre-allocate arrays. Even if you don't know how big an array will be, you can over-allocate it and trim afterward. It's my understanding that when you append a single value onto an array, in terms of memory use, MATLAB creates a copy with the new value added rather than simply adding another element to the array. If the array already exists because you pre-allocated it, MATLAB doesn't have to make copies, but just fill in the elements. Hope that helps.
Felix Lauwaert
Felix Lauwaert le 1 Août 2015
Well, I guess I will have to do some arrangements and oversize preallocations to fit into the while loops, but I will be using these functions to a wide range of input conditions so the "oversizing" is relative. May it be a good practice to preallocate the variables inside a while loop that would only actually loop if the oversizement isn't big enough?
What I need to do is to solve asteroid orbits by computing the Poincaré section under the same dynamycal system but with different initial conditions. I have several functions: a runge-kutta 7-8 function (ode78)(while loop), a function that calculates "input" sections of Poincaré (PS_solver)(while loop), a function that finds the exact point of poincaré (bisection)(while loop), a main script to run PS_solver for different initial conditions (PSexe)(for loop). I also use a couple of other functions but they're very simple, providing formulae, extra invariable initial conditions and transforming results between cartesian and polar coordinates.
So as you can see, it's not just a while in a script, it's more like a while-inception!
Jon
Jon le 2 Août 2015
My gut tells me that it would take you much longer to vectorize this (if even possible) than it would take just to run all the test cases you want.
Once you've preallocated and vectorized your code as much as possible, look into parfor if you really need to save time. You can likely parfor the different intitial conditions.
Felix Lauwaert
Felix Lauwaert le 2 Août 2015
You're probably right. I'll have a better look at parfor, although I've allready used it a little. Thanks

Connectez-vous pour commenter.

 Réponse acceptée

Jan
Jan le 1 Août 2015
Modifié(e) : Jan le 1 Août 2015

1 vote

Why do you assume, that the while loop needs a remarkable amount of time in your code? The profiler will reveal, which lines or subfunctions require the most time. When the loop itself takes a few percent of the processing time only, an optimization is not efficient.
Matlab's JIT acceleration is impeded, if lines contain more than one command. Therefore and to improve the readability, use one command per line only.

5 commentaires

Cedric
Cedric le 2 Août 2015
Modifié(e) : Cedric le 2 Août 2015
Fellix, the simplest way to get an overview of what the profiler can do for you is to type
profile viewer
in the command window. Then you type the name of your main script in the field labeled "Run this code" and you click on its right, on [Start Profiling]. And then you enjoy the report!
Felix Lauwaert
Felix Lauwaert le 2 Août 2015
Hello and thank you both Jan and Cedric. Profile results for a simple execution (just 5 different initial conditions instead of 1000) are: Time spent calling different formulas: 4.37s. Time spent calling dynamic system formula: 60.744s. Time spent on ode78 (base function that numerically solves the integration, using the main formula): 28.756s. Total time 166.699s. So I guess I have to try to preallocate the ode78's "while loop"? convPol has a global variable and a "for" loop. Formulari uses the same global value. I attach the results. Meanwhile I'll be trying to vectorize convPol and changing the global for input variables.
Thank you very much for your help.
Felix Lauwaert
Felix Lauwaert le 2 Août 2015
I have preallocated some variables in the ode78 script and I've noticed no difference (less than 1s) and I think the problem might be because the calls to the equation that's being called 1.9e6 times. But that's a different topic than this post so thank you very much helping me to figure out where my code is lame.
Cedric
Cedric le 2 Août 2015
Modifié(e) : Cedric le 2 Août 2015
Difficult to know without testing ourselves, but it is a good setup for learning to use the profiler and to analyze reports. If you cannot "vectorize" part of the code, there are still ways to optimize, e.g. by eliminating function calls and implementing in place operations, by reducing the number of intermediary variables, by working along dimensions that make computations faster, ..
You exported/attached the summary, but I think that you saw the full report as well, with colors etc. If you enter functions from the MATLAB base package or toolboxes (which you cannot always do), you may realize that some are very slow because of tests implemented internally like calls to ISMATRIX or conversions from string to number that perform a lot of tests. If you see that, it can be advantageous to call more specific functions which involve less testing, or to build your own version of these functions without implementing any test (if you think that they are not relevant to your case).
Jan
Jan le 2 Août 2015
An integration with 1.9e6 function calls is suspicious. Do you integrate over a very long period of time or are the integration tolerances set to tiny values? In both cases the accumulated rounding errors must be taken into account and dominate the local discretization errors. Another problem could be, that the function to be integrated is stiff, while your ODE78 solver is designed for non-stiff functions. This would affect the accuracy severely. Or you have discontinuities in the function and the stepsize control fails.
So you see, that there can be many sources for a slow processing time apart from the old rumor, that Matlab processes loops slowly.

Connectez-vous pour commenter.

Plus de réponses (0)

Catégories

En savoir plus sur Loops and Conditional Statements dans Centre d'aide et File Exchange

Produits

Community Treasure Hunt

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

Start Hunting!

Translated by