Incorrect results from intersect when entering imaginary numbers

2 views (last 30 days)
The attached file, data1.txt, contains the X-Y coordinates of the points in Set A.
The other file, data2.txt, contains the X-Y coordinates of the points in Set B.
My objective is to find the intersection of the two sets.
I used intersect() in MATLAB in three ways but got different answers.
First way, combining the X array and the Y array in the same set as table(X, Y) and then input the two tables to intersect();
Second way, combining the X array, Y array in the same set as X+1i.*Y and then input the two imaginary number arrays to intersect();
Third way, combining the X array, Y array in the same set as X+100.*Y and then input the two real number arrays to intersect().
I found the answers from the first two ways were wrong!
  1 Comment
Dave B
Dave B on 23 Oct 2021
Can you expand on what you mean by the first two ways were wrong? From what I can tell all three methods produce the same result (other than how the values are sorted)...
load('data1.txt')
load('data2.txt')
% I think these are the three ways you used intersect:
t1=table(data1(:,1),data1(:,2));
t2=table(data2(:,1),data2(:,2));
res1=intersect(t1,t2);
res2=intersect(data1(:,1)+data1(:,2)*1i,data2(:,1)+data2(:,2)*1i);
res3=intersect(data1(:,1)+data1(:,2)*100,data2(:,1)+data2(:,2)*100);
% Here's an alternative that doesn't use intersect:
res_alt=data2(ismember(data2,data1(ismember(data1,data2,'rows'),:),'rows'),:);
% Are the the same number of elements?
height(res1)==height(res2)
ans = logical
1
height(res1)==height(res3)
ans = logical
1
height(res1)==height(res_alt)
ans = logical
1
% Decompose the complex back into real components and sort rows to compare with res1:
isequal(sortrows(table2array(res1)), sortrows([real(res2) imag(res2)]))
ans = logical
1
% Decompose the *100 out of res3
res3_y=(floor(res3/50)*50)/100;
res3_x=res3-res3_y*100;
a=sortrows(table2array(res1))-sortrows([res3_x res3_y]);
% some floating point error is to be expected, right?
max(abs(sort(res1.Var1)-sort(res3_x)))
ans = 9.1038e-14
max(abs(sort(res1.Var2)-sort(res3_y)))
ans = 0
% check res1 against res_alt
isequal(sortrows(table2array(res1)), sortrows(res_alt))
ans = logical
1

Sign in to comment.

Answers (2)

Stephen23
Stephen23 on 23 Oct 2021
A = readmatrix('data1.txt')
A = 465×2
0.4000 1.5000 0.6000 1.5000 0.8000 1.5000 1.0000 1.5000 1.2000 1.5000 1.4000 1.5000 1.8000 1.5000 2.0000 1.5000 0.4000 2.0000 0.6000 2.0000
B = readmatrix('data2.txt')
B = 408×2
0.2000 1.5000 0.4000 1.5000 0.6000 1.5000 0.8000 1.5000 1.0000 1.5000 1.2000 1.5000 1.4000 1.5000 1.6000 1.5000 1.8000 1.5000 0.2000 2.0000
C = intersect(A,B,'rows')
C = 388×2
0.2000 1.5000 0.2000 2.0000 0.2000 2.5000 0.2000 3.0000 0.2000 3.5000 0.2000 4.0000 0.2000 4.5000 0.2000 5.0000 0.2000 5.5000 0.2000 6.0000

Thomas Tang
Thomas Tang on 26 Oct 2021
In my application, the actual situation is like running the following scripts in R2021a.
clear
load('A.mat','overturn_Pi_p','overturn_Pi_a');
A = table(overturn_Pi_p, overturn_Pi_a);
load('B.mat','overturn_Pi_p','overturn_Pi_a');
B = table(overturn_Pi_p, overturn_Pi_a);
%First way gives the wrong answer 232
height(intersect(A, B))
%Second way gives the wrong answer 232
A_comb1 = A.overturn_Pi_p + 1i.*A.overturn_Pi_a;
B_comb1 = B.overturn_Pi_p + 1i.*B.overturn_Pi_a;
length(intersect(A_comb1, B_comb1))
%Third way gives the correct answer 388
A_comb2 = A.overturn_Pi_p + 100.*A.overturn_Pi_a;
B_comb2 = B.overturn_Pi_p + 100.*B.overturn_Pi_a;
length(intersect(A_comb2, B_comb2))
  3 Comments
Thomas Tang
Thomas Tang on 26 Oct 2021
Thank you, Dave! You are absolutely right.
Now I can get identical answer from the three approaches after modifying the codes as below to get rid of the floating point error.
The array overturn_Pi_p was generated elsewhere by assigning 0.2:0.2:8 to it with certain filtering criterion and then saved it to *.mat. This process causes floating point error!
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
load('A.mat','overturn_Pi_p','overturn_Pi_a');
overturn_Pi_p=round(overturn_Pi_p.*10)./10;
overturn_Pi_a=round(overturn_Pi_a.*10)./10;
A = table(overturn_Pi_p, overturn_Pi_a);
load('B.mat','overturn_Pi_p','overturn_Pi_a');
overturn_Pi_p=round(overturn_Pi_p.*10)./10;
overturn_Pi_a=round(overturn_Pi_a.*10)./10;
B = table(overturn_Pi_p, overturn_Pi_a);
......

Sign in to comment.

Products


Release

R2021a

Community Treasure Hunt

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

Start Hunting!