subroutine generate_single_pcpp(nI, elec_map, ilut, nJ, excitMat, tParity, pGen)
implicit none
! given the initial determinant (both as nI and ilut), create a random double excitation
! given by nJ/ilutnJ/excitMat with probability pGen. tParity indicates the fermi sign
! picked up by applying the excitation operator
! Input: nI - determinant to excite from
! elec_map - map to translate electron picks to orbitals
! ilut - determinant to excite from in ilut format
! nJ - on return, excited determinant
! excitMat - on return, excitation matrix nI -> nJ
! tParity - on return, the parity of the excitation nI -> nJ
! pGen - on return, the probability of generating the excitation nI -> nJ
integer, intent(in) :: nI(nel)
integer, intent(in) :: elec_map(nel)
integer(n_int), intent(in) :: ilut(0:NIfTot)
integer, intent(out) :: nJ(nel)
integer, intent(out) :: ExcitMat(2, 2)
logical, intent(out) :: tParity
real(dp), intent(out) :: pGen
integer :: src, elec, tgt
real(dp) :: pHole
! get a random electron
call single_elec_sampler%sample(src, pGen)
! map the electron to the current determinant
src = elec_map(src)
! get a random associated orbital
call single_hole_sampler(src)%sample(tgt, pHole)
if (IsOcc(ilut, tgt)) then
! invalidate the excitation, we hit an occupied orbital
nJ = 0
excitMat = 0
excitMat(1, 1) = src
excitMat(2, 1) = tgt
! report the failure
tParity = .false.
else
elec = binary_search_first_ge(nI, src)
call make_single(nI, nJ, elec, tgt, excitMat, tParity)
end if
! add the probability to find this hole from this electron
pGen = pGen * pHole
end subroutine generate_single_pcpp