issue with 'intersect' function
4 views (last 30 days)
Hello, I have defined a vector t=[0,1] with dt=0.0001. Now, I consider another time interval DT=100*dt=0.01. I then use command [val, ind]=intersect(t,t1,'stable'), to find the indices of the common elements between t and t1. At the same time, I define another vector t2=0:DT:1 and t3=t(ind). Now I expect that t2 and t3 should be identical. However, t3 is missing some elements. Here is my code:
dt=0.0001; t=0:dt:1; % original vector
R=100; DT=R*dt; %new step size
t1=0:DT:t(end); %vector based on new step
[sv, ind]=intersect(t,t1); % find indices of common elements
t2=t(ind); % new vector created using indices
p1=plot(t,t,'k.') %plot original vector
p2=plot(t1,t1,'o') % vector defined using DT
p3=plot(t2,t2,'sq') % vector created using indices from intersect. Notice p2 ~= p3.
John D'Errico on 23 Jan 2022
Edited: John D'Errico on 23 Jan 2022
I'm sorry, but your problem lies in understanding floating point arithmetic. Two sets of floating point numbers, created by even a different order of operations, will often not be identical.
.1 + .2 - .3 == -.3 + .1 + .2
You have effectively done the same thing, created a list of numbers, that you expect should be identical to the another. So, for example...
x1 = linspace(0,1,11);
x2 = 0:.1:1;
x1 == x2
So two vectors, containing what should be the numbers 0 to 1, in increments of 0.1, are not identical. 0.3 was not the same in both in my vectors. Intersect must now fail, as it did for you.
The answer is to use a tolerance when I do any such operation. For example, while there is no intersecttol, we could use ismembertol like this:
tol = eps;
which found all 11 numbers in both vectors.
More Answers (1)
Rik on 23 Jan 2022
Decimals are difficult for computers, since they work in binary, not base 10.
Say I ask you to divide 1 by 3. You answer 0.3333. Then I ask you to multiply the result by 3. Should you reply 1 or 0.9999? Since you wrote down the result with a finite precision you should answer the second option.
Now you select the list of integers. Is 0.9999 an integer? It isn't, but based on the calculation steps you might have expected it to be there.
The moral of the story: always use a tolerance when dealing with non-integers. You can probably use the ismembertol function to achieve what you need, or generate the new indices by hand like you did.