MATLAB: Slow Triple for loop

optimization

Hi,
I have created a program that has a tripple for loop but runs very slowly and was hoping for some tips to speed it up… Here is the code:
if WeightingVectorWells(1) > 0 || WeightingVectorWells(4) > 0
for LatCounter = 1:length(handles.Latitude)
for LongCounter = 1:length(handles.Longitude)
for WellDataCounter = 1:size(handles.WellData,1)
if sqrt(((handles.WellData{WellDataCounter,2} - handles.Latitude(LatCounter)) ^ 2 + (handles.WellData{WellDataCounter,3} - handles.Longitude(LongCounter)) ^ 2)) < .01067
handles.ScoreSheetBPDOil(LatCounter,LongCounter) = handles.WellData{WellDataCounter,12} * WeightingVectorWells(1) + ...
handles.ScoreSheetBPDOil(LatCounter,LongCounter);
handles.ScoreSheetCumOil(LatCounter,LongCounter) = handles.WellData{WellDataCounter,13} * WeightingVectorWells(4) + ...
handles.ScoreSheetCumOil(LatCounter,LongCounter);
end
end
end
if LatCounter == length(handles.Latitude)
LatCounter = LatCounter - 1;
end
progressbar(LatCounter / length(handles.Latitude))
end
end
I created a GUI for this program (first time using GUIDE and handles and handles was the easiest way I found to talk to different functions and share data so sorry if that's bad pratice). The handles.ScoreSheets are preallocated. The LatCounter and LongCounter are both about 300 in size and the handles.WellData is a 19000 by 26 matrix (19000 being the max, it can be as little as 1 but is usually around 500 or so). Whenever I stop this mid processing (ctrl-c) it always seems to be doing the sqrt function. Also, as a side note I'm trying to get my company to get parallel processing tool box because I have six of these loops. progressbar is just a function I picked up off the file exchange and takes very little processing and the if statement at the bottom inside the outer most loop is just so that progressbar doesn't bug out.
Thanks for any help, I'm an engineer, not a programmer so I really do appreciate anything.

Best Answer

The very first thing is that you should not modify the loop index LatCounter within the loop. ( EDIT: the following sentence is wrong! see Iain's comment) What you are doing with the -1 will create an infinite loop blocked on LatCounter == length(handles.Latitude).
Then you can probably get rid of the two outer loops by creating a meshgrid of longitudes and latitudes. Example:
lat = 1:2:7
lon = 10:2:14
[LAT, LON] = meshgrid(lat, lon)
normCoordSq = LAT.^2 + LON.^2
cumResult = zeros(size(LAT)) ;
data = [2, 7, 5, 9] ;
for dataId = 1 : length(data)
mask = sqrt(normCoordSq + cumResult + data(dataId)^2) < 16 ;
cumResult(mask) = cumResult(mask) + data(dataId)^2 ;
end
cumResult
This leads to the following output:
lat =
1 3 5 7
lon =
10 12 14
LAT =
1 3 5 7
1 3 5 7
1 3 5 7
LON =
10 10 10 10
12 12 12 12
14 14 14 14
normCoordSq =
101 109 125 149
145 153 169 193
197 205 221 245
cumResult =
78 78 78 78
78 78 78 53
53 29 29 4
As you can see, there is only one loop, and the conditional statement is replaced by logical indexing based on the outcome of a relational operation. Then you could probably get rid of the last loop using ARRAYFUN, CELLFUN, or BSXFUN, but I doubt that it would bring much improvement (in the sense that these are essentially hidden loops which bring more conciseness than efficiency in term of computation time).