Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

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.

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.




Published with MATLAB® R2015a

|
  • print
  • send email