In my work, I have to deal with everyday computation efficiency problems with Matlab. Indeed, generating stiffness and mass matrices can take quite a long time. Maybe you don't want to achieve the best performing code ever since you don't have a super computer anyway, but you maybe still want to do efficient programming. Therefore, here are some good programming habits that should be useful:
- Avoid loops. It may seem strange but Matlab takes quite a long time to run those loops, especially when accessing large matrices. It is therefore, when possible, much faster to replace those loops with a matricial generation.
For example, the following code is quite slow since it needs to access 250 000 times to the matrix K.
clear all;
tic();
Mmax=500;
Nmax=500;
K=zeros(Mmax+1,Nmax+1);
for m=0:1:Mmax
for n=0:1:Nmax
K(m+1,n+1)=m*n*sin(m*pi)*sin(n*pi);
end
end
toc();
Elapsed time is 3.136801 seconds.
|
It could easily be replaced by this same code which creates the whole matrix K2 at once through a vector product.
clear all;
tic();
Mmax=500;
Nmax=500;
m=0:1:Mmax;%m is a vector here
n=0:1:Nmax;%n is a vector here
K2=(m.*sin(m*pi))'*(n.*sin(n*pi));
toc();
Elapsed time is 0.010542 seconds.
|
- Play with the dimensions. When generating a stiffness matrix with the finite element method you may have to enter a structure like this when integrating over the Gauss points:
clear all;
tic();
Mmax=500;
Nmax=500;
K=zeros(Mmax+1,1);
for m=0:1:Mmax
for n=0:1:Nmax
K(m+1)=K(m+1)+m*n*sin(m*pi)*sin(n*pi);
end
end
toc();
| Elapsed time is 0.021230 seconds. |
In this case it is more interesting to create an array first and then sum over one dimension. Therefore, you could do:
clear all;
tic();
Mmax=500;
Nmax=500;
m=0:1:Mmax;%m is a vector here
n=0:1:Nmax;%n is a vector here
K2=sum((m.*sin(m*pi))'*(n.*sin(n*pi)),2);
toc();
| Elapsed time is 0.001119 seconds. |
And of course :
- Always preallocate arrays when possible so you avoid messages like "The variable 'B' appears to change size on every loop iteration. Consider preallocating for speed."In this case, Matlab help will guide you, but the general solution would be to use the command zeros which preallocate your array with zeros; the parameters of this function are the size of every dimension of your array.
Mmax=500;
Nmax=500;
K=zeros(Mmax+1,Nmax+1);
No comments:
Post a Comment