4

I have matrix

A=[2 3 4 5 6 7;
   7 6 5 4 3 2]

I want to count how many number of elements have a value greater than 3 and less than 6.

5 Answers 5

8
flatA = A(:);
count = sum(flatA > 3 & flatA < 6);
Sign up to request clarification or add additional context in comments.

Comments

7

I can think of a few ways:

count = numel(A( A(:)>3 & A(:)<6 ))      %# (1)

count = length(A( A(:)>3 & A(:)<6 ))     %# (2)

count = nnz( A(:)>3 & A(:)<6 )           %# (3)

count = sum( A(:)>3 & A(:)<6 )           %# (4)

Ac = A(:);
count = numel(A( Ac>3 & Ac<6 ))          %# (5,6,7,8)
%# prevents double expansion
%# similar for length(), nnz(), sum(),
%# in the same order as (1)-(4)

count = numel(A( abs(A-(6+3)/2)<3/2 ))   %# (9,10,11,12)
%# prevents double comparison and & 
%# similar for length(), nnz(), sum()
%# in the same order as (1)-(4)

So, let's test what the fastest way is. Test code:

A = randi(10, 50);
tic
for ii = 1:1e5

    %# method is inserted here

end
toc

results (best of 5 runs, all in seconds):

%# ( 1): 2.981446
%# ( 2): 3.006602
%# ( 3): 3.077083
%# ( 4): 2.619057
%# ( 5): 3.011029
%# ( 6): 2.868021
%# ( 7): 3.149641
%# ( 8): 2.457988
%# ( 9): 1.675575
%# (10): 1.675384
%# (11): 2.442607
%# (12): 1.222510

So it seems that count = sum(( abs(A(:)-(6+3)/2)<3/2 )); is the best way to go here.

On a personal note: I did not expect comparison to be slower than arithmetic in Matlab -- does anyone know an explanation for this?

Plus: why is nnz so slow compared to sum? I guess that makes sense now that I know comparison is slower than arithmetic...

2 Comments

thanks mr. ROdy. hehe if size(find(A>3&A<6),1) is one of the best way or not??
Mr, dont you give me suggestion for this case stackoverflow.com/questions/12009394/…
3
length(A(A>3 & A<6))

Comments

2

Accumarray is made to do these kind of things:

count = accumarray(A(A>3 & A<6),1)

returns

>> count'
ans = 
       0  0  0  2  2

which you can sum:

count = sum(count);

First zeros correspond to number of occurences of 1,2,3 which we ignored.

Or even simpler:

count = sum(A(:)>3 & A(:)<6);

2 Comments

accumarray feels like overkill...the problem is too simple for something so sophisticated. The second solution alone would have given you a +1 :)
I interpreted the question wrong on the first try, corrected afterwards and let the accumarray in as an example
0

You could use matlab for-loop and cycle through the values on your own. Pros is that any function can be specified (>2 & <5 ; >3 & <6; etc.), cons is that it's kind of heavy approach. Here's approximate code:

count = 0;
for i=1:length(A)
  element = A(i);
  if (element > 2 && element < 5) 
    count = count + 1;
  end
end

5 Comments

@RodyOldenhuis This answer is correct (although not the shortest one) and should therefor not be downvoted (imo): meta.stackexchange.com/a/130054/185265
@GuntherStruyf in the link you provide, in section "Downvote questions": item 2 "Makes no sense" and item 7 "Bad coding practices" certainly do seem to apply here.
@GuntherStruyf Plus: his limits are incorrect: the OP asked for >3 and <6, while the anser contains >2 and <5.
what is bad coding practice here? there is just one assignment which is unnessecary, and it does make sense in that Pros is that any function can be specified Only your second argument about the limits is valid imo
@GuntherStruyf This solution clearly stems from C-style, element-wise thinking, rather than matrix style (Matlab's primary intention). It teaches the OP to use loops for every simple case, instead of simpler, vectorized solutions. As can be deduced from the OPs other posts, he already has a habit of using loops where none are required, which makes for bad coding in Matlab (and no, the JIT does not justify this sort of loop)

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.