3
$\begingroup$

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[{"0``2.", ",", "0``2."}], "]"}], ",", 
RowBox[{"List", "[", 
RowBox[{"0.5`1.6989700043360187", ",", 
        "0.86602540378443859658830206171842291951`1.93753063169585"}],
        "]"}], ",", 
RowBox[{"List", "[", 
RowBox[{"0.5`1.6989700043360187", ",", 
RowBox[{"-", 
         "0.86602540378443859658830206171842291951`1.93753063169585"}]\
}], "]"}], ",", 
RowBox[{"List", "[", 
RowBox[{
RowBox[{"-", "1.`2."}], ",", "0``2."}], "]"}]}], "]"}],
ShowSpecialCharacters->False,
ShowStringCharacters->True,
NumberMarks->True],
FullForm]\)

and

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

returns False.

$\endgroup$
  • 2
    $\begingroup$ 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] $\endgroup$ – Simon Woods Feb 14 '16 at 13:45
  • $\begingroup$ A related question of mine from Stack Overflow, with a valuable answer from WReach: Instability in DeleteDuplicates and Tally $\endgroup$ – Mr.Wizard Feb 14 '16 at 15:01
3
$\begingroup$

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}}
$\endgroup$
0
$\begingroup$
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
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.