Tell me more ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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
1  
If you use Ordering, Ordering[list, 1] is more efficient than First@Ordering[list] – Szabolcs Feb 11 at 19:40

2 Answers

up vote 4 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.

cf=Compile[{{x,_Real,1}},
      Module[{listval,max},
             listval=# Sin[#]&/@x;
             max=Max[listval];
             (Position[listval,max])[[1,1]]
             ],
      CompilationTarget->"C",
      RuntimeAttributes->{Listable},Parallelization->True];
share|improve this answer
This seems to be much faster than the other proposal on large inputs. – Reb.Cabin Feb 11 at 16:15
1  
Yes I will update the answer with timing comparison. – PlatoManiac Feb 11 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] &]. – kguler Feb 11 at 17:00

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

f=Sin;
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

Your Answer

 
discard

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.