Correspondance matrix for matching values in two vectors

Assume two vectors with 20 values as follows:
a=[2 2 2 2 2 1 1 1 3 3 2 2 1 1 1 1 3 3 2 2];
b=[1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1 ];
Now I try to count how the values in vector a match to those in vector b. From visual relation I can make these three observations: - value 2 in vector a corresponds 6 times to value 1 in vector b, 3 times to value 2 in vector b and there is no matching 3 value in vector b; - value 1 in vector a has 0 corresponding value 1 in vector b, corresponds 7 times to value 2 in vector b and there is no matching 3 value in vector b; - value 3 in vector a corresponds 1 time to value 1 in vector b, 3 times to value 2 in vector b and there is no matching 3 value in vector b;
I would like to display these three observations in a matrix where each row corresponds to one observation:
c=[6 3 0; 0 7 0; 1 3 0];
I can envisage that the code for this possibly first requires the sorting of the data so that numbers in vector a have ascending order, which would mean that the resulting matrix becomes:
c=[0 7 0; 6 3 0; 1 3 0];
Can anybody tell me how to code the solution?

 Accepted Answer

That gives the second form of your expected result, but assuming elements are 1,2,..., n
n = 3;
c = accumarray([a(:),b(:)],1,[n n])
If the values do not meet the above requirement, the this will do:
u = union(a,b); % or u = unique(a)?
[~,ia] = ismember(a(:),u);
[bb,ib] = ismember(b(:),u);
n = length(u);
c = accumarray([ia(bb),ib(bb)],1,[n n])

8 Comments

+1 "...but assuming elements are 1,2,..., n"
And if that is not true, then use the third output of unique.
@Stephen: Not sure independent third output of UNIQUE on a and b is what OP wants, since he obviously includes the count of 3 in B (there is 0 of them in the example). IMO he works on some common set.
I don't know what you mean by "independent third output of UNIQUE": how is its third output "independent"?
"Independent" because you have to apply for A and B independently no?
Or are you assumed unique(b) is a subset of unique(a)?
I think my solution with UNION/ISMEMBER is correct rather then UNIQUE/UNIQUE.
[a1,~,row] = unique(a);
[~,col] = ismember(b,a1);
n = numel(a1);
c = accumarray([row(:),col(:)],1,[n n]);
""Independent" because you have to apply for A and B independently no?"
Sure, just like you have to apply ismember "independently". What does this mean?
No, in my case two ISMEMBER checks on the same set U, which can be derived from UNIQUE(A) or UNION(A,B) (I have a doubt which one OP wants), so it's not independent in this sense.
If you still don't see the difference, never-mind, and believe Andrei see it.
"is this behavious you expect from 2 (independent) UNIQUE ?"
As long as the vectors both contain the same values, then it will work (and be reasonably efficient). This is an assumption, just like your assumption of your original answer that the values are 1,2,...N, but I missed that 3, so it turns out to be invalid for this data.

Sign in to comment.

More Answers (1)

a = [2 2 2 2 2 1 1 1 3 3 2 2 1 1 1 1 3 3 2 2];
b = [1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 1 1 1];
[a1,~,c] = unique(a);
n = numel(a1);
out = zeros(n);
a2 = [a1,a1(end)+1];
for ii = 1:n
out(ii,:) = histcounts(b(c == ii),a2);
end

Categories

Products

Asked:

on 16 Oct 2018

Edited:

on 16 Oct 2018

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!