Take the 2-minute tour ×
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
2  
If you use Ordering, Ordering[list, 1] is more efficient than First@Ordering[list] –  Szabolcs Feb 11 '13 at 19:40
add comment

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 '13 at 16:15
1  
Yes I will update the answer with timing comparison. –  PlatoManiac Feb 11 '13 at 16:16
1  
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 '13 at 17:00
add comment

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
    
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
add comment

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.