Loren on the Art of MATLAB

Turn ideas into MATLAB

Finding the Closest Value Less than a Threshold 15

Posted by Loren Shure,

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.

Contents

Set up

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.


Get the MATLAB code

Published with MATLAB® R2015a

112 views (last 30 days)  | |

Comments

To leave a comment, please click here to sign in to your MathWorks Account or create a new one.