I am looking for fortran routines that perform ranking. That is given a one dimensional array I would like a routine that returns the indices in that array of the (descending) sorted values. All I could fined are routines that perform sorting. Additionally it would be nice to have a routine that performs partial ordering. That is returning for a given number M the indices of the M biggest values - and others in any order. I found dlasrt but it only does sorting...
Well, for partial-sorting you just can just choose a sorting algorithm like selection sort and terminate after the first required number of elements rather than all of them. Make sure that you (partial-)sort a parallel array of indices rather than the array itself.
There's a partial_sort algorithm built into the standard library of C++, but not Fortran. Maybe you could check out how that is implemented.
module sorting
implicit none
contains
subroutine swap( a, b )
integer, intent(inout) :: a, b
integer temp
temp = a
a = b
b = temp
end subroutine swap
function best_n( A, nfirst ) result( indices )
integer, intent(in) :: A(:)
integer, intent(in) :: nfirst
integer, allocatable :: indices(:)
integer n
integer i, j, jmin
n = size( A )
indices = [ ( i, i = 1, n ) ]
do i = 1, nfirst
jmin = i
do j = i + 1, n
if ( A(indices(j)) > A(indices(jmin)) ) jmin = j
end do
if ( jmin /= i ) call swap( indices(i), indices(jmin) )
end do
end function best_n
end module sorting
!======================================================================
program main
use sorting
implicit none
integer, allocatable :: A(:), indices(:)
integer n
character(len=*), parameter :: fmt = "( a, *(i3,1x) )"
A = [ 1, -1, 2, -2, 3, -3 ]
n = 3
indices = best_n( A, n )
write( *, fmt ) "Original array: ", A
write( *, fmt ) "Best indices: ", indices(1:n)
write( *, fmt ) "Best values: ", A(indices(1:n))
end program main
Original array: 1 -1 2 -2 3 -3
Best indices: 5 3 1
Best values: 3 2 1