Finding the Closest Value Less than a Threshold
I just got asked a question about a good way to find the closest value in a vector that was less than a threshold. My solution is fairly short, and demonstrates some of my favorite MATLAB techniques. I will compare also show you an "obvious" solution.
First let's set up the data for our problem.
thresh = 75; nvals = 10^6; data = 100*rand(1,nvals);
Solution via looping
We could solve this by brute force, just looping over the values. Let's try that. I'm going to set the index value to empty (). That way, if we end up with an array that doesn't meet the criterion, we can tell. Also, I am setting the current minimum value to -Inf so any finite value that we find as a valid candidate will be closer to thresh, assuming we can find one.
loopindex = ; candidate = -inf; for ind = 1:numel(data) dval = data(ind); if dval < thresh && dval > candidate candidate = dval; loopindex = ind; end end
Solution using logical indexing
Next I show you my non-loop solution.
First collect the list of possible data entries - the ones that are less than the threshold value thresh. This list is a logical variable, essentially true and false values for each entry in data, selecting the candidate values that are less than the thresh value.
possibles = data < thresh;
Let's find the actual best value, plus its index into the reduced set from possibles. The index we find will not be the index into data but rather into a smaller array which is the subset meeting the threshold criteria.
[posmax, posind] = max(data(possibles));
Convert the answer into the correct index in the original array, data.
inddatapos = find(possibles); % possible indices inddata = inddatapos(posind); % find the index we care about
If inddata is empty, then there were no possible values meeting the criterion. So we set the final values accordingly.
if isempty(inddata) posmax = -Inf; end
Let's make sure both solutions match
sameSolution = isequal([inddata posmax],[loopindex candidate])
sameSolution = 1
Which solution do you prefer?
You might guess correctly which solution is more natural to me at this point :-). I am wondering which solution you prefer, and why? Let me know here.
To leave a comment, please click here to sign in to your MathWorks Account or create a new one.