# UMatInd_base Function

## private elemental function UMatInd_base(I, J, K, L, nBI) result(UMatInd)

### Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: I
integer, intent(in) :: J
integer, intent(in) :: K
integer, intent(in) :: L
integer, intent(in) :: nBI

## Source Code

    elemental FUNCTION UMatInd_base(I, J, K, L, nBI) result(UMatInd)
! Get the index of physical order UMAT element <IJ|KL>.
! Indices are internally reordered such that I>K, J>L,(I,K)>(J,L)
! Note: (i,k)>(j,l) := (k>l) || ((k==l)&&(i>j))
! In:
!    I,J,K,L: orbital indices. These refer to spin orbitals in
!      unrestricted calculations and spatial orbitals in restricted
!      calculations.
!    nBasis: size of basis. If =0, use nStates instead.
!    nOccupied: # of occupied orbitals.  If =0, then nOcc is used.
!    Should only be passed as non-zero during the freezing process.
INTEGER, intent(in) :: I, J, K, L, nBI
integer(int64) :: UMatInd
integer :: A, B

if (t_non_hermitian_2_body) then
A = (I - 1) * nBi + K
B = (J - 1) * nBi + L
else
!Combine indices I and K, ensuring I>K
IF (I > K) THEN
A = (I * (I - 1)) / 2 + K
ELSE
A = (K * (K - 1)) / 2 + I
END IF

!Combine indices J and L, ensuring J>L
IF (J > L) THEN
B = (J * (J - 1)) / 2 + L
ELSE
B = (L * (L - 1)) / 2 + J
END IF
end if

!Combine (IK) and (JL) in a unique way  (k > l or if k = l then i > j)
IF (A > B) THEN
UMatInd = (int(A, int64) * int(A - 1, int64)) / 2 + int(B, int64)
ELSE
UMatInd = (int(B, int64) * int(B - 1, int64)) / 2 + int(A, int64)
END IF
#ifdef CMPLX_
if (.not. tComplexWalkers_RealInts) then
UMatInd = (UmatInd - 1) * 2 + 1
!We need to test whether we have swapped i and k or j and l independantly of each other
!If we have done this, it is one of the 'other' integrals - add one.
if (((I > K) .and. (J < L)) .or. ((I < K) .and. (J > L))) then
UMatInd = UMatInd + 1
end if
end if
#endif
END FUNCTION UMatInd_Base