Feature request: generalization of findmax/findmin to n values

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.

1 Like

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])
4 Likes

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

EDIT: or partialsortperm to get the positions.

1 Like

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

1 Like

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])
3 Likes

I would like to note that I also found myself wanting for this functionality. partialsortperm works for AbstractVector but not for AbstractDict