필터 지우기
필터 지우기

How to vectorize three for loop or fast

조회 수: 1 (최근 30일)
Eb Bed
Eb Bed 2018년 6월 11일
댓글: Jan 2018년 6월 12일
% this is to do the grid-based central finite difference for the two vectors dimension as u(lon, lat, time) and v(lon,lat,time). the for loops works fine but it is too slow. I need a helpful loop that is faster than me from Matlab community.
Ur = zeros(291,243,1459);
[NR, NC]=size(lat);
for k = 1: length(t)
for i = 2:NR-1
for j = 2:NC-1
Ur(k,i,j)=sqrt((u(i+1,j,k)-2*u(i,j,k)+u(i-1,j,k))./(lon(i)-lon(i-1)^2) ...
+(v(i,j+1,k)-2*v(i,j,k)+v(i,j-1,k))./(lat(j)-lat(j-1)^2));
end
end
end
  댓글 수: 1
Geoff Hayes
Geoff Hayes 2018년 6월 11일
Eb - please clarify/quantify what you mean by too slow. Does this take seconds, minutes or hours to complete? Have you considered deferring the square root until after Ur is populated for all i,j,k? (Just to remove one computation that isn't strictly necessary until later...)

댓글을 달려면 로그인하십시오.

채택된 답변

Jan
Jan 2018년 6월 11일
편집: Jan 2018년 6월 11일
  • Avoid repeated calculations.
  • Process the data in column order.
Ur = zeros(291,243,1459);
[NR, NC]=size(lat);
for j = 2:NC-1
latj = lat(j) - lat(j-1)^2;
for i = 2:NR-1
loni = lon(i) - lon(i-1)^2;
for k = 1: length(t)
Ur(k,i,j) = sqrt((u(i+1,j,k) - 2 * u(i,j,k) + u(i-1,j,k)) ./ loni ...
+ (v(i,j+1,k) - 2 * v(i,j,k) + v(i,j-1,k)) ./ latj);
end
end
end
If you provide all input arguments, e.g. created by some rand() command, we could check the speed. I assume the inner loop is easy to vectorize:
Ur = zeros(291,243,1459);
[NR, NC]=size(lat);
for j = 2:NC-1
latj = lat(j) - lat(j-1)^2;
for i = 2:NR-1
loni = lon(i) - lon(i-1)^2;
Ur(:,i,j) = sqrt((u(i+1,j,:) - 2 * u(i,j,:) + u(i-1,j,:)) ./ loni + ...
(v(i,j+1,:) - 2 * v(i,j,:) + v(i,j-1,:)) ./ latj);
end
end
A further vectorization is possible, but I hesitate to implement it: It looks strange, that you treat lat as 2D in [NR, NC]=size(lat), but access the first column only by using 1 index later. Does the code really do, what you want?
  댓글 수: 2
Eb Bed
Eb Bed 2018년 6월 11일
Daer Jan, you figure out it for me. My data formats are both lat 2D and 1D. for 1D is it more efficient code?? If there is I am happy to hear you. Thanks
Jan
Jan 2018년 6월 12일
@Eb Bde: As said already, if you provide the input arguments such that this piece of code runs, it can be improved further. All you need to do is to post some rand commands to create lat, u and v:
lat = rand(...)
u = rand(...)
v = rand(...)
Please replace the ... with the real dimension. Of course I could guess some values, but I'm unsure due to the suspicious indexing and I do not understand: "My data formats are both lat 2D and 1D".

댓글을 달려면 로그인하십시오.

추가 답변 (0개)

카테고리

Help CenterFile Exchange에서 Matrices and Arrays에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by