Reputation: 68
I am struggling to optimize a piece of code. I will have to deal with many numbers (millions) and my code is running slow. Let's suppose that we have the matrix 3x3:
A = [ 8 1 6; 3 5 7; 4 9 2 ];
I want to know how many elements are in the intervals [0, 3), [3, 6) and [6, 9). Therefor, i need a matrix 1x3 :
p = [ 2 3 4 ];
My code is :
p = zeros(1, 3);
for i = 1 : 9
p( floor(A / 3) + 1 ) += 1;
I want to do it without for loops, but the code :
p = zeros(1, 3);
p( floor(A / 3) + 1 ) += 1;
Outputs :
p = 1 1 1
Any ideas why? And how can i correct this issue?
Upvotes: 3
Views: 551
Reputation: 36710
What you are implementing is a histogram:
p=histc(A(:),[0,3,6,9]); %For MATLAB 2014b or newer use histcounts instead
It returns p=[2,3,3,1]
because it implicitly creates an interval [9,inf)
To explain the indexing problem. Multiple assignments to the same index are not supported in MATLAB. They always take the last assignment:
x=zeros(3,1)
x([1,1,2,1])=[1,2,3,4] %results in x(1)=4
And for the increment operator, the same rules apply. It behaves like:
x([1,1,1,1])=x([1,1,1,1])+1
For the general case of such an multi-assignment, you can use accumarray:
%assume you want x([1,1,2,1])=[1,2,3,4]
accumarray([1,1,1,1].',[1,2,3,4].')
%results in [7,3]
Upvotes: 2
Reputation: 73176
Histogram bin counts
As Daniel writes in his answer, you're computing counts of values in histogram bins. An alternative method to hist
is using the newer histcounts
command (recommended for newer Matlab versions).
A = [ 8 1 6; 3 5 7; 4 9 2 ];
[p, ~, ~] = histcounts(A, 0:3:9);
%// p = 2 3 4
Matrix relation operators followed by non-zero element count
You could also make use of matrix relational operators followed by nnz
command to count non-zero elements:
A = [ 8 1 6; 3 5 7; 4 9 2 ];
p = [nnz(A < 3);
nnz(A >= 3 & A < 6);
nnz(A >= 6)]; %// alternatively nnz(A >= 6 & A < 9) for the last entry
%// ...
p =
2
3
4
"Quickest?"
From some quick tic
/toc
tests, it seems that—on my system (running Matlab R2014b)—the latter nnz
method is:
histcounts
method.hist
command.I have not tried, however, to see how this scales as A
becomes larger, in case this is the case for your application.
Upvotes: 1