subroutine gen_next_single_ex(string_i, ilut_i, nras1, nras3, ind, par, ex, ras, classes, gen_store, tgen, tcount)
! Generate the next single excitation (within the RAS space - we don't need to consider
! excitations to outside it) and also return the associated parity and the class and
! address of the created string. If tcount is true then the routine is only being used
! to count the excitation, so these are not returned in this case.
integer, intent(in) :: string_i(tot_nelec)
integer(n_int), intent(in) :: ilut_i(0:NIfD)
integer, intent(in) :: nras1, nras3
integer, intent(out) :: ind, par
integer, intent(out) :: ex(2)
type(ras_parameters), intent(in) :: ras
type(ras_class_data), intent(in) :: classes(ras%num_classes)
type(simple_excit_store), intent(inout), target :: gen_store
logical, intent(inout) :: tgen
logical, intent(in) :: tcount
integer, pointer :: i, j
integer :: orb1, orb2, temp1, temp3, class_k, m
integer :: string_k(tot_nelec)
! Map the local variables onto the store.
i => gen_store%i;
j => gen_store%j
! Initialise the generator.
if (tgen) then
i = 1
j = 0
tgen = .false.
end if
! Find the next possible single excitation. Loop over electrons and vacant orbitals.
! Interrupt loop when we find what we need.
do i = i, tot_nelec
orb1 = string_i(i)
j = j + 1
do j = j, tot_norbs
orb2 = j
! Cannot excite to an occupied orbital, unless it is the orbital that we are
! exciting from.
if (IsOcc(ilut_i, orb2) .and. (string_i(i) /= j)) cycle
ex(1) = string_i(i)
ex(2) = j
temp1 = nras1
temp3 = nras3
! Store the values of nras1 and nras3 for the new string.
if (ex(1) <= ras%size_1) then
temp1 = temp1 - 1
else if (ex(1) > ras%size_1 + ras%size_2) then
temp3 = temp3 - 1
end if
if (ex(2) <= ras%size_1) then
temp1 = temp1 + 1
else if (ex(2) > ras%size_1 + ras%size_2) then
temp3 = temp3 + 1
end if
! We don't have to consider excitations to outside the ras space.
if (.not. class_allowed(ras, temp1, temp3)) cycle
! If we get to this point then (orb1, orb2) is a valid excitation. As an
! optimisation, if we are only counting the excitations then return now.
if (tcount) return
! Encode new string.
string_k = string_i
string_k(i) = j
call sort(string_k)
class_k = ras%class_label(temp1, temp3)
ind = classes(class_k)%address_map(get_address(classes(class_k), string_k))
do m = 1, class_k - 1
ind = ind + classes(m)%class_size
end do
par = get_single_parity(ilut_i, ex(1), ex(2))
return
end do
j = 0 ! Reset loop.
end do
tgen = .true.
end subroutine gen_next_single_ex