BinSearchParts_rdm Subroutine

public subroutine BinSearchParts_rdm(iLut, MinInd, MaxInd, PartInd, tSuccess)

Arguments

Type IntentOptional Attributes Name
integer(kind=n_int) :: iLut(0:NIfTot)
integer :: MinInd
integer :: MaxInd
integer :: PartInd
logical :: tSuccess

Contents

Source Code


Source Code

    subroutine BinSearchParts_rdm(iLut, MinInd, MaxInd, PartInd, tSuccess)

        ! Do a binary search in CurrentDets, between the indices of MinInd and
        ! MaxInd. If successful, tSuccess will be true and  PartInd will be a
        ! coincident determinant. If there are multiple values, the chosen one
        ! may be any of them... If failure, then the index will be one less than
        ! the index that the particle would be in if it was present in the list.
        ! (or close enough!)

        integer(kind=n_int) :: iLut(0:NIfTot)
        integer :: MinInd, MaxInd, PartInd
        integer :: i, j, N, Comp
        logical :: tSuccess

        i = MinInd
        j = MaxInd
        if (i - j == 0) then
            Comp = DetBitLT(CurrentDets(:, MaxInd), iLut(:), nifd)
            if (Comp == 0) then
                tSuccess = .true.
                PartInd = MaxInd
                return
            else
                tSuccess = .false.
                PartInd = MinInd
            end if
        end if

        do while (j - i > 0)  ! End when the upper and lower bound are the same.
            N = (i + j) / 2       ! Find the midpoint of the two indices.

            ! Comp is 1 if CyrrebtDets(N) is "less" than iLut, and -1 if it is
            ! more or 0 if they are the same
            Comp = DetBitLT(CurrentDets(:, N), iLut(:), nifd)

            if (Comp == 0) then
                ! Praise the lord, we've found it!
                tSuccess = .true.
                PartInd = N
                return
            else if ((Comp == 1) .and. (i /= N)) then
                ! The value of the determinant at N is LESS than the determinant
                ! we're looking for. Therefore, move the lower bound of the search
                ! up to N. However, if the lower bound is already equal to N then
                ! the two bounds are consecutive and we have failed...
                i = N
            else if (i == N) then

                if (i == MaxInd - 1) then
                    ! This deals with the case where we are interested in the
                    ! final/first entry in the list. Check the final entry of
                    ! the list and leave. We need to check the last index.
                    Comp = DetBitLT(CurrentDets(:, i + 1), iLut(:), nifd)
                    if (Comp == 0) then
                        tSuccess = .true.
                        PartInd = i + 1
                        return
                    else if (Comp == 1) then
                        ! final entry is less than the one we want.
                        tSuccess = .false.
                        PartInd = i + 1
                        return
                    else
                        tSuccess = .false.
                        PartInd = i
                        return
                    end if

                else if (i == MinInd) then
                    tSuccess = .false.
                    PartInd = i
                    return
                else
                    i = j
                end if

            else if (Comp == -1) then
                ! The value of the determinant at N is MORE than the determinant
                ! we're looking for. Move the upper bound of the search down to N.
                j = N
            else
                ! We have failed - exit loop.
                i = j
            end if

        end do

        ! If we have failed, then we want to find the index that is one less
        ! than where the particle would have been.
        tSuccess = .false.
        PartInd = max(MinInd, i - 1)

    end subroutine BinSearchParts_rdm