11
$\begingroup$

It maybe a stupid thing in the end but I'm stuck a couple of hours now.

I have a list of 2 points on the plane and I want to get the one with the biggest second coordinate. I thought I knew how SortBy operates. For example

SortBy[{{a, 1/2 (2 + Sqrt[2])}, {b, 1/2 (3 + Sqrt[2])}, {c, 1/2 (1 + Sqrt[2])}}, Function[{x}, x[[2]]]]

gives as expected the answer

{{c, 1/2 (1 + Sqrt[2])}, {a, 1/2 (2 + Sqrt[2])}, {b, 1/2 (3 + Sqrt[2])}}

and

SortBy[{{a, 1/2 (2 + Sqrt[2])}, {b, 1/2 (3 + Sqrt[2])}, {c, 1/2 (1 + Sqrt[2])}}, Function[{x}, -x[[2]]]]

gives as an answer

{{b, 1/2 (3 + Sqrt[2])}, {a, 1/2 (2 + Sqrt[2])}, {c, 1/2 (1 + Sqrt[2])}}

which is perfectly fine.

My list is

{{4/13 (-9 - Sqrt[3]), 6/13 (4 - Sqrt[3])}, {4/13 (-9 + Sqrt[3]), 6/13 (4 + Sqrt[3])}}

and the command

SortBy[{{4/13 (-9 - Sqrt[3]), 6/13 (4 - Sqrt[3])}, {4/13 (-9 + Sqrt[3]), 6/13 (4 + Sqrt[3])}}, Function[{x}, x[[2]]]]

gives the answer

{{4/13 (-9 - Sqrt[3]), 6/13 (4 - Sqrt[3])}, {4/13 (-9 + Sqrt[3]), 6/13 (4 + Sqrt[3])}}

which is the same as the answer I get from

SortBy[{{4/13 (-9 - Sqrt[3]), 6/13 (4 - Sqrt[3])}, {4/13 (-9 + Sqrt[3]), 6/13 (4 + Sqrt[3])}}, Function[{x}, -x[[2]]]]

Can someone explain to me what's going on? This drives me crazy.

$\endgroup$
  • 1
    $\begingroup$ related mathematica.stackexchange.com/questions/2729/ordering-problem $\endgroup$ – Algohi Oct 14 '14 at 7:10
  • 2
    $\begingroup$ No, it's not a bug. Sort only sorts numerically for explicit NumberQ numbers. SortBy is doing the same, based on second elements in this example. As pointed out in responses, to get that effect one might use N[#[[2]]]& as a second argument to SortBy. $\endgroup$ – Daniel Lichtblau Oct 14 '14 at 15:31
  • $\begingroup$ @Daniel Would you please give your attention to (31261)? Can you give me the kind of reference I am seeking? Will the canonical ordering ever by publicly defined in a rigorous way? $\endgroup$ – Mr.Wizard Oct 14 '14 at 19:08
  • $\begingroup$ @Mr.Wizard I am not aware of anything beyond what is already stated in the documentation. Also can say that, even with my own idiosyncratic internal needs (e.g. in working on products-of-powers code many years ago), I really have not had felt I had to know much about what Sort would do. That it puts numbers first is about all I ever relied upon. Also, occasionally it might change. $\endgroup$ – Daniel Lichtblau Oct 14 '14 at 19:58
9
$\begingroup$

I don't know exactly why Mathematica is giving a wrong result, but here's a workaround:

SortBy[{{4/13 (-9 - Sqrt[3]), 6/13 (4 - Sqrt[3])}, {4/13 (-9 + Sqrt[3]), 6/13 (4 + Sqrt[3])}}, 
        -N @ #[[2]] &]

Mathematica graphics

That is, force Mathematica to sort by their numerical value.

OR you can use Sort instead:

Sort[{{4/13 (-9 - Sqrt[3]), 6/13 (4 - Sqrt[3])}, {4/13 (-9 + Sqrt[3]),
    6/13 (4 + Sqrt[3])}}, #1[[2]] > #2[[2]] &]

Which gives the same result.

| improve this answer | |
$\endgroup$
  • $\begingroup$ Thanks! I think I'm convinced that this is a bug. Should I report it? $\endgroup$ – tst Oct 14 '14 at 2:16
  • $\begingroup$ I avoid using Sort because I'm confused with the ordering function thing. $\endgroup$ – tst Oct 14 '14 at 2:17
  • 2
    $\begingroup$ It may not be what you expected or desire but it performs as documented. "Sort[list] sorts the elements of list into canonical order." Using N or an inequality operator in the ordering function forces the canonical order to be numeric order for your examples. Note that since lists can contain any expressions and "Sort can be used on expressions with any head, not only List" the ordering function needs to be more generic than just numeric. $\endgroup$ – Bob Hanlon Oct 14 '14 at 3:38
  • 3
    $\begingroup$ @BobHanlon Out of curiosity, how else would you order things that are clearly numeric? Plus, "canonical ordering" is vague, I saw that in the documentation too. $\endgroup$ – RunnyKine Oct 14 '14 at 3:43
  • 1
    $\begingroup$ "Sort usually orders expressions by putting shorter ones first, and then comparing parts in a depth-first manner." This might be useful if you are trying to find the "simplest" form for expressions that are numerically equivalent. The "Details" section of the documentation for Sort gives insight into "canonical ordering." $\endgroup$ – Bob Hanlon Oct 14 '14 at 3:56
8
$\begingroup$

If this is a bug it runs far deeper than SortBy. Since no one has yet been able to provide a reference for the intended ordering of Sort etc. it is hard to say with certainty. I can demonstrate that Sort, Ordering and Order all agree, even if I can't justify that result.

x = {6/13 (4 - Sqrt[3]), 6/13 (4 + Sqrt[3])};

Outer[#@#2 &, {Order @@ # &, Ordering, Sort}, {x, -x}, 1] // Transpose // MatrixForm

enter image description here

Observe that both the original and negated (-x) forms are handed the same by each of the three functions. We can deduce that these expressions while not SameQ are considered "order irrelevant." Whether or not that is intended behavior I think only the designers can say.

What is clearly stated is that numeric comparision is not used by default, e.g.:

Sort[{∞, Sqrt[2], 1, 2, -∞, 1/Sqrt[2]}]
{1, 2, 1/Sqrt[2], Sqrt[2], -∞, ∞}

Therefore you should use N if you desire a numeric ranking.

| improve this answer | |
$\endgroup$
  • $\begingroup$ As an alternative to N you can use inequality operators: Sort[{\[Infinity], Sqrt[2], 1, 2, -\[Infinity], 1/Sqrt[2]}, Less] gives {-\[Infinity], 1/Sqrt[2], 1, Sqrt[2], 2, \[Infinity]} and Sort[{\[Infinity], Sqrt[2], 1, 2, -\[Infinity], 1/Sqrt[2]}, Greater] gives {\[Infinity], 2, Sqrt[2], 1, 1/Sqrt[2], -\[Infinity]} $\endgroup$ – Bob Hanlon Oct 14 '14 at 4:03
  • $\begingroup$ @Bob I meant that for SortBy one should use N; I don't see how one could use e.g. Less there. On the other hand of course Less is applicable to Sort and straight out of the documentation. $\endgroup$ – Mr.Wizard Oct 14 '14 at 6:11

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.