Mathematica Stack Exchange is a question and answer site for users of Mathematica. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

Wondering whether there are discrete versions of ArgMax / ArgMin, that is, something that will find the part of an expression at which some function f of the elements is maximized (or minimized).

Last[Ordering[f/@list]] and First[Ordering[f/@list]] will do, but the following does not work:

ArgMax[Function[i, (f/@list)[[i]]], i]
share|improve this question
If you use Ordering, Ordering[list, 1] is more efficient than First@Ordering[list] – Szabolcs Feb 11 '13 at 19:40
What if the function is bivariate, e.g., f(x,y), and we want to find argmax or argmin over both x and y? – Alex Mar 24 '15 at 18:27
If you have a new question, please ask it by clicking the Ask Question button. Include a link to this question if it helps provide context. – bbgodfrey Mar 24 '15 at 18:58
This does not provide an answer to the question. To critique or request clarification from an author, leave a comment below their post - you can always comment on your own posts, and once you have sufficient reputation you will be able to comment on any post. – Louis Mar 24 '15 at 19:38
up vote 7 down vote accepted

I guess Max and Min are the best fit for discrete lists.

f[x_] := x Sin[x];
list = RandomReal[10, 10^6];
(Position[#, Max[#], 2][[1, 1]]) &@(f /@ list)

One can forcefully use NArgMax or NArgMin for this purpose but they are likely to be extremely inefficient! One such example

list = RandomReal[10, 1000];
ob[i_?IntegerQ] := (f /@ list)[[i]];
ob@NArgMax[{Evaluate@ob[x],1<= x<= Length@list&&Element[x,Integers]},x]//AbsoluteTiming

{5.8344103, 7.91672}

Where as

Max[f /@ list]// AbsoluteTiming

{0., 7.91672}

For timing comparison with solution using Ordering see the following plot. Horizontal axes shows the data length of list and the vertical axes is denoting computation time in seconds. I have tested it in an Intel i7 PC with 64 GB RAM.

enter image description here

As one can see if you compile the functions you get even better speed ups.

             listval=# Sin[#]&/@x;
share|improve this answer
This seems to be much faster than the other proposal on large inputs. – Reb.Cabin Feb 11 '13 at 16:15
Yes I will update the answer with timing comparison. – PlatoManiac Feb 11 '13 at 16:16
Ordering[f /@ list, -1] for argmax and Ordering[f /@ list,1] for argmin seems to be faster than both Position-Max combination and Ordering[list,f[#1] < f[#2] &]. – kglr Feb 11 '13 at 17:00

Ordering is good for this if you use a custom ordering function:

list = RandomReal[{0, Pi}, 100];
First@Ordering[list, 1, f[#1] < f[#2] &]

And similarly for maximum replacing 1 with -1 (or < with >)

share|improve this answer
Manually supplying an ordering function seems to be much slower than just using Ordering[f/@list,1] as kguler recommended in a comment to an answer above. – Wizard Oct 7 '13 at 21:59

Version 10 has a new function FindPeaks that can be used here:

f[x_] := x Sin[x];
list = Range[1, 10, 0.1];
FindPeaks[f /@ list]

This returns the location (in the list) and value of the local maxes. Another new function that's related is MaxDetect, which returns a vector of zeros (at all the non-max locations) and ones (at all the max locations).

MaxDetect[f /@ list]

MaxDetect also works nicely on 2D and 3D data arrays and images, and there is also MinDetect that does what you would expect.

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

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