Feature request: generalization of findmax/findmin to n values


#1

Given an array X I would like to find the n maximum (or minimum) values of the array and the positions where they are located. In matlab there is the following function that just does this

We have findmax that already does this for the maximum value. Could we have it for n values?
Something like findmax(X,5) returning 5 values and 5 positions would be very nice.


#2

You can get the same functionality in two lines via selectperm:

julia> function findextrema(v, n; rev=false)
           idx = selectperm(v, 1:n; rev=rev)
           return v[idx], idx
       end

julia> v = rand(-10:10, 5)
5-element Array{Int64,1}:
 -7
  7
  1
  4
  2

julia> findextrema(v,3; rev=true)
([7, 4, 2], [2, 4, 5])

#3

partialsort in v0.7 may help you. In v0.6.2 this same function is named select.

EDIT: or partialsortperm to get the positions.


#4

I agree that it would be nice to have a “more obvious” function for this in Base such as what @davidbp suggested.


#5

It looks like the method signature to do this with the function findmax is not yet taken.

function findpartialsort(v,k; opts...)
    inds = partialsortperm(v,k;opts...)
    length(inds) == 1 ? (inds,v[inds]) : (inds,v[[inds...]])
end

Base.findmax(v::AbstractArray,k::AbstractUnitRange; opts...) = findpartialsort(v,k; opts..., rev=true)
Base.findmin(v::AbstractArray,k::AbstractUnitRange; opts...) = findpartialsort(v,k; opts...)
julia> a = [40, 69, 14, 98, 83, 33, 20, 18, 53, 23];

julia> println(sort(a))
[14, 18, 20, 23, 33, 40, 53, 69, 83, 98]

julia> findmin(a,3:4)
([7, 10], [20, 23])

julia> findmax(a,3:4)
([2, 9], [69, 53])