
!!! Here come the methods handling the selection of eigenvalues and eigenvectors !!!
!!! If you want a personal method, simply created a Subroutine returning the index
!!! array selected ind which contains as the first nval_out entries the index of the evals

! *****************************************************************************
!> \brief ...
!> \param arnoldi_data ...
! *****************************************************************************
  SUBROUTINE select_evals_[nametype1](arnoldi_data)
    TYPE(dbcsr_arnoldi_data)                :: arnoldi_data

    CHARACTER(LEN=*), PARAMETER :: routineN = 'select_evals_[nametype1]', &
      routineP = moduleN//':'//routineN 
    
    INTEGER                                  :: my_crit, last_el, my_ind, i
    REAL([type_prec])                        :: convergence
    TYPE(arnoldi_data_[nametype1]),POINTER   :: ar_data
    TYPE(arnoldi_control), POINTER           :: control

    control => get_control(arnoldi_data)
    ar_data => get_data_[nametype1](arnoldi_data)

    last_el=control%current_step
    convergence=REAL(0.0, [type_prec])
    my_crit=control%selection_crit
    control%nval_out=MIN(control%nval_req, control%current_step)
    SELECT CASE(my_crit)
    ! minimum and maximum real eval
    CASE(1)
       CALL index_min_max_real_eval_[nametype1](ar_data%evals, control%current_step, control%selected_ind, control%nval_out)
    ! n maximum real eval
    CASE(2)
       CALL index_nmax_real_eval_[nametype1](ar_data%evals, control%current_step, control%selected_ind, control%nval_out)
    ! n minimum real eval
    CASE(3)
       CALL index_nmin_real_eval_[nametype1](ar_data%evals, control%current_step, control%selected_ind, control%nval_out)
    CASE DEFAULT
       STOP 'unknown selection index'
    END SELECT
    ! test whether we are converged
    DO i=1, control%nval_out
       my_ind=control%selected_ind(i)
       convergence=MAX(convergence, &
                   ABS(ar_data%revec(last_el, my_ind)*ar_data%Hessenberg(last_el+1, last_el)))
    END DO
    control%converged=convergence.LT.control%threshold

  END SUBROUTINE select_evals_[nametype1]

! *****************************************************************************
!> \brief ...
!> \param evals ...
!> \param current_step ...
!> \param selected_ind ...
!> \param neval ...
! *****************************************************************************
  SUBROUTINE index_min_max_real_eval_[nametype1](evals, current_step, selected_ind, neval)
    COMPLEX([type_prec]), DIMENSION(:)       :: evals
    INTEGER                                  :: current_step
    INTEGER, DIMENSION(:)                    :: selected_ind
    INTEGER                                  :: neval

    CHARACTER(LEN=*), PARAMETER :: routineN = 'index_min_max_real_eval_[nametype1]', &
      routineP = moduleN//':'//routineN

    INTEGER, DIMENSION(current_step)         :: indexing
    REAL([type_prec]), DIMENSION(current_step)        :: tmp_array
    INTEGER                                   :: i

    neval=0
    selected_ind=0
    tmp_array(1:current_step)=REAL(evals(1:current_step), [type_prec])
    CALL sort(tmp_array, current_step, indexing)
    DO i=1,current_step
       IF(ABS(AIMAG(evals(indexing(i))))<EPSILON([real_zero]))THEN
          selected_ind(1)=indexing(i)
          neval=neval+1
          EXIT
       END IF
    END DO
    DO i=current_step,1,-1
       IF(ABS(AIMAG(evals(indexing(i))))<EPSILON([real_zero]))THEN
          selected_ind(2)=indexing(i)
          neval=neval+1
          EXIT
       END IF
    END DO

  END SUBROUTINE index_min_max_real_eval_[nametype1]

! *****************************************************************************
!> \brief ...
!> \param evals ...
!> \param current_step ...
!> \param selected_ind ...
!> \param neval ...
! *****************************************************************************
  SUBROUTINE index_nmax_real_eval_[nametype1](evals, current_step, selected_ind, neval)
    COMPLEX([type_prec]), DIMENSION(:)       :: evals
    INTEGER                                  :: current_step
    INTEGER, DIMENSION(:)                    :: selected_ind
    INTEGER                                  :: neval

    CHARACTER(LEN=*), PARAMETER :: routineN = 'index_nmax_real_eval_[nametype1]', &
      routineP = moduleN//':'//routineN
    
    INTEGER                                  :: i, nlimit
    INTEGER, DIMENSION(current_step)         :: indexing
    REAL([type_prec]), DIMENSION(current_step)        :: tmp_array

    nlimit=neval; neval=0
    selected_ind=0
    tmp_array(1:current_step)=REAL(evals(1:current_step), [type_prec])
    CALL sort(tmp_array, current_step, indexing)
    DO i=1, current_step
       IF(ABS(AIMAG(evals(indexing(current_step+1-i))))<EPSILON([real_zero]))THEN
          selected_ind(i)=indexing(current_step+1-i)
          neval=neval+1
          IF(neval==nlimit)EXIT
       END IF
    END DO

  END SUBROUTINE index_nmax_real_eval_[nametype1]

! *****************************************************************************
!> \brief ...
!> \param evals ...
!> \param current_step ...
!> \param selected_ind ...
!> \param neval ...
! *****************************************************************************
  SUBROUTINE index_nmin_real_eval_[nametype1](evals, current_step, selected_ind, neval)
    COMPLEX([type_prec]), DIMENSION(:)       :: evals
    INTEGER                                  :: current_step
    INTEGER, DIMENSION(:)                    :: selected_ind
    INTEGER                                  :: neval,nlimit

    CHARACTER(LEN=*), PARAMETER :: routineN = 'index_nmin_real_eval_[nametype1]', &
      routineP = moduleN//':'//routineN

    INTEGER                                  :: i
    INTEGER, DIMENSION(current_step)         :: indexing
    REAL([type_prec]), DIMENSION(current_step)        :: tmp_array

    nlimit=neval; neval=0
    selected_ind=0
    tmp_array(1:current_step)=REAL(evals(1:current_step), [type_prec])
    CALL sort(tmp_array, current_step, indexing)
    DO i=1, current_step
       IF(ABS(AIMAG(evals(indexing(i))))<EPSILON([real_zero]))THEN
          selected_ind(i)=indexing(i)
          neval=neval+1
          IF(neval==nlimit)EXIT
       END IF
    END DO

  END SUBROUTINE index_nmin_real_eval_[nametype1]

