I don't understand why this doesn't work:
In[30]:= MinimalBy[{{1, -Infinity}, {2, 3}}, Last]
Out[30]= {{2, 3}}
While this works seemingly:
In[31]:= MaximalBy[{"A" -> Infinity, "B" -> 2}, Last]
Out[31]= {"A" -> Infinity}
Mathematica Stack Exchange is a question and answer site for users of Wolfram Mathematica. It only takes a minute to sign up.
Sign up to join this communityI don't understand why this doesn't work:
In[30]:= MinimalBy[{{1, -Infinity}, {2, 3}}, Last]
Out[30]= {{2, 3}}
While this works seemingly:
In[31]:= MaximalBy[{"A" -> Infinity, "B" -> 2}, Last]
Out[31]= {"A" -> Infinity}
I agree, that's certainly confusing! Jim explained why it happened. Now how do we fix it?
Before MinimalBy
was introduced, I used
MinBy[list_, fun_] := list[[First@Ordering[fun /@ list, 1]]]
It does more or less the same thing except that it only returns a single result, even if there are multiple minimal elements.
Unlike MinimalBy
, Ordering
(and Sort
) can take a custom comparison function. Let's include this:
MinBy[list_, fun_, less_] := list[[First@Ordering[fun /@ list, 1, less]]]
The default behaviour is
MinBy[{{1, -Infinity}, {2, 3}}, Last, OrderedQ[{##}] &]
(* {2,3} *)
We can instead use
MinBy[{{1, -Infinity}, {2, 3}}, Last, Less]
(* {1, -∞} *)
Using a custom comparison function will probably significantly impact performance, but I haven't measured by how much. So avoid doing this when it's not necessary, e.g. when you have a very large list of only numbers.
There is another consideration (see under Possible Issues in the documentation), which also explains why Less
is not the default comparison.
To find out which of two expressions is larger may be computationally expensive and difficult, or Mathematica might not even be able to do it. Mathematica may need to compute BesselJ[0, 1]
and BesselJ[1, 1]
numerically to decide which is larger, and for some expressions this might be expensive. Or we might even be asking for a symbolic comparison like a^2 > a
assuming a > 1
.
The documentation for MinimalBy
states
The maximal element is determined using OrderedQ, not numerical ordering.
Try
OrderedQ[{3, Pi, 4}]
OrderedQ[{3, N[Pi], 4}]
You'll get False for the first (meaning the elements are not in canonical order) and True for the second (meaning the elements are in canonical order).
infConvert[x_]:=x/.{Infinity->$MaxMachineNumber,-Infinity->-$MaxMachineNumber}
and thenMinimalBy[{{1,-Infinity},{2,3}},Last[infConvert[#]]&]
$\endgroup$ – N.J.Evans Sep 15 '15 at 17:30