Incorrect results from intersect when entering imaginary numbers

2 次查看(过去 30 天)
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 个评论
Dave B
Dave B 2021-10-23
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

请先登录,再进行评论。

回答(2 个)

Stephen23
Stephen23 2021-10-23
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 2021-10-26
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 个评论
Thomas Tang
Thomas Tang 2021-10-26
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);
......

请先登录,再进行评论。

类别

Help CenterFile Exchange 中查找有关 Logical 的更多信息

产品


版本

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by