Reputation: 659
Given the values in C
, I want to count how many times I encounter each of these values in the vector B
. For example, if C = [1 2]
, I'd like to count how many "1"s are in B and how many "2"s are in B by checking the elements of array C.
However, the code I have seems to count up to 5, but what the true output should be is that the number of 1s is 2 and the number of 2s is 3.
The code I wrote is shown below. Any help would be certainly appreciated.
My code :
B = [ 1 2 1 4 5 2 2 ]
C = [ 1 2 ]
lb = length(B)
lc = length(C)
for i = 1:length(B)
for j = 1:length(C)
if B(1,i)==C(1,j)
c=c+1
A(i)=c
end
end
end
Upvotes: 1
Views: 285
Reputation: 104565
Santhan Salai gave the corrected answer if you want to stick with loops. However, for efficiency, you could achieve what you want with bsxfun
and sum
if you don't want to loop:
>> B = [ 1 2 1 4 5 2 2 ];
>> C = [ 1 2 ];
>> D = sum(bsxfun(@eq, B, C.'), 2)
D =
2
3
bsxfun
is a nice tool that allows you to broadcast data across singleton dimensions. In our case, I used the equals
functions to check for element-wise equality and I transposed C
so that it becomes a column vector. What will be produced is a matrix where we have as many rows as there are in C
and as many columns as there are in B
. Each row of this output matrix tells you which elements were equal to each corresponding element in C
. C
is broadcasted such that we get a matrix of a bunch of [1;2]
columns mashed together for as many elements as there are in B
and B
is broadcasted such that we get replicates of B
with as many rows as there are in C
. By doing element-wise equality, we would produce a logical matrix where each element for a row tells you which elements were equal to the corresponding value of C
. All you have to do now is sum over the columns to get how many elements were equal to each value in C
, hence the sum
call over the second dimension.
If you want overkill, you can also use accumarray
. Assuming that B
and C
only consist of integers, do:
>> B = [ 1 2 1 4 5 2 2 ];
>> C = [ 1 2 ];
>> D = accumarray(B.', 1);
D =
2
3
0
1
1
This however computes the frequency of all unique values in B
, and so you'd just want the first two entries in D
.
One more alternative is to use histc
:
>> B = [ 1 2 1 4 5 2 2 ];
>> C = [ 1 2 ];
>> D = histc(B, C)
D =
2 3
What you are basically computing is a histogram of B
at specified bins, which are denoted at C
.
Upvotes: 3
Reputation: 3898
Using arrayfun
could be one alternate to your loop
out = arrayfun(@(x) sum(ismember(B,x)), C)
Here is your corrected loop
count = zeros(1,numel(C));
for ii = 1:numel(C)
for jj = 1:numel(B)
if (C(ii) == B(jj))
count(ii) = count(ii) + 1;
end
end
end
Upvotes: 1