While preparing an answer to Count how many different values a list takes in Mathematica I came across an instability (for lack of a better term) in both DeleteDuplicates
and Tally
that I do not understand.
Consider first:
a = {2.2000000000000005, 2.2, 2.1999999999999999};
a // InputForm
DeleteDuplicates@a // InputForm
Union@a // InputForm
Tally@a // InputForm
{2.2000000000000006`, 2.2, 2.1999999999999997`}
{2.2000000000000006`, 2.2, 2.1999999999999997`}
{2.1999999999999997`, 2.2, 2.2000000000000006`}
{{2.2000000000000006`, 3}}
This behavior is as I expected in each case. Tally
compensates for the slight numerical differences and sees each element as being equivalent. Union
and DeleteDuplicates
see all elements as unique. (This behavior of Tally
is not documented to my knowledge, but I have made use of it before.)
Now, consider this complication:
a = {11/5, 2.2000000000000005, 2.2, 2.1999999999999997};
a // InputForm
DeleteDuplicates@a // InputForm
Union@a // InputForm
Tally@a // InputForm
{11/5, 2.2000000000000006, 2.2, 2.1999999999999997}
{11/5, 2.2000000000000006, 2.2}
{2.1999999999999997, 2.2, 11/5, 2.2000000000000006}
{{11/5, 1}, {2.2000000000000006, 1}, {2.2, 2}}
The output of Union
is as anticipated, but the results from both DeleteDuplicates
and Tally
are surprising.
Why does
DeleteDuplicates
suddenly see2.1999999999999997
as a duplicate to be eliminated?Why does
Tally
suddenly see2.2000000000000006
and2.2
as distinct, when it did not before?
As a related point, it can be seen that packed arrays affect Tally
:
a = {2.2000000000000005, 2.2, 2.1999999999999999};
a // InputForm
Tally@a // InputForm
{2.2000000000000006, 2.2, 2.1999999999999997}
{{2.2000000000000006`, 3}}
a = Developer`ToPackedArray@a;
a // InputForm
Tally@a // InputForm
{2.2000000000000006, 2.2, 2.1999999999999997}
{{2.2000000000000006`, 1}, {2.2, 2}}