3
votes

I'm currently trying to find the min/max value of 5 different 2x1 arrays of doubles on Matlab. I wrote a function below that works, returning the min and max values from all 5 arrays listed. However, it looks so long and bulky. I was wondering if there was a more efficient way of doing this?

I was thinking of making an array of arrays, but I don't want to copy all that data and waste memory just to check for a min and max value.

Any ideas on this? Thanks!

%% Finds min/max Lat values
function results = FindRanges(hObject,handles)

% Min of Latitudes
minLat = TG_Lat;
if min(handles.AC_Lats(:)) < minLat
    minLat = min(handles.AC_Lats(:));
end
if min(handles.MS_Lats(:)) < minLat
    minLat = min(handles.MS_Lats(:));
end
if min(handles.DL_Lats(:)) < minLat
    minLat = min(handles.DL_Lats(:));
end
if min(handles.PI_Lats(:)) < minLat
    minLat = min(handles.PI_Lats(:));
end
if min(handles.EM_Lats(:)) < minLat
    minLat = min(handles.EM_Lats(:));
end

% Max of Latitudes
maxLat = TG_Lat;
if max(handles.AC_Lats(:)) > maxLat
    maxLat = max(handles.AC_Lats(:));
end
if max(handles.MS_Lats(:)) > maxLat
    maxLat = max(handles.MS_Lats(:));
end
if max(handles.DL_Lats(:)) > maxLat
    maxLat = max(handles.DL_Lats(:));
end
if max(handles.PI_Lats(:)) > maxLat
    maxLat = max(handles.PI_Lats(:));
end
if max(handles.EM_Lats(:)) > maxLat
    maxLat = max(handles.EM_Lats(:));
end

results = [minLat, maxLat];
2
what is your handles object like, are the only properties the ones you are using for your min/max? - sg1234

2 Answers

3
votes

Copying 5 2x1 arrays is no big deal. That might even be more efficient than calling the max and min function 5 times (function call overhead is a real thing in MATLAB still). So you could do:

data = [handles.AC_Lats(:); handles.MS_Lats(:); handles.DL_Lats(:); ...
        handles.PI_Lats(:); handles.EM_Lats(:)];
results = [min(data), max(data)];

If arrays are (potentially) larger, you could do this:

minLat = min([min(handles.AC_Lats(:)), min(handles.MS_Lats(:)), min(handles.DL_Lats(:)), ...
              min(handles.PI_Lats(:)), min(handles.EM_Lats(:))]);
maxLat = max([max(handles.AC_Lats(:)), max(handles.MS_Lats(:)), max(handles.DL_Lats(:)), ...
              max(handles.PI_Lats(:)), max(handles.EM_Lats(:))]);
results = [minLat, maxLat];

This is the same thing you do, but using the built-in min and max functions instead of writing them out.

PS: I've ignored your TG_Lat, not sure what that is used for. Currently it looks like a 6th data element, but it is not described in the question text.

2
votes

My current answer assumes what I believe to be the case regarding your handles object, i.e. that it only contains the information relevant to this task. If this is not the case then this will not work as it iterates through all the properties of the handles object.

data = [TG_Lat,structfun(@(x)x(1),handles)';TG_Lat,structfun(@(x)x(2),handles)'];
results = [ min(min(data)),max(max(data)) ];

I would like to also add that, although there is nothing wrong with code being a bit bulky, you make too many calls to min() and max(). Vectorization aside (which will likely not substantially change performance in this case), it seems like a good practice to avoid calling the same function twice for the same result (in the if and in the assignment).

Edit 1 Actually, it seems struct2array would be even simpler, and looking at Cris Luengo's answer putting the data in one dimension would work as well, so here's another answer that uses some of their answer ;) (I hope this is cool.)

data = [TG_Lat([1;1]),struct2array(handles)];
results = [min(data(:)),max(data(:))]