Reputation: 1255
How do you compare an array of numbers to several given numbers? More precisely, I have an array given like so
inputArray = [1 2 2 3 4 6]
and I want to compare inputArray to the numbers 1:7 to ultimately count how many times a "1" is in inputArray, a "2", a "3" and so on.
Obviously I can do something like
res = zeros(7,1);
for i = 1:7
res(i) = sum(inputArray == i);
end
or more generally when I also might be interested in the locations of occurrences
res = zeros(7,length(inputArray));
for i = 1:7
res(i,:) = inputArray == i;
end
res2 = sum(res,1);
Out of curiosity and/or speed improvements I am wondering if this is possible without a for loop in a single statement?
Upvotes: 2
Views: 61
Reputation: 23858
When you want more dimensions of vectorization than is built in to the functions you're working with, or want to collapse a simple loop into a function call, you can use bsxfun
("Binary Singleton eXpansion FUNction"). It's pretty general, reasonably fast, and produces concise code.
In this case, you could use it to construct that equality grid, and then sum them up.
a = [1 2 2 3 4 5];
i = [1:7]'; % Flip it so it's oriented perpendicular to a
res = bsxfun(@eq, a, i);
counts = sum(res,2)'; %'
% One-liner version
counts = sum(bsxfun(@eq, a, [1:7]'), 2)';
Though in the particular case you're working with, since you're doing simple arithmetic operations on primitive arrays, the for
loops might actually be fastest with JIT optimizations, as long as you're careful to isolate the work in its own function so the JIT can do "in-place" optimizations.
Upvotes: 2
Reputation: 112679
Yet another possibility: use accumarray
:
count = accumarray(inputArray(:), 1, [7 1]); %// Change "7" as needed
Upvotes: 2
Reputation: 21563
It seems like you are looking for a histogram count, see here:
x = [1 3 10 1 8]
b = [1 2 3]
histc(x,b)
Will produce
[2 0 1]
Upvotes: 3