iqsort Subroutine

public recursive subroutine iqsort(list, order)

Sorts a sequence of integers

Arguments

Type IntentOptional Attributes Name
integer, intent(inout), DIMENSION (:) :: list

Sequence of integers to be sorted

integer, intent(out), optional, DIMENSION (:) :: order

Indices of the sorted sequence


Called by

proc~~iqsort~~CalledByGraph proc~iqsort iqsort proc~ivector_sort ivector_t%ivector_sort proc~ivector_sort->proc~iqsort proc~ivector_unique ivector_t%ivector_unique proc~ivector_unique->proc~iqsort proc~atan_build atan_build proc~atan_build->proc~ivector_sort proc~atat_build atat_build proc~atat_build->proc~ivector_unique proc~atbo_build atbo_build proc~atbo_build->proc~ivector_sort proc~atdh_build atdh_build proc~atdh_build->proc~ivector_sort proc~build_pt_aabbtree build_pt_aabbtree proc~build_pt_aabbtree->proc~ivector_sort proc~exat_build exat_build proc~exat_build->proc~ivector_unique proc~pt_build pt_build proc~pt_build->proc~build_pt_aabbtree proc~pt_init pt_init proc~pt_init->proc~atat_build proc~pt_init->proc~atbo_build proc~pt_init->proc~exat_build proc~ia_add_vdw_forces ia_add_vdw_forces proc~ia_add_vdw_forces->proc~pt_build proc~ia_setup ia_setup proc~ia_setup->proc~pt_init proc~ia_calc_forces ia_calc_forces proc~ia_calc_forces->proc~ia_add_vdw_forces proc~run run proc~run->proc~ia_setup proc~bds_run bds_run proc~run->proc~bds_run proc~calc_drift calc_drift proc~calc_drift->proc~ia_calc_forces program~main main program~main->proc~run proc~integrate_em integrate_em proc~integrate_em->proc~calc_drift proc~se_fval se_fval proc~se_fval->proc~calc_drift proc~bds_run->proc~integrate_em

Source Code

RECURSIVE SUBROUTINE iqsort(list, order)
    !!  Sorts a sequence of integers

IMPLICIT NONE

INTEGER, DIMENSION (:), INTENT(IN OUT)  :: list
    !!  Sequence of integers to be sorted
INTEGER, DIMENSION (:), INTENT(OUT), OPTIONAL  :: order
    !!  Indices of the sorted sequence

! Local variable
INTEGER :: i

IF (PRESENT(order)) THEN
    DO i = 1, SIZE(list)
      order(i) = i
    END DO
END IF

CALL quick_sort_1(1, SIZE(list))

CONTAINS

    RECURSIVE SUBROUTINE quick_sort_1(left_end, right_end)
    
    INTEGER, INTENT(IN) :: left_end, right_end
    
    !     Local variables
    INTEGER             :: i, j, itemp
    INTEGER             :: reference, temp
    INTEGER, PARAMETER  :: max_simple_sort_size = 8
    
    IF (right_end < left_end + max_simple_sort_size) THEN
        ! Use interchange sort for small lists
        CALL interchange_sort(left_end, right_end)
    
    ELSE
        ! Use partition ("quick") sort
        reference = list((left_end + right_end)/2)
        i = left_end - 1; j = right_end + 1
    
        DO
            ! Scan list from left end until element >= reference is found
            DO
                i = i + 1
                IF (list(i) >= reference) EXIT
            END DO
            ! Scan list from right end until element <= reference is found
            DO
                j = j - 1
                IF (list(j) <= reference) EXIT
            END DO
    
            IF (i < j) THEN
                ! Swap two out-of-order elements
                temp = list(i); list(i) = list(j); list(j) = temp
                IF (PRESENT(order)) THEN
                    itemp = order(i); order(i) = order(j); order(j) = itemp
                END IF
            ELSE IF (i == j) THEN
                i = i + 1
                EXIT
            ELSE
                EXIT
            END IF
        END DO
    
        IF (left_end < j) CALL quick_sort_1(left_end, j)
        IF (i < right_end) CALL quick_sort_1(i, right_end)
    END IF
    
    END SUBROUTINE quick_sort_1


    SUBROUTINE interchange_sort(left_end, right_end)
    
    INTEGER, INTENT(IN) :: left_end, right_end
    
    !     Local variables
    INTEGER             :: i, j, itemp
    INTEGER                :: temp
    
    DO i = left_end, right_end - 1
        DO j = i+1, right_end
            IF (list(i) > list(j)) THEN
                temp = list(i); list(i) = list(j); list(j) = temp
                IF (PRESENT(order)) THEN
                    itemp = order(i); order(i) = order(j); order(j) = itemp
                END IF
            END IF
        END DO
    END DO
    
    END SUBROUTINE interchange_sort

END SUBROUTINE iqsort