user1809923
user1809923

Reputation: 1255

Compare an array to several numbers at once

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

Answers (3)

Andrew Janke
Andrew Janke

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

Luis Mendo
Luis Mendo

Reputation: 112679

Yet another possibility: use accumarray:

count = accumarray(inputArray(:), 1, [7 1]); %// Change "7" as needed

Upvotes: 2

Dennis Jaheruddin
Dennis Jaheruddin

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

Related Questions