finding common elements in a matrix

I believe there should be a simple answer but I could not get it myself.
Assume there is a matrix say A =
1.3693 1.6266
0.2054 1.3820
1.4125 0.4844
0.0734 0.7480
1.0499 1.0451
There is one more matrix
B =
1.3693 2.0920
1.9255 1.3820
1.4125 1.8541
0.0734 1.4454
1.0499 1.4112
Now, How do I find common elements in every row of these two matrices?? I must get a final coloumn vector of only the 'common element' of every row of these two matrices.
Any quick reply is highly appreciated

3 Comments

You cannot organize the result into a vector unless you are sure that there is going to be exactly 1 common element in each row, which is not the case in your example.
Also, will the "common element" be exactly equal in both A and B or do you need to worry about floating point errors?
Yes we need to consider the floating point numbers in each row too....

Sign in to comment.

 Accepted Answer

I have to make a few assumptions as your question and comments are not clear.
Case A - assumptions: (1) exactly one common element per row (2) in the same column in A and B
tf = abs(A-B) < tol
C = A(tf)
Case B - assumptions: (1) exactly one common element per row (2) that element may be at different columns between A and B
tf = abs(A-B) < tol || abs(fliplr(A)-B) < tol
C = A(tf)
Case C - assumptions: (1) zero or one common element per row (2) in the same column in A and B
tf = abs(A-B) < tol
[r,c] = find(tf)
C = zeros(size(A,1),1)
C(r) = A(tf)
Case D - Assumptions: (1) zero or one common element per row (2) that element may be at different columns between A and B
...

5 Comments

Hello,
I'm trying to use your code for Case B, but it keeps giving me this error
" Operands to the || and && operators must be convertible to logical scalar
values.
Error in Script_HW5 (line 71)
tf = abs(LA-LB) < 1e-4 || abs(fliplr(LA)-LB) < 1e-4 "
I'd really appreciate it if you could help me with this.
@Salar: that is a little bug in Jos' answer. Use or | instead of short-circuit or ||:
tf = abs(A-B) < tol | abs(fliplr(A)-B) < tol
^
Stephen,
Thank you! but this code still doesn't spit out the common ones in order. Can you tell by looking at the code why is that? and is there any way I could get them all in order? because I need to graph them vs Time.
Thank you in advance
And also to be honest, I think this code doesn't do the work see :
a =
90 50
20 11
0 87
11 110
>> b= [ 41 90; 11 31;87 0; 11 -2]
b =
41 90
11 31
87 1
11 -2
>> tf = abs(a-b) < 1e-1 | abs(fliplr(a)-b) < 1e-1; >> LambdaS = a(tf)
LambdaS =
20
0
11
50
87
The output that I need to get is
LambdaS : 90 11 87 11
You need to take into account that MATLAB operates column-wise:
>> a = [90,50;20,11;0,87;11,110]
>> b = [41,90;11,31;87,1;11,-2]
>> at = a.';
>> bt = b.';
>> xt = at==bt | at==bt([2,1],:)
>> at(xt)
ans =
90
11
87
11

Sign in to comment.

More Answers (2)

Patrik Ek
Patrik Ek on 8 Jan 2014
Edited: Patrik Ek on 8 Jan 2014
You may use the function ismember. The syntax is
[member,ind] = ismember(A,B);
The first output shows which elements in A that belongs to B and the second output shows at which linear index in B it appears. Then it would be easy to determine at which row it appears since the element numbering in a matrix in matlab is columnwise. The row should just be
rows = mod(ind,nrows);
rows(rows==0 && ind>0) = nrows;
This may however not result in a column vector unless there are exactly 1 common index per row.
BR Patrik

3 Comments

Matt J
Matt J on 8 Jan 2014
Edited: Matt J on 8 Jan 2014
See also ISMEMBERF on the File Exchange if you need to apply a tolerance for floating point errors.
That would work I guess, but it is also possible to do a round of on A and B eg,
A = round(10*A)/10; (one decimal)
and analouge on B. Where 10 is here 1/tol. This will work for any tolerance.
A = round(1/tol*A)*tol;
However, this is more like a truncation. It truncates the values in A to a value that is a multiple of 1/tol.
Hello,
What are we supped to put for "nrows" ? when I use your code as it is it says undefined function "nrows" and when I plug in my number of rows for it the matrix rows that I get is just not correct. thanks

Sign in to comment.

A = [ 1.3693 1.6266;
0.2054 1.3820;
1.4125 0.4844;
0.0734 0.7480;
1.0499 1.0451];
B = [1.3693 2.0920;
1.9255 1.3820;
1.4125 1.8541;
0.0734 1.4454;
1.0499 1.4112];
C=(A==B);
D=A.*C;
E=sum(D,2);
E =
1.3693
1.3820
1.4125
0.0734
1.0499
% single line code
E2 = sum(A.*(A==B),2);
E2 =
1.3693
1.3820
1.4125
0.0734
1.0499

3 Comments

Your answer is very impressive. Thanks a ton. However we found an error in our program in which some of the numbers is showing as '0' in final output... Check out this program
n =5;
x1=exprnd(1,n,1);
x1
z1 = normrnd(0,1,n,1);
z1
x11=x1+z1;
x11
k1=x11
x2=exprnd(1,n,2);
x2
z2 = normrnd(0,1,n,2);
z2
x22=x2+z2;
x22
k2=max(x22')
k2
k=k2'
k
k(:,2) = k
s=k-z2
C =(s==x2);
D = s.*C;
E = sum(D,2);
E
Let me know what exactly is going wrong in the program. Thanks a lot in advance
If there is no common element in a row, you will get 0 in that row.
This code snippet does only consider elements that has the exact location. It will not react on for example,
A = [1 2;
3 4];
B = [2 1;
4 3];
Which will yield a vector,
E = [0;
0];
Also this is also requires that each row has exactly one common value.

Sign in to comment.

Categories

Asked:

on 8 Jan 2014

Edited:

on 25 Feb 2016

Community Treasure Hunt

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

Start Hunting!