# Role of Accuracy in numerical evaluations, SplitBy vs GatherBy

This is a follow-up question to this question.

I generated a list by substituting the results of a solve[] routine and set:

sln=expression /.Solve[...];
list= SetAccuracy[N[sln],2]]


You can find the FullForm[list] further down. I was trying to parition this list into sublists with equal norms.

If you evaluate Map[Norm, list] you get {0, 1.6, 0.6, 0.6, 1.6, 1.6, 0.6, 0.6, 1.6, 0.6, 1.6} There are three sets of values for the norms.

I tried

GatherBy[SortBy[list, Norm], Norm]


and

SplitBy[SortBy[list, Norm], Norm]


And they give me different results. However, if my list2 was a list of numbers inputted by hands without any explicit accuracy, the two expressions yield equal results.

• What is different about SplitBy[] and Gatherby[] that causes this?
• How do accuracy and precision interplay in numerical results?

For reproduciblity purposes, I am quoting FullForm version of list variable that I performed the tests with:

FullForm[list]=     \!$$TagBox[ StyleBox[ RowBox[{"List", "[", RowBox[{ RowBox[{"List", "[", RowBox[{"02.", ",", "02."}], "]"}], ",", RowBox[{"List", "[", RowBox[{"0.51.6989700043360187", ",", "0.866025403784438596588302061718422919511.93753063169585"}], "]"}], ",", RowBox[{"List", "[", RowBox[{"0.51.6989700043360187", ",", RowBox[{"-", "0.866025403784438596588302061718422919511.93753063169585"}]\ }], "]"}], ",", RowBox[{"List", "[", RowBox[{ RowBox[{"-", "1.2."}], ",", "02."}], "]"}]}], "]"}], ShowSpecialCharacters->False, ShowStringCharacters->True, NumberMarks->True], FullForm]$$


and

GatherBy[SortBy[a, Norm], Norm] == SplitBy[SortBy[a, Norm], Norm]


returns False.

• A simpler formulation of the same fundamental question: Given list = SetAccuracy[{1, 1, 1.01, 1.01, 1.02, 1.02}, 2] why does Gather[list] give a different result from Split[list] – Simon Woods Feb 14 '16 at 13:45
• A related question of mine from Stack Overflow, with a valuable answer from WReach: Instability in DeleteDuplicates and Tally – Mr.Wizard Feb 14 '16 at 15:01

In the words of WReach: SameQ Is Not An Equivalence Relation

I shall take Simon Woods's concise example as a starting point:

list = SetAccuracy[{1, 1, 1.01, 1.01, 1.02, 1.02}, 2];

Gather[list]
Split[list]

{{1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}}

{{1.0, 1.0, 1.0, 1.0, 1.0, 1.0}}


Split compares elements that are side-by-side, and in that measure they are all SameQ true:

SameQ @@@ Partition[list, 2, 1]

{True, True, True, True, True}


However this does not mean that the first and last elements are SameQ true!

SameQ @@ list[[{1, -1}]]

False


SameQ is not a complete explanation for this behavior because it is possible to set an Internal$SameQTolerance that sees the first and last elements as identical, yet have Gather return three lists: Internal$SameQTolerance = 3;

SameQ @@ list[[{1, -1}]]

Gather[list]

True

{{1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}}


With a sufficiently high value a single list is returned, so this is having an effect on Gather:

Internal\$SameQTolerance = 15;

Gather[list]

{{1.0, 1.0, 1.0, 1.0, 1.0, 1.0}}

list = SetAccuracy[{1, 1, 1.01, 1.01, 1.02, 1.02}, 2] // Partition[#, 2] &

(*  {{1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}}  *)


To get what appears to be his desired behaviour, I think the OP should be using Round

GatherBy[SortBy[list, Norm], Norm[Round[#, .1]] &]

(*  {{{1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}}}  *)

SplitBy[SortBy[list, Norm], Norm]

(*  {{{1.0, 1.0}, {1.0, 1.0}, {1.0, 1.0}}}  *)

% === %%

True