Indexing Issue (with both ismember() and find())

5 views (last 30 days)
I have a really stange thing happening:
I have two arrays/lists that seem to match perfectly, but both the ismember function and the find function don't seem to recognize the third value...
array1 = [.1,.2,.3,.4];
array2 = [];
for i = .1:.1:.4
array2 = [array2, i];
end
array1
array2
ismember(array2,array1)
find(array2==array1)
These are the results:
array1 =
0.1000 0.2000 0.3000 0.4000
array2 =
0.1000 0.2000 0.3000 0.4000
ans =
1×4 logical array
1 1 0 1
ans =
1 2 4
You can see that the arrays match perfectly, but for some reason, it thinks the 3rd slot does not
(This came up while I was trying to write code for Euler's Formula)
Thank You
  1 Comment
Stephen23
Stephen23 on 9 Jul 2020
Edited: Stephen23 on 9 Jul 2020
"I have a really stange thing happening"
Nothing strange is happening.
"I have two arrays/lists that seem to match perfectly..."
Did you check this by just looking at some approximation of the values displayed in the command window or by using an actual robust method of comparison e.g. by obtaining their HEX representations or by using num2strexact ?
"...but both the ismember function and the find function don't seem to recognize the third value"
Because the third value is NOT the same.
"You can see that the arrays match perfectly..."
No, I can see that the arrays do NOT match perfectly:
>> array1-array2
ans =
0 0 -5.5511e-17 0
"... but for some reason, it thinks the 3rd slot does not"
Because they are different:
>> num2strexact(array1(3))
ans =
0.299999999999999988897769753748434595763683319091796875
>> num2strexact(array2(3))
ans =
0.3000000000000000444089209850062616169452667236328125
You did not take into account that you generated those binary floating point numbers in two different ways and so their accumulated error can be expected to be different. Common behaviors of binary floating point numbers have been discussed thoroughly many times:
This is worth reading as well:
Checking for exact equivalence will not work, the correct approach is to comapre the absolute difference against a tolerance.

Sign in to comment.

Accepted Answer

Star Strider
Star Strider on 9 Jul 2020
You have encountered floating-point approximation error, and the way the colon operator works.
Try this:
array1 = [.1,.2,.3,.4];
array2 = [];
for i = .1:.1:.4
array2 = [array2, i];
end
array1
array2
CheckEqual = array1-array2
ismembertol(array2,array1, 1E-4) % Use Tolerances
find(abs(array2-array1)<1E-4) % Use Tolerances
See Floating-Point Numbers and colon for more informaiton.
  2 Comments
Joseph Erreich
Joseph Erreich on 9 Jul 2020
This was perfect. The function I was mainly trying to use was ismember() (the find function was just an extra test to see what was going on). I altered it to ismembertol with teh 1E-4 parameter...Runs perfectly now. Thank you!

Sign in to comment.

More Answers (0)

Products


Release

R2020a

Community Treasure Hunt

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

Start Hunting!