# create_all_spin_flips Function

## public function create_all_spin_flips(nI_in) result(spin_flips)

### Arguments

Type IntentOptional Attributes Name
integer, intent(in) :: nI_in(:)

## Source Code

    function create_all_spin_flips(nI_in) result(spin_flips)
! takes a given spin-configuration in nI representation and
! creates all possible states with flipped spin and same ms
integer, intent(in) :: nI_in(:)
integer, allocatable :: spin_flips(:, :)

integer :: nI(size(nI_in)), nJ(size(nI_in))
integer :: num, n_open, ms, n_states, i, j, k, n_found
integer(n_int) :: ilutI(0:niftot), ilutJ(0:niftot)
integer, allocatable :: open_shells(:)
integer(n_int), allocatable :: ilut_list(:, :)

nI = nI_in

num = size(nI)

! it is not necessary to have nI sorted at input, so do that now
call sort_orbitals(nI)

call EncodeBitDet(nI, ilutI)

n_open = count_open_orbs(ilutI)
ms = sum(get_spin_pn(nI))

! the number of possible spin distributions:
n_states = int(choose_i64(n_open, n_open / 2 + ms))

allocate(spin_flips(num, n_states))
spin_flips = 0
! the first det will be the original one
spin_flips(:, 1) = nI

allocate(ilut_list(0:niftot, n_states))
ilut_list = 0_n_int
ilut_list(:, 1) = ilutI

n_found = 1
! i have a brute force solution for now:
! loop over all the possible states, starting with the original,
! since we need to account for multiple flips in this way
! i dont need to take the last one..
do i = 1, n_states - 1
! here determine the positions of the open-shell orbitals
open_shells = find_open_shell_indices(spin_flips(:, i))

! and now flip all possible open-shell pairs
do j = 1, n_open - 1
do k = j + 1, n_open
! cycle if same orbital or parallel spin
!                     if (j == k) cycle
if (same_spin(spin_flips(open_shells(j), i), spin_flips(open_shells(k), i))) cycle

nj = spin_flips(:, i)
if (is_beta(spin_flips(open_shells(j), i))) then
! then we know (j) is beta and (k) is alpha
nJ(open_shells(j)) = &
get_alpha(spin_flips(open_shells(j), i))
nJ(open_shells(k)) = &
get_beta(spin_flips(open_shells(k), i))
else
! otherwise (j) is alpha and (k) is beta
nJ(open_shells(j)) = &
get_beta(spin_flips(open_shells(j), i))
nJ(open_shells(k)) = &
get_alpha(spin_flips(open_shells(k), i))
end if

! if this determinant is not yet in the spin-flip
! list, put it in
call EncodeBitDet(nJ, ilutJ)
if (.not. is_in_list_ilut(ilutJ, n_found, ilut_list)) then
n_found = n_found + 1
ilut_list(:, n_found) = ilutJ
spin_flips(:, n_found) = nJ
end if
end do
end do
end do

!         call print_matrix(transpose(spin_flips))

end function create_all_spin_flips