how can I reduce the computational time of a single for loop in a Matlab code
2 views (last 30 days)
Show older comments
I have a problem with the following for. it is too time consuming. could anyone help me with it?thank in advance for your consideration and time.
Let me give you some more details about the aim of the code. I have observations with the number of 'd' that measured in 'day-of-year'. so each observations occured in a specific 'day-of-year'.
I want to collocate each of these observations (10 million data) with 'VWC', 'SM_R' that measured in coordinates (Lat, Lon) and (LAT_R, LON_R) in days called 'DOY' and 'DOY-R' in code, respectivelly. see the associate part of code:
%%%%%Matlab Code%%%%%%
Lon_d=Lon(DOY==day_of_year(d));
Lat_d=Lat(DOY==day_of_year(d));
VWC_SMAP_d=VWC(DOY==day_of_year(d));
LAT_R_d=LAT_R(DOY_R==day_of_year(d));
LON_R_d= LON_R(DOY_R==day_of_year(d));
SM_R_9_d=SM_R(DOY_R==day_of_year(d));
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
to achieve this goal, each observation with coordinate 'lon_cy(d), lat_cy(d)' was collocated with observations limited to 'step (18/110 degree) *step (18/110 degree)' grids with the center of it (lon_cy(d), lat_cy(d)):
%%%%%%%Matlab Code%%%%%%%%%%%%%%%%%%%%
lon_smap_9_index= find(LON_R_d <=lon_cy(d)+step & LON_R_d>=lon_cy(d)-step);
lat_smap_9_index= find(LAT_R_d <=lat_cy(d)+step & LAT_R_d>=lat_cy(d)-step);
intsec_smap_9=intersect(lon_smap_9_index,lat_smap_9_index);
VWC_SMAP_g_9=VWC_R_9_d(intsec_smap_9)
lon_smap_36_index= find(Lat_d <=lat_cy (d)+step & Lat_d>=lat_cy(d)-step);
lat_smap_36_index= find(Lon_d <=lon_cy(d)+step & Lon_d>=lon_cy(d)-step);
intsec_smap_36=intersect(lon_smap_36_index,lat_smap_36_index);
SM_g_36=SM_d(intsec_smap_36);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
two additional ancillary datasets were aimed to colloated with the d-dimension observations for each day-of-year:
here I just need to find the nearest ancillary datasets to each observation. that is why I used 'knnsearch' function.
%%%%%%%%%%%%%%%%%%%Matlab%%%%%%%%%%%%%%
point_1=[lat_cy(d) lon_cy(d)];
ptCloud_1=[latitu longi];
idx_land = knnsearch(ptCloud_1,point_1);
ptCloud_2=[clay(:,1) clay(:,2)];
idx_clay = knnsearch(ptCloud_2,point_1);
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
and finally I will store each collocated observations in the following way and save it
%%%%%%%%%%%%%%%%%%%%Matlab%%%%%%%%%%%%%%%
FT=[day_of_year(d) lon_cy(d) lat_cy(d) inc_cy(d) ref_cy(d) mean(VWC_SMAP_g_9) mean(roughness_g_9) mean(SM_g_9) mean(VWC_SMAP_g_36) mean(roughness_g_36) mean(TM_d_36) mean(SM_g_36) clay(idx_clay,3) land_cover(idx_land)];
8 Comments
Walter Roberson
on 8 Apr 2023
Lon_d=Lon(DOY==day_of_year(d));
Lat_d=Lat(DOY==day_of_year(d));
VWC_SMAP_d=VWC(DOY==day_of_year(d));
roughness_d=roughness(DOY==day_of_year(d));
TM_d=TM(DOY==day_of_year(d));
SM_d=SM_36(DOY==day_of_year(d));
LAT_R_d=LAT_R(DOY_R==day_of_year(d));
LON_R_d= LON_R(DOY_R==day_of_year(d));
VWC_R_9_d=VWC_R(DOY_R==day_of_year(d));
SM_R_9_d=SM_R(DOY_R==day_of_year(d));
ROUGH_R_9_d=ROUGH_R(DOY_R==day_of_year(d));
You can pre-calculate those for each different value 1 to 365 (or 366 if appropriate), and index them by day_of_year(d), instead of calculating them every time.
Answers (1)
埃博拉酱
on 9 Apr 2023
Edited: 埃博拉酱
on 9 Apr 2023
It seems that you are calling knnsearch twice in each loop to search for a single point in the point cloud. However, knnsearch can actually search for multiple points at once. It is recommended that you try to move knnsearch out of the loop and use the vectorized syntax of knnsearch to calculate all idx_land and idx_clay at once.
Based on my experience, I feel that the bottleneck of your code's speed is this knnsearch. If it's not, please reply to me again.
0 Comments
See Also
Categories
Find more on Logical in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!