2

I have two arrays threshold and values.

threshold=[10 22 97]  
values=[99 23 77 11 8 10]  

I want to output idx such that threshold(idx-1)<values(i)<=threshold(idx). That is for the above example output will be

output=[4 3 3 2 1 1]  

The naive code that can produce above output will be

output=ones(1,length(values))*(length(values)+1); 
for i=1:length(values)  
  for j=1:length(threshold)  
    if(values(i)>threshold(j))  
       output(i)=j;
    end  
  end  
end   

Is there a simple way of doing it. I want to avoid loops.

6
  • Also the inner loop with j, can be replaced with find function. That is, find(threshold>values(i),1,'first'); Commented Nov 12, 2013 at 8:03
  • 1
    Why do you want to avoid loops ? You want a simple way, yet you already have a naive way. What is the desired difference between a naive way and a simple way ? Commented Nov 12, 2013 at 8:04
  • The matrix is really huge. The for loop is very very slow. Commented Nov 12, 2013 at 8:08
  • Your values isn't sorted...I suppose that is a typo? Commented Nov 12, 2013 at 8:22
  • I want a matlab friendly code that is faster. Commented Nov 12, 2013 at 8:22

2 Answers 2

3

You can use histc command, with a slight adjustment of threshold array

>> threshold=[-inf 10 22 97 inf];
>> values=[99 23 77 11 8 10]; 
>> [~, output] = histc( values, threshold+.1 )
output =

 4     3     3     2     1     1

The modification of threshold is due to "less-than"/"less-than-equal" type of comparison for bin boundary decisions.

Sign up to request clarification or add additional context in comments.

4 Comments

@RodyOldenhuis yes... I was surprised to see your answer - I honestly thought you got ahead of me and I was about to delete my answer...
seems my answer is wrong in the context of non-sorted values...I'll delete mine and drink some coffee :)
@RodyOldenhuis please do not delete your answer. it is a good example of comparison using bsxfun.
@Shai: well, if you insist.
2

No loops often means you'll gain speed by increasing peak memory. Try this:

threshold = [10 22 97];
values    = [99 23 77 11 8 10];

%// Do ALL comparisons
A = sum(bsxfun(@gt, values.', threshold));

%// Find the indices and the ones before 
R = max(1, [A; A-1]);

%// The array you want
R(:).'

If you run out of memory, just use the loop, but then with a find replacing the inner loop.

Loops aren't all that bad, you know (if you have MATLAB > R2008). In theory, the solution above shouldn't even be faster than a loop with find, but oh well...profiling is key :)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.