What is the efficient way to loop though a multidimensional array in matlab?

조회 수: 70 (최근 30일)
Hello,
I have a fundamental doubt regarding looping across a multidimensional array. while using a for loop to calculate for every element of the matrix, what should be the order of dimensions to loop across. Consider the below code for example:
for k=2:Nz+1
for j=2:Ny+1
for i=2:Nx+1
aE=(0.5*(k_cv(j,i+1,k)+k_cv(j,i,k)))*dy*dz/dx;
aW=(0.5*(k_cv(j,i-1,k)+k_cv(j,i,k)))*dy*dz/dx;
aN=(0.5*(k_cv(j+1,i,k)+k_cv(j,i,k)))*dx*dz/dy;
aS=(0.5*(k_cv(j-1,i,k)+k_cv(j,i,k)))*dx*dz/dy;
aT=(0.5*(k_cv(j,i,k+1)+k_cv(j,i,k)))*dy*dx/dz;
aB=(0.5*(k_cv(j,i,k-1)+k_cv(j,i,k)))*dy*dx/dz;
ap_0=(rho_cv(j,i,k)*Cp_cv(j,i,k)*dx*dy*dz)/dt;
ap=aE+aW+aN+aS+aT+aB+ap_0-(Sc*dx*dy*dz);
b=(Sc*dx*dy*dz)+(ap_0*Temp_old(j,i,k));
Temp(j,i,k)=((Temp_old(j,i+1,k)*aE)+(Temp_old(j,i-1,k)*aW)+...
(Temp_old(j+1,i,k)*aN)+(Temp_old(j-1,i,k)*aS)+...
(Temp_old(j,i,k+1)*aT)+(Temp_old(j,i,k-1)*aB)+b)/ap;
%%%%
end
end
end
As can be seen, in the above example, the 3rd dimenison is the outermost loop, followed by 1st, and finally 2nd.
The same code can be written, in which, outermost for loop would be 1st, followed by 2nd, and then 3rd dimensions respectively, or any other order.
Of all the possible ways it can be done, what would be the efficient way to do it?
Does the order of dimensions in the nested for loop affect the speedness of the code?
Thank you,
Venu Madhav

채택된 답변

Bruno Luong
Bruno Luong 2023년 1월 5일
The inner most loop should be the fist index, the outer most loop last index.
Since MATLAB arranges data with first-dimension vaires first, you'll get more or less a linear memory access and data cache is more efficient.

추가 답변 (1개)

William Rose
William Rose 2023년 1월 5일
Be sure to allocate all arrays and vectors before doing the looping.
I don't think the order of looping will have a significant effect on speed. I could be wrong. You can check this by trying the different orderings. Put a tic and a toc command before and after the outermost loops, to get the elapsed time, as in the example below. In general, I think it is easy to spend more tme trying to figure out the fastest code than is worth while. It is not worth spending many minutes figuring out a speed advantage of a second or two.
tic
a=zeros(20,20,20);
for i=1:20
for j=1:20
for k=1:20, a(i,j,k)=i+20*j+20*20*k; end
end
end
toc
Elapsed time is 0.008596 seconds.
Other notes:
Your code accesses elements k_cv(i+1,j,k), k_cv(i,j+1,k), etc., and Temp_old(i+1,j,k), Temp_old(i,j+1,k), etc. Since i attains a max value of Nx+1, and j goes up to Ny+1, etc., you need to make sure the dimension of k_cv is (Nx+2,Ny+2,Nz+2). Likewise for the dimesions of Temp_old.
Or, if you want k_cv and Temp_old to have dimensions of (Nx,Ny,Nz), then the loops should be i=2:Nx-1,... j=2:Ny-1,... k=2: Nz-1.
Good luck.

카테고리

Help CenterFile Exchange에서 Loops and Conditional Statements에 대해 자세히 알아보기

제품


릴리스

R2022b

Community Treasure Hunt

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

Start Hunting!

Translated by