stdlib_lapack_eigv_gen2.fypp Source File


Source Code

#:include "common.fypp" 
submodule(stdlib_lapack_eig_svd_lsq) stdlib_lapack_eigv_gen2
  implicit none


  contains
#:for ik,it,ii in LINALG_INT_KINDS_TYPES

     module subroutine stdlib${ii}$_shseqr( job, compz, n, ilo, ihi, h, ldh, wr, wi, z,ldz, work, lwork, info )
     !! SHSEQR computes the eigenvalues of a Hessenberg matrix H
     !! and, optionally, the matrices T and Z from the Schur decomposition
     !! H = Z T Z**T, where T is an upper quasi-triangular matrix (the
     !! Schur form), and Z is the orthogonal matrix of Schur vectors.
     !! Optionally Z may be postmultiplied into an input orthogonal
     !! matrix Q so that this routine can give the Schur factorization
     !! of a matrix A which has been reduced to the Hessenberg form H
     !! by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ihi, ilo, ldh, ldz, lwork, n
           integer(${ik}$), intent(out) :: info
           character, intent(in) :: compz, job
           ! Array Arguments 
           real(sp), intent(inout) :: h(ldh,*), z(ldz,*)
           real(sp), intent(out) :: wi(*), work(*), wr(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ntiny = 15_${ik}$
           integer(${ik}$), parameter :: nl = 49_${ik}$
           ! ==== matrices of order ntiny or smaller must be processed by
           ! .    stdlib${ii}$_slahqr because of insufficient subdiagonal scratch space.
           ! .    (this is a hard limit.) ====
           
           ! ==== nl allocates some local workspace to help small matrices
           ! .    through a rare stdlib${ii}$_slahqr failure.  nl > ntiny = 15 is
           ! .    required and nl <= nmin = stdlib${ii}$_ilaenv(ispec=12,...) is recom-
           ! .    mended.  (the default value of nmin is 75.)  using nl = 49
           ! .    allows up to six simultaneous shifts and a 16-by-16
           ! .    deflation window.  ====
           
           
           ! Local Arrays 
           real(sp) :: hl(nl,nl), workl(nl)
           ! Local Scalars 
           integer(${ik}$) :: i, kbot, nmin
           logical(lk) :: initz, lquery, wantt, wantz
           ! Intrinsic Functions 
           ! Executable Statements 
           ! ==== decode and check the input parameters. ====
           wantt = stdlib_lsame( job, 'S' )
           initz = stdlib_lsame( compz, 'I' )
           wantz = initz .or. stdlib_lsame( compz, 'V' )
           work( 1_${ik}$ ) = real( max( 1_${ik}$, n ),KIND=sp)
           lquery = lwork==-1_${ik}$
           info = 0_${ik}$
           if( .not.stdlib_lsame( job, 'E' ) .and. .not.wantt ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compz, 'N' ) .and. .not.wantz ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ilo<1_${ik}$ .or. ilo>max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ihi<min( ilo, n ) .or. ihi>n ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<max( 1_${ik}$, n ) ) ) then
              info = -11_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -13_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              ! ==== quick return in case of invalid argument. ====
              call stdlib${ii}$_xerbla( 'SHSEQR', -info )
              return
           else if( n==0_${ik}$ ) then
              ! ==== quick return in case n = 0; nothing to do. ====
              return
           else if( lquery ) then
              ! ==== quick return in case of a workspace query ====
              call stdlib${ii}$_slaqr0( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                        work, lwork, info )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = max( real( max( 1_${ik}$, n ),KIND=sp), work( 1_${ik}$ ) )
              return
           else
              ! ==== copy eigenvalues isolated by stdlib${ii}$_sgebal ====
              do i = 1, ilo - 1
                 wr( i ) = h( i, i )
                 wi( i ) = zero
              end do
              do i = ihi + 1, n
                 wr( i ) = h( i, i )
                 wi( i ) = zero
              end do
              ! ==== initialize z, if requested ====
              if( initz )call stdlib${ii}$_slaset( 'A', n, n, zero, one, z, ldz )
              ! ==== quick return if possible ====
              if( ilo==ihi ) then
                 wr( ilo ) = h( ilo, ilo )
                 wi( ilo ) = zero
                 return
              end if
              ! ==== stdlib${ii}$_slahqr/stdlib${ii}$_slaqr0 crossover point ====
              nmin = stdlib${ii}$_ilaenv( 12_${ik}$, 'SHSEQR', job( : 1_${ik}$ ) // compz( : 1_${ik}$ ), n,ilo, ihi, lwork )
                        
              nmin = max( ntiny, nmin )
              ! ==== stdlib${ii}$_slaqr0 for big matrices; stdlib${ii}$_slahqr for small ones ====
              if( n>nmin ) then
                 call stdlib${ii}$_slaqr0( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                           work, lwork, info )
              else
                 ! ==== small matrix ====
                 call stdlib${ii}$_slahqr( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                           info )
                 if( info>0_${ik}$ ) then
                    ! ==== a rare stdlib${ii}$_slahqr failure!  stdlib${ii}$_slaqr0 sometimes succeeds
                    ! .    when stdlib${ii}$_slahqr fails. ====
                    kbot = info
                    if( n>=nl ) then
                       ! ==== larger matrices have enough subdiagonal scratch
                       ! .    space to call stdlib${ii}$_slaqr0 directly. ====
                       call stdlib${ii}$_slaqr0( wantt, wantz, n, ilo, kbot, h, ldh, wr,wi, ilo, ihi, z,&
                                  ldz, work, lwork, info )
                    else
                       ! ==== tiny matrices don't have enough subdiagonal
                       ! .    scratch space to benefit from stdlib${ii}$_slaqr0.  hence,
                       ! .    tiny matrices must be copied into a larger
                       ! .    array before calling stdlib${ii}$_slaqr0. ====
                       call stdlib${ii}$_slacpy( 'A', n, n, h, ldh, hl, nl )
                       hl( n+1, n ) = zero
                       call stdlib${ii}$_slaset( 'A', nl, nl-n, zero, zero, hl( 1_${ik}$, n+1 ),nl )
                       call stdlib${ii}$_slaqr0( wantt, wantz, nl, ilo, kbot, hl, nl, wr,wi, ilo, ihi, &
                                 z, ldz, workl, nl, info )
                       if( wantt .or. info/=0_${ik}$ )call stdlib${ii}$_slacpy( 'A', n, n, hl, nl, h, ldh )
                                 
                    end if
                 end if
              end if
              ! ==== clear out the trash, if necessary. ====
              if( ( wantt .or. info/=0_${ik}$ ) .and. n>2_${ik}$ )call stdlib${ii}$_slaset( 'L', n-2, n-2, zero, zero,&
                         h( 3_${ik}$, 1_${ik}$ ), ldh )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = max( real( max( 1_${ik}$, n ),KIND=sp), work( 1_${ik}$ ) )
           end if
     end subroutine stdlib${ii}$_shseqr

     module subroutine stdlib${ii}$_dhseqr( job, compz, n, ilo, ihi, h, ldh, wr, wi, z,ldz, work, lwork, info )
     !! DHSEQR computes the eigenvalues of a Hessenberg matrix H
     !! and, optionally, the matrices T and Z from the Schur decomposition
     !! H = Z T Z**T, where T is an upper quasi-triangular matrix (the
     !! Schur form), and Z is the orthogonal matrix of Schur vectors.
     !! Optionally Z may be postmultiplied into an input orthogonal
     !! matrix Q so that this routine can give the Schur factorization
     !! of a matrix A which has been reduced to the Hessenberg form H
     !! by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ihi, ilo, ldh, ldz, lwork, n
           integer(${ik}$), intent(out) :: info
           character, intent(in) :: compz, job
           ! Array Arguments 
           real(dp), intent(inout) :: h(ldh,*), z(ldz,*)
           real(dp), intent(out) :: wi(*), work(*), wr(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ntiny = 15_${ik}$
           integer(${ik}$), parameter :: nl = 49_${ik}$
           ! ==== matrices of order ntiny or smaller must be processed by
           ! .    stdlib${ii}$_dlahqr because of insufficient subdiagonal scratch space.
           ! .    (this is a hard limit.) ====
           
           ! ==== nl allocates some local workspace to help small matrices
           ! .    through a rare stdlib${ii}$_dlahqr failure.  nl > ntiny = 15 is
           ! .    required and nl <= nmin = stdlib${ii}$_ilaenv(ispec=12,...) is recom-
           ! .    mended.  (the default value of nmin is 75.)  using nl = 49
           ! .    allows up to six simultaneous shifts and a 16-by-16
           ! .    deflation window.  ====
           
           
           ! Local Arrays 
           real(dp) :: hl(nl,nl), workl(nl)
           ! Local Scalars 
           integer(${ik}$) :: i, kbot, nmin
           logical(lk) :: initz, lquery, wantt, wantz
           ! Intrinsic Functions 
           ! Executable Statements 
           ! ==== decode and check the input parameters. ====
           wantt = stdlib_lsame( job, 'S' )
           initz = stdlib_lsame( compz, 'I' )
           wantz = initz .or. stdlib_lsame( compz, 'V' )
           work( 1_${ik}$ ) = real( max( 1_${ik}$, n ),KIND=dp)
           lquery = lwork==-1_${ik}$
           info = 0_${ik}$
           if( .not.stdlib_lsame( job, 'E' ) .and. .not.wantt ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compz, 'N' ) .and. .not.wantz ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ilo<1_${ik}$ .or. ilo>max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ihi<min( ilo, n ) .or. ihi>n ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<max( 1_${ik}$, n ) ) ) then
              info = -11_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -13_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              ! ==== quick return in case of invalid argument. ====
              call stdlib${ii}$_xerbla( 'DHSEQR', -info )
              return
           else if( n==0_${ik}$ ) then
              ! ==== quick return in case n = 0; nothing to do. ====
              return
           else if( lquery ) then
              ! ==== quick return in case of a workspace query ====
              call stdlib${ii}$_dlaqr0( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                        work, lwork, info )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = max( real( max( 1_${ik}$, n ),KIND=dp), work( 1_${ik}$ ) )
              return
           else
              ! ==== copy eigenvalues isolated by stdlib${ii}$_dgebal ====
              do i = 1, ilo - 1
                 wr( i ) = h( i, i )
                 wi( i ) = zero
              end do
              do i = ihi + 1, n
                 wr( i ) = h( i, i )
                 wi( i ) = zero
              end do
              ! ==== initialize z, if requested ====
              if( initz )call stdlib${ii}$_dlaset( 'A', n, n, zero, one, z, ldz )
              ! ==== quick return if possible ====
              if( ilo==ihi ) then
                 wr( ilo ) = h( ilo, ilo )
                 wi( ilo ) = zero
                 return
              end if
              ! ==== stdlib${ii}$_dlahqr/stdlib${ii}$_dlaqr0 crossover point ====
              nmin = stdlib${ii}$_ilaenv( 12_${ik}$, 'DHSEQR', job( : 1_${ik}$ ) // compz( : 1_${ik}$ ), n,ilo, ihi, lwork )
                        
              nmin = max( ntiny, nmin )
              ! ==== stdlib${ii}$_dlaqr0 for big matrices; stdlib${ii}$_dlahqr for small ones ====
              if( n>nmin ) then
                 call stdlib${ii}$_dlaqr0( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                           work, lwork, info )
              else
                 ! ==== small matrix ====
                 call stdlib${ii}$_dlahqr( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                           info )
                 if( info>0_${ik}$ ) then
                    ! ==== a rare stdlib${ii}$_dlahqr failure!  stdlib${ii}$_dlaqr0 sometimes succeeds
                    ! .    when stdlib${ii}$_dlahqr fails. ====
                    kbot = info
                    if( n>=nl ) then
                       ! ==== larger matrices have enough subdiagonal scratch
                       ! .    space to call stdlib${ii}$_dlaqr0 directly. ====
                       call stdlib${ii}$_dlaqr0( wantt, wantz, n, ilo, kbot, h, ldh, wr,wi, ilo, ihi, z,&
                                  ldz, work, lwork, info )
                    else
                       ! ==== tiny matrices don't have enough subdiagonal
                       ! .    scratch space to benefit from stdlib${ii}$_dlaqr0.  hence,
                       ! .    tiny matrices must be copied into a larger
                       ! .    array before calling stdlib${ii}$_dlaqr0. ====
                       call stdlib${ii}$_dlacpy( 'A', n, n, h, ldh, hl, nl )
                       hl( n+1, n ) = zero
                       call stdlib${ii}$_dlaset( 'A', nl, nl-n, zero, zero, hl( 1_${ik}$, n+1 ),nl )
                       call stdlib${ii}$_dlaqr0( wantt, wantz, nl, ilo, kbot, hl, nl, wr,wi, ilo, ihi, &
                                 z, ldz, workl, nl, info )
                       if( wantt .or. info/=0_${ik}$ )call stdlib${ii}$_dlacpy( 'A', n, n, hl, nl, h, ldh )
                                 
                    end if
                 end if
              end if
              ! ==== clear out the trash, if necessary. ====
              if( ( wantt .or. info/=0_${ik}$ ) .and. n>2_${ik}$ )call stdlib${ii}$_dlaset( 'L', n-2, n-2, zero, zero,&
                         h( 3_${ik}$, 1_${ik}$ ), ldh )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = max( real( max( 1_${ik}$, n ),KIND=dp), work( 1_${ik}$ ) )
           end if
     end subroutine stdlib${ii}$_dhseqr

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$hseqr( job, compz, n, ilo, ihi, h, ldh, wr, wi, z,ldz, work, lwork, info )
     !! DHSEQR: computes the eigenvalues of a Hessenberg matrix H
     !! and, optionally, the matrices T and Z from the Schur decomposition
     !! H = Z T Z**T, where T is an upper quasi-triangular matrix (the
     !! Schur form), and Z is the orthogonal matrix of Schur vectors.
     !! Optionally Z may be postmultiplied into an input orthogonal
     !! matrix Q so that this routine can give the Schur factorization
     !! of a matrix A which has been reduced to the Hessenberg form H
     !! by the orthogonal matrix Q:  A = Q*H*Q**T = (QZ)*T*(QZ)**T.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ihi, ilo, ldh, ldz, lwork, n
           integer(${ik}$), intent(out) :: info
           character, intent(in) :: compz, job
           ! Array Arguments 
           real(${rk}$), intent(inout) :: h(ldh,*), z(ldz,*)
           real(${rk}$), intent(out) :: wi(*), work(*), wr(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ntiny = 15_${ik}$
           integer(${ik}$), parameter :: nl = 49_${ik}$
           ! ==== matrices of order ntiny or smaller must be processed by
           ! .    stdlib${ii}$_${ri}$lahqr because of insufficient subdiagonal scratch space.
           ! .    (this is a hard limit.) ====
           
           ! ==== nl allocates some local workspace to help small matrices
           ! .    through a rare stdlib${ii}$_${ri}$lahqr failure.  nl > ntiny = 15 is
           ! .    required and nl <= nmin = stdlib${ii}$_ilaenv(ispec=12,...) is recom-
           ! .    mended.  (the default value of nmin is 75.)  using nl = 49
           ! .    allows up to six simultaneous shifts and a 16-by-16
           ! .    deflation window.  ====
           
           
           ! Local Arrays 
           real(${rk}$) :: hl(nl,nl), workl(nl)
           ! Local Scalars 
           integer(${ik}$) :: i, kbot, nmin
           logical(lk) :: initz, lquery, wantt, wantz
           ! Intrinsic Functions 
           ! Executable Statements 
           ! ==== decode and check the input parameters. ====
           wantt = stdlib_lsame( job, 'S' )
           initz = stdlib_lsame( compz, 'I' )
           wantz = initz .or. stdlib_lsame( compz, 'V' )
           work( 1_${ik}$ ) = real( max( 1_${ik}$, n ),KIND=${rk}$)
           lquery = lwork==-1_${ik}$
           info = 0_${ik}$
           if( .not.stdlib_lsame( job, 'E' ) .and. .not.wantt ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compz, 'N' ) .and. .not.wantz ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ilo<1_${ik}$ .or. ilo>max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ihi<min( ilo, n ) .or. ihi>n ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<max( 1_${ik}$, n ) ) ) then
              info = -11_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -13_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              ! ==== quick return in case of invalid argument. ====
              call stdlib${ii}$_xerbla( 'DHSEQR', -info )
              return
           else if( n==0_${ik}$ ) then
              ! ==== quick return in case n = 0; nothing to do. ====
              return
           else if( lquery ) then
              ! ==== quick return in case of a workspace query ====
              call stdlib${ii}$_${ri}$laqr0( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                        work, lwork, info )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = max( real( max( 1_${ik}$, n ),KIND=${rk}$), work( 1_${ik}$ ) )
              return
           else
              ! ==== copy eigenvalues isolated by stdlib${ii}$_${ri}$gebal ====
              do i = 1, ilo - 1
                 wr( i ) = h( i, i )
                 wi( i ) = zero
              end do
              do i = ihi + 1, n
                 wr( i ) = h( i, i )
                 wi( i ) = zero
              end do
              ! ==== initialize z, if requested ====
              if( initz )call stdlib${ii}$_${ri}$laset( 'A', n, n, zero, one, z, ldz )
              ! ==== quick return if possible ====
              if( ilo==ihi ) then
                 wr( ilo ) = h( ilo, ilo )
                 wi( ilo ) = zero
                 return
              end if
              ! ==== stdlib${ii}$_${ri}$lahqr/stdlib${ii}$_${ri}$laqr0 crossover point ====
              nmin = stdlib${ii}$_ilaenv( 12_${ik}$, 'DHSEQR', job( : 1_${ik}$ ) // compz( : 1_${ik}$ ), n,ilo, ihi, lwork )
                        
              nmin = max( ntiny, nmin )
              ! ==== stdlib${ii}$_${ri}$laqr0 for big matrices; stdlib${ii}$_${ri}$lahqr for small ones ====
              if( n>nmin ) then
                 call stdlib${ii}$_${ri}$laqr0( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                           work, lwork, info )
              else
                 ! ==== small matrix ====
                 call stdlib${ii}$_${ri}$lahqr( wantt, wantz, n, ilo, ihi, h, ldh, wr, wi, ilo,ihi, z, ldz, &
                           info )
                 if( info>0_${ik}$ ) then
                    ! ==== a rare stdlib${ii}$_${ri}$lahqr failure!  stdlib${ii}$_${ri}$laqr0 sometimes succeeds
                    ! .    when stdlib${ii}$_${ri}$lahqr fails. ====
                    kbot = info
                    if( n>=nl ) then
                       ! ==== larger matrices have enough subdiagonal scratch
                       ! .    space to call stdlib${ii}$_${ri}$laqr0 directly. ====
                       call stdlib${ii}$_${ri}$laqr0( wantt, wantz, n, ilo, kbot, h, ldh, wr,wi, ilo, ihi, z,&
                                  ldz, work, lwork, info )
                    else
                       ! ==== tiny matrices don't have enough subdiagonal
                       ! .    scratch space to benefit from stdlib${ii}$_${ri}$laqr0.  hence,
                       ! .    tiny matrices must be copied into a larger
                       ! .    array before calling stdlib${ii}$_${ri}$laqr0. ====
                       call stdlib${ii}$_${ri}$lacpy( 'A', n, n, h, ldh, hl, nl )
                       hl( n+1, n ) = zero
                       call stdlib${ii}$_${ri}$laset( 'A', nl, nl-n, zero, zero, hl( 1_${ik}$, n+1 ),nl )
                       call stdlib${ii}$_${ri}$laqr0( wantt, wantz, nl, ilo, kbot, hl, nl, wr,wi, ilo, ihi, &
                                 z, ldz, workl, nl, info )
                       if( wantt .or. info/=0_${ik}$ )call stdlib${ii}$_${ri}$lacpy( 'A', n, n, hl, nl, h, ldh )
                                 
                    end if
                 end if
              end if
              ! ==== clear out the trash, if necessary. ====
              if( ( wantt .or. info/=0_${ik}$ ) .and. n>2_${ik}$ )call stdlib${ii}$_${ri}$laset( 'L', n-2, n-2, zero, zero,&
                         h( 3_${ik}$, 1_${ik}$ ), ldh )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = max( real( max( 1_${ik}$, n ),KIND=${rk}$), work( 1_${ik}$ ) )
           end if
     end subroutine stdlib${ii}$_${ri}$hseqr

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_chseqr( job, compz, n, ilo, ihi, h, ldh, w, z, ldz,work, lwork, info )
     !! CHSEQR computes the eigenvalues of a Hessenberg matrix H
     !! and, optionally, the matrices T and Z from the Schur decomposition
     !! H = Z T Z**H, where T is an upper triangular matrix (the
     !! Schur form), and Z is the unitary matrix of Schur vectors.
     !! Optionally Z may be postmultiplied into an input unitary
     !! matrix Q so that this routine can give the Schur factorization
     !! of a matrix A which has been reduced to the Hessenberg form H
     !! by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*T*(QZ)**H.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ihi, ilo, ldh, ldz, lwork, n
           integer(${ik}$), intent(out) :: info
           character, intent(in) :: compz, job
           ! Array Arguments 
           complex(sp), intent(inout) :: h(ldh,*), z(ldz,*)
           complex(sp), intent(out) :: w(*), work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ntiny = 15_${ik}$
           integer(${ik}$), parameter :: nl = 49_${ik}$
           ! ==== matrices of order ntiny or smaller must be processed by
           ! .    stdlib${ii}$_clahqr because of insufficient subdiagonal scratch space.
           ! .    (this is a hard limit.) ====
           
           ! ==== nl allocates some local workspace to help small matrices
           ! .    through a rare stdlib${ii}$_clahqr failure.  nl > ntiny = 15 is
           ! .    required and nl <= nmin = stdlib${ii}$_ilaenv(ispec=12,...) is recom-
           ! .    mended.  (the default value of nmin is 75.)  using nl = 49
           ! .    allows up to six simultaneous shifts and a 16-by-16
           ! .    deflation window.  ====
           
           
           
           ! Local Arrays 
           complex(sp) :: hl(nl,nl), workl(nl)
           ! Local Scalars 
           integer(${ik}$) :: kbot, nmin
           logical(lk) :: initz, lquery, wantt, wantz
           ! Intrinsic Functions 
           ! Executable Statements 
           ! ==== decode and check the input parameters. ====
           wantt = stdlib_lsame( job, 'S' )
           initz = stdlib_lsame( compz, 'I' )
           wantz = initz .or. stdlib_lsame( compz, 'V' )
           work( 1_${ik}$ ) = cmplx( real( max( 1_${ik}$, n ),KIND=sp), zero,KIND=sp)
           lquery = lwork==-1_${ik}$
           info = 0_${ik}$
           if( .not.stdlib_lsame( job, 'E' ) .and. .not.wantt ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compz, 'N' ) .and. .not.wantz ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ilo<1_${ik}$ .or. ilo>max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ihi<min( ilo, n ) .or. ihi>n ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<max( 1_${ik}$, n ) ) ) then
              info = -10_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              ! ==== quick return in case of invalid argument. ====
              call stdlib${ii}$_xerbla( 'CHSEQR', -info )
              return
           else if( n==0_${ik}$ ) then
              ! ==== quick return in case n = 0; nothing to do. ====
              return
           else if( lquery ) then
              ! ==== quick return in case of a workspace query ====
              call stdlib${ii}$_claqr0( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi, z,ldz, work, &
                        lwork, info )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = cmplx( max( real( work( 1_${ik}$ ),KIND=sp), real( max( 1_${ik}$,n ),KIND=sp) ), &
                        zero,KIND=sp)
              return
           else
              ! ==== copy eigenvalues isolated by stdlib${ii}$_cgebal ====
              if( ilo>1_${ik}$ )call stdlib${ii}$_ccopy( ilo-1, h, ldh+1, w, 1_${ik}$ )
              if( ihi<n )call stdlib${ii}$_ccopy( n-ihi, h( ihi+1, ihi+1 ), ldh+1, w( ihi+1 ), 1_${ik}$ )
                        
              ! ==== initialize z, if requested ====
              if( initz )call stdlib${ii}$_claset( 'A', n, n, czero, cone, z, ldz )
              ! ==== quick return if possible ====
              if( ilo==ihi ) then
                 w( ilo ) = h( ilo, ilo )
                 return
              end if
              ! ==== stdlib${ii}$_clahqr/stdlib${ii}$_claqr0 crossover point ====
              nmin = stdlib${ii}$_ilaenv( 12_${ik}$, 'CHSEQR', job( : 1_${ik}$ ) // compz( : 1_${ik}$ ), n,ilo, ihi, lwork )
                        
              nmin = max( ntiny, nmin )
              ! ==== stdlib${ii}$_claqr0 for big matrices; stdlib${ii}$_clahqr for small ones ====
              if( n>nmin ) then
                 call stdlib${ii}$_claqr0( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi,z, ldz, work, &
                           lwork, info )
              else
                 ! ==== small matrix ====
                 call stdlib${ii}$_clahqr( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi,z, ldz, info )
                           
                 if( info>0_${ik}$ ) then
                    ! ==== a rare stdlib${ii}$_clahqr failure!  stdlib${ii}$_claqr0 sometimes succeeds
                    ! .    when stdlib${ii}$_clahqr fails. ====
                    kbot = info
                    if( n>=nl ) then
                       ! ==== larger matrices have enough subdiagonal scratch
                       ! .    space to call stdlib${ii}$_claqr0 directly. ====
                       call stdlib${ii}$_claqr0( wantt, wantz, n, ilo, kbot, h, ldh, w,ilo, ihi, z, ldz,&
                                  work, lwork, info )
                    else
                       ! ==== tiny matrices don't have enough subdiagonal
                       ! .    scratch space to benefit from stdlib${ii}$_claqr0.  hence,
                       ! .    tiny matrices must be copied into a larger
                       ! .    array before calling stdlib${ii}$_claqr0. ====
                       call stdlib${ii}$_clacpy( 'A', n, n, h, ldh, hl, nl )
                       hl( n+1, n ) = czero
                       call stdlib${ii}$_claset( 'A', nl, nl-n, czero, czero, hl( 1_${ik}$, n+1 ),nl )
                       call stdlib${ii}$_claqr0( wantt, wantz, nl, ilo, kbot, hl, nl, w,ilo, ihi, z, &
                                 ldz, workl, nl, info )
                       if( wantt .or. info/=0_${ik}$ )call stdlib${ii}$_clacpy( 'A', n, n, hl, nl, h, ldh )
                                 
                    end if
                 end if
              end if
              ! ==== clear out the trash, if necessary. ====
              if( ( wantt .or. info/=0_${ik}$ ) .and. n>2_${ik}$ )call stdlib${ii}$_claset( 'L', n-2, n-2, czero, &
                        czero, h( 3_${ik}$, 1_${ik}$ ), ldh )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = cmplx( max( real( max( 1_${ik}$, n ),KIND=sp),real( work( 1_${ik}$ ),KIND=sp) ), &
                        zero,KIND=sp)
           end if
     end subroutine stdlib${ii}$_chseqr

     pure module subroutine stdlib${ii}$_zhseqr( job, compz, n, ilo, ihi, h, ldh, w, z, ldz,work, lwork, info )
     !! ZHSEQR computes the eigenvalues of a Hessenberg matrix H
     !! and, optionally, the matrices T and Z from the Schur decomposition
     !! H = Z T Z**H, where T is an upper triangular matrix (the
     !! Schur form), and Z is the unitary matrix of Schur vectors.
     !! Optionally Z may be postmultiplied into an input unitary
     !! matrix Q so that this routine can give the Schur factorization
     !! of a matrix A which has been reduced to the Hessenberg form H
     !! by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*T*(QZ)**H.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ihi, ilo, ldh, ldz, lwork, n
           integer(${ik}$), intent(out) :: info
           character, intent(in) :: compz, job
           ! Array Arguments 
           complex(dp), intent(inout) :: h(ldh,*), z(ldz,*)
           complex(dp), intent(out) :: w(*), work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ntiny = 15_${ik}$
           integer(${ik}$), parameter :: nl = 49_${ik}$
           ! ==== matrices of order ntiny or smaller must be processed by
           ! .    stdlib${ii}$_zlahqr because of insufficient subdiagonal scratch space.
           ! .    (this is a hard limit.) ====
           
           ! ==== nl allocates some local workspace to help small matrices
           ! .    through a rare stdlib${ii}$_zlahqr failure.  nl > ntiny = 15 is
           ! .    required and nl <= nmin = stdlib${ii}$_ilaenv(ispec=12,...) is recom-
           ! .    mended.  (the default value of nmin is 75.)  using nl = 49
           ! .    allows up to six simultaneous shifts and a 16-by-16
           ! .    deflation window.  ====
           
           
           
           ! Local Arrays 
           complex(dp) :: hl(nl,nl), workl(nl)
           ! Local Scalars 
           integer(${ik}$) :: kbot, nmin
           logical(lk) :: initz, lquery, wantt, wantz
           ! Intrinsic Functions 
           ! Executable Statements 
           ! ==== decode and check the input parameters. ====
           wantt = stdlib_lsame( job, 'S' )
           initz = stdlib_lsame( compz, 'I' )
           wantz = initz .or. stdlib_lsame( compz, 'V' )
           work( 1_${ik}$ ) = cmplx( real( max( 1_${ik}$, n ),KIND=dp), zero,KIND=dp)
           lquery = lwork==-1_${ik}$
           info = 0_${ik}$
           if( .not.stdlib_lsame( job, 'E' ) .and. .not.wantt ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compz, 'N' ) .and. .not.wantz ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ilo<1_${ik}$ .or. ilo>max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ihi<min( ilo, n ) .or. ihi>n ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<max( 1_${ik}$, n ) ) ) then
              info = -10_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              ! ==== quick return in case of invalid argument. ====
              call stdlib${ii}$_xerbla( 'ZHSEQR', -info )
              return
           else if( n==0_${ik}$ ) then
              ! ==== quick return in case n = 0; nothing to do. ====
              return
           else if( lquery ) then
              ! ==== quick return in case of a workspace query ====
              call stdlib${ii}$_zlaqr0( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi, z,ldz, work, &
                        lwork, info )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = cmplx( max( real( work( 1_${ik}$ ),KIND=dp), real( max( 1_${ik}$,n ),KIND=dp) ), &
                        zero,KIND=dp)
              return
           else
              ! ==== copy eigenvalues isolated by stdlib${ii}$_zgebal ====
              if( ilo>1_${ik}$ )call stdlib${ii}$_zcopy( ilo-1, h, ldh+1, w, 1_${ik}$ )
              if( ihi<n )call stdlib${ii}$_zcopy( n-ihi, h( ihi+1, ihi+1 ), ldh+1, w( ihi+1 ), 1_${ik}$ )
                        
              ! ==== initialize z, if requested ====
              if( initz )call stdlib${ii}$_zlaset( 'A', n, n, czero, cone, z, ldz )
              ! ==== quick return if possible ====
              if( ilo==ihi ) then
                 w( ilo ) = h( ilo, ilo )
                 return
              end if
              ! ==== stdlib${ii}$_zlahqr/stdlib${ii}$_zlaqr0 crossover point ====
              nmin = stdlib${ii}$_ilaenv( 12_${ik}$, 'ZHSEQR', job( : 1_${ik}$ ) // compz( : 1_${ik}$ ), n,ilo, ihi, lwork )
                        
              nmin = max( ntiny, nmin )
              ! ==== stdlib${ii}$_zlaqr0 for big matrices; stdlib${ii}$_zlahqr for small ones ====
              if( n>nmin ) then
                 call stdlib${ii}$_zlaqr0( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi,z, ldz, work, &
                           lwork, info )
              else
                 ! ==== small matrix ====
                 call stdlib${ii}$_zlahqr( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi,z, ldz, info )
                           
                 if( info>0_${ik}$ ) then
                    ! ==== a rare stdlib${ii}$_zlahqr failure!  stdlib${ii}$_zlaqr0 sometimes succeeds
                    ! .    when stdlib${ii}$_zlahqr fails. ====
                    kbot = info
                    if( n>=nl ) then
                       ! ==== larger matrices have enough subdiagonal scratch
                       ! .    space to call stdlib${ii}$_zlaqr0 directly. ====
                       call stdlib${ii}$_zlaqr0( wantt, wantz, n, ilo, kbot, h, ldh, w,ilo, ihi, z, ldz,&
                                  work, lwork, info )
                    else
                       ! ==== tiny matrices don't have enough subdiagonal
                       ! .    scratch space to benefit from stdlib${ii}$_zlaqr0.  hence,
                       ! .    tiny matrices must be copied into a larger
                       ! .    array before calling stdlib${ii}$_zlaqr0. ====
                       call stdlib${ii}$_zlacpy( 'A', n, n, h, ldh, hl, nl )
                       hl( n+1, n ) = czero
                       call stdlib${ii}$_zlaset( 'A', nl, nl-n, czero, czero, hl( 1_${ik}$, n+1 ),nl )
                       call stdlib${ii}$_zlaqr0( wantt, wantz, nl, ilo, kbot, hl, nl, w,ilo, ihi, z, &
                                 ldz, workl, nl, info )
                       if( wantt .or. info/=0_${ik}$ )call stdlib${ii}$_zlacpy( 'A', n, n, hl, nl, h, ldh )
                                 
                    end if
                 end if
              end if
              ! ==== clear out the trash, if necessary. ====
              if( ( wantt .or. info/=0_${ik}$ ) .and. n>2_${ik}$ )call stdlib${ii}$_zlaset( 'L', n-2, n-2, czero, &
                        czero, h( 3_${ik}$, 1_${ik}$ ), ldh )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = cmplx( max( real( max( 1_${ik}$, n ),KIND=dp),real( work( 1_${ik}$ ),KIND=dp) ), &
                        zero,KIND=dp)
           end if
     end subroutine stdlib${ii}$_zhseqr

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$hseqr( job, compz, n, ilo, ihi, h, ldh, w, z, ldz,work, lwork, info )
     !! ZHSEQR: computes the eigenvalues of a Hessenberg matrix H
     !! and, optionally, the matrices T and Z from the Schur decomposition
     !! H = Z T Z**H, where T is an upper triangular matrix (the
     !! Schur form), and Z is the unitary matrix of Schur vectors.
     !! Optionally Z may be postmultiplied into an input unitary
     !! matrix Q so that this routine can give the Schur factorization
     !! of a matrix A which has been reduced to the Hessenberg form H
     !! by the unitary matrix Q:  A = Q*H*Q**H = (QZ)*T*(QZ)**H.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ihi, ilo, ldh, ldz, lwork, n
           integer(${ik}$), intent(out) :: info
           character, intent(in) :: compz, job
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: h(ldh,*), z(ldz,*)
           complex(${ck}$), intent(out) :: w(*), work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ntiny = 15_${ik}$
           integer(${ik}$), parameter :: nl = 49_${ik}$
           ! ==== matrices of order ntiny or smaller must be processed by
           ! .    stdlib${ii}$_${ci}$lahqr because of insufficient subdiagonal scratch space.
           ! .    (this is a hard limit.) ====
           
           ! ==== nl allocates some local workspace to help small matrices
           ! .    through a rare stdlib${ii}$_${ci}$lahqr failure.  nl > ntiny = 15 is
           ! .    required and nl <= nmin = stdlib${ii}$_ilaenv(ispec=12,...) is recom-
           ! .    mended.  (the default value of nmin is 75.)  using nl = 49
           ! .    allows up to six simultaneous shifts and a 16-by-16
           ! .    deflation window.  ====
           
           
           
           ! Local Arrays 
           complex(${ck}$) :: hl(nl,nl), workl(nl)
           ! Local Scalars 
           integer(${ik}$) :: kbot, nmin
           logical(lk) :: initz, lquery, wantt, wantz
           ! Intrinsic Functions 
           ! Executable Statements 
           ! ==== decode and check the input parameters. ====
           wantt = stdlib_lsame( job, 'S' )
           initz = stdlib_lsame( compz, 'I' )
           wantz = initz .or. stdlib_lsame( compz, 'V' )
           work( 1_${ik}$ ) = cmplx( real( max( 1_${ik}$, n ),KIND=${ck}$), zero,KIND=${ck}$)
           lquery = lwork==-1_${ik}$
           info = 0_${ik}$
           if( .not.stdlib_lsame( job, 'E' ) .and. .not.wantt ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compz, 'N' ) .and. .not.wantz ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ilo<1_${ik}$ .or. ilo>max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ihi<min( ilo, n ) .or. ihi>n ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<max( 1_${ik}$, n ) ) ) then
              info = -10_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              ! ==== quick return in case of invalid argument. ====
              call stdlib${ii}$_xerbla( 'ZHSEQR', -info )
              return
           else if( n==0_${ik}$ ) then
              ! ==== quick return in case n = 0; nothing to do. ====
              return
           else if( lquery ) then
              ! ==== quick return in case of a workspace query ====
              call stdlib${ii}$_${ci}$laqr0( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi, z,ldz, work, &
                        lwork, info )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = cmplx( max( real( work( 1_${ik}$ ),KIND=${ck}$), real( max( 1_${ik}$,n ),KIND=${ck}$) ), &
                        zero,KIND=${ck}$)
              return
           else
              ! ==== copy eigenvalues isolated by stdlib${ii}$_${ci}$gebal ====
              if( ilo>1_${ik}$ )call stdlib${ii}$_${ci}$copy( ilo-1, h, ldh+1, w, 1_${ik}$ )
              if( ihi<n )call stdlib${ii}$_${ci}$copy( n-ihi, h( ihi+1, ihi+1 ), ldh+1, w( ihi+1 ), 1_${ik}$ )
                        
              ! ==== initialize z, if requested ====
              if( initz )call stdlib${ii}$_${ci}$laset( 'A', n, n, czero, cone, z, ldz )
              ! ==== quick return if possible ====
              if( ilo==ihi ) then
                 w( ilo ) = h( ilo, ilo )
                 return
              end if
              ! ==== stdlib${ii}$_${ci}$lahqr/stdlib${ii}$_${ci}$laqr0 crossover point ====
              nmin = stdlib${ii}$_ilaenv( 12_${ik}$, 'ZHSEQR', job( : 1_${ik}$ ) // compz( : 1_${ik}$ ), n,ilo, ihi, lwork )
                        
              nmin = max( ntiny, nmin )
              ! ==== stdlib${ii}$_${ci}$laqr0 for big matrices; stdlib${ii}$_${ci}$lahqr for small ones ====
              if( n>nmin ) then
                 call stdlib${ii}$_${ci}$laqr0( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi,z, ldz, work, &
                           lwork, info )
              else
                 ! ==== small matrix ====
                 call stdlib${ii}$_${ci}$lahqr( wantt, wantz, n, ilo, ihi, h, ldh, w, ilo, ihi,z, ldz, info )
                           
                 if( info>0_${ik}$ ) then
                    ! ==== a rare stdlib${ii}$_${ci}$lahqr failure!  stdlib${ii}$_${ci}$laqr0 sometimes succeeds
                    ! .    when stdlib${ii}$_${ci}$lahqr fails. ====
                    kbot = info
                    if( n>=nl ) then
                       ! ==== larger matrices have enough subdiagonal scratch
                       ! .    space to call stdlib${ii}$_${ci}$laqr0 directly. ====
                       call stdlib${ii}$_${ci}$laqr0( wantt, wantz, n, ilo, kbot, h, ldh, w,ilo, ihi, z, ldz,&
                                  work, lwork, info )
                    else
                       ! ==== tiny matrices don't have enough subdiagonal
                       ! .    scratch space to benefit from stdlib${ii}$_${ci}$laqr0.  hence,
                       ! .    tiny matrices must be copied into a larger
                       ! .    array before calling stdlib${ii}$_${ci}$laqr0. ====
                       call stdlib${ii}$_${ci}$lacpy( 'A', n, n, h, ldh, hl, nl )
                       hl( n+1, n ) = czero
                       call stdlib${ii}$_${ci}$laset( 'A', nl, nl-n, czero, czero, hl( 1_${ik}$, n+1 ),nl )
                       call stdlib${ii}$_${ci}$laqr0( wantt, wantz, nl, ilo, kbot, hl, nl, w,ilo, ihi, z, &
                                 ldz, workl, nl, info )
                       if( wantt .or. info/=0_${ik}$ )call stdlib${ii}$_${ci}$lacpy( 'A', n, n, hl, nl, h, ldh )
                                 
                    end if
                 end if
              end if
              ! ==== clear out the trash, if necessary. ====
              if( ( wantt .or. info/=0_${ik}$ ) .and. n>2_${ik}$ )call stdlib${ii}$_${ci}$laset( 'L', n-2, n-2, czero, &
                        czero, h( 3_${ik}$, 1_${ik}$ ), ldh )
              ! ==== ensure reported workspace size is backward-compatible with
              ! .    previous lapack versions. ====
              work( 1_${ik}$ ) = cmplx( max( real( max( 1_${ik}$, n ),KIND=${ck}$),real( work( 1_${ik}$ ),KIND=${ck}$) ), &
                        zero,KIND=${ck}$)
           end if
     end subroutine stdlib${ii}$_${ci}$hseqr

#:endif
#:endfor



     module subroutine stdlib${ii}$_shsein( side, eigsrc, initv, select, n, h, ldh, wr, wi,vl, ldvl, vr, ldvr, &
     !! SHSEIN uses inverse iteration to find specified right and/or left
     !! eigenvectors of a real upper Hessenberg matrix H.
     !! The right eigenvector x and the left eigenvector y of the matrix H
     !! corresponding to an eigenvalue w are defined by:
     !! H * x = w * x,     y**h * H = w * y**h
     !! where y**h denotes the conjugate transpose of the vector y.
               mm, m, work, ifaill,ifailr, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: eigsrc, initv, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldh, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           integer(${ik}$), intent(out) :: ifaill(*), ifailr(*)
           real(sp), intent(in) :: h(ldh,*), wi(*)
           real(sp), intent(inout) :: vl(ldvl,*), vr(ldvr,*), wr(*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: bothv, fromqr, leftv, noinit, pair, rightv
           integer(${ik}$) :: i, iinfo, k, kl, kln, kr, ksi, ksr, ldwork
           real(sp) :: bignum, eps3, hnorm, smlnum, ulp, unfl, wki, wkr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           fromqr = stdlib_lsame( eigsrc, 'Q' )
           noinit = stdlib_lsame( initv, 'N' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors, and standardize the array select.
           m = 0_${ik}$
           pair = .false.
           do k = 1, n
              if( pair ) then
                 pair = .false.
                 select( k ) = .false.
              else
                 if( wi( k )==zero ) then
                    if( select( k ) )m = m + 1_${ik}$
                 else
                    pair = .true.
                    if( select( k ) .or. select( k+1 ) ) then
                       select( k ) = .true.
                       m = m + 2_${ik}$
                    end if
                 end if
              end if
           end do
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.fromqr .and. .not.stdlib_lsame( eigsrc, 'N' ) ) then
              info = -2_${ik}$
           else if( .not.noinit .and. .not.stdlib_lsame( initv, 'U' ) ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -11_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -13_${ik}$
           else if( mm<m ) then
              info = -14_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SHSEIN', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set machine-dependent constants.
           unfl = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ulp = stdlib${ii}$_slamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ldwork = n + 1_${ik}$
           kl = 1_${ik}$
           kln = 0_${ik}$
           if( fromqr ) then
              kr = 0_${ik}$
           else
              kr = n
           end if
           ksr = 1_${ik}$
           loop_120: do k = 1, n
              if( select( k ) ) then
                 ! compute eigenvector(s) corresponding to w(k).
                 if( fromqr ) then
                    ! if affiliation of eigenvalues is known, check whether
                    ! the matrix splits.
                    ! determine kl and kr such that 1 <= kl <= k <= kr <= n
                    ! and h(kl,kl-1) and h(kr+1,kr) are zero (or kl = 1 or
                    ! kr = n).
                    ! then inverse iteration can be performed with the
                    ! submatrix h(kl:n,kl:n) for a left eigenvector, and with
                    ! the submatrix h(1:kr,1:kr) for a right eigenvector.
                    do i = k, kl + 1, -1
                       if( h( i, i-1 )==zero )go to 30
                    end do
                    30 continue
                    kl = i
                    if( k>kr ) then
                       do i = k, n - 1
                          if( h( i+1, i )==zero )go to 50
                       end do
                       50 continue
                       kr = i
                    end if
                 end if
                 if( kl/=kln ) then
                    kln = kl
                    ! compute infinity-norm of submatrix h(kl:kr,kl:kr) if it
                    ! has not ben computed before.
                    hnorm = stdlib${ii}$_slanhs( 'I', kr-kl+1, h( kl, kl ), ldh, work )
                    if( stdlib${ii}$_sisnan( hnorm ) ) then
                       info = -6_${ik}$
                       return
                    else if( hnorm>zero ) then
                       eps3 = hnorm*ulp
                    else
                       eps3 = smlnum
                    end if
                 end if
                 ! perturb eigenvalue if it is close to any previous
                 ! selected eigenvalues affiliated to the submatrix
                 ! h(kl:kr,kl:kr). close roots are modified by eps3.
                 wkr = wr( k )
                 wki = wi( k )
                 60 continue
                 do i = k - 1, kl, -1
                    if( select( i ) .and. abs( wr( i )-wkr )+abs( wi( i )-wki )<eps3 ) &
                              then
                       wkr = wkr + eps3
                       go to 60
                    end if
                 end do
                 wr( k ) = wkr
                 pair = wki/=zero
                 if( pair ) then
                    ksi = ksr + 1_${ik}$
                 else
                    ksi = ksr
                 end if
                 if( leftv ) then
                    ! compute left eigenvector.
                    call stdlib${ii}$_slaein( .false., noinit, n-kl+1, h( kl, kl ), ldh,wkr, wki, vl( &
                    kl, ksr ), vl( kl, ksi ),work, ldwork, work( n*n+n+1 ), eps3, smlnum,bignum, &
                              iinfo )
                    if( iinfo>0_${ik}$ ) then
                       if( pair ) then
                          info = info + 2_${ik}$
                       else
                          info = info + 1_${ik}$
                       end if
                       ifaill( ksr ) = k
                       ifaill( ksi ) = k
                    else
                       ifaill( ksr ) = 0_${ik}$
                       ifaill( ksi ) = 0_${ik}$
                    end if
                    do i = 1, kl - 1
                       vl( i, ksr ) = zero
                    end do
                    if( pair ) then
                       do i = 1, kl - 1
                          vl( i, ksi ) = zero
                       end do
                    end if
                 end if
                 if( rightv ) then
                    ! compute right eigenvector.
                    call stdlib${ii}$_slaein( .true., noinit, kr, h, ldh, wkr, wki,vr( 1_${ik}$, ksr ), vr( 1_${ik}$, &
                              ksi ), work, ldwork,work( n*n+n+1 ), eps3, smlnum, bignum,iinfo )
                    if( iinfo>0_${ik}$ ) then
                       if( pair ) then
                          info = info + 2_${ik}$
                       else
                          info = info + 1_${ik}$
                       end if
                       ifailr( ksr ) = k
                       ifailr( ksi ) = k
                    else
                       ifailr( ksr ) = 0_${ik}$
                       ifailr( ksi ) = 0_${ik}$
                    end if
                    do i = kr + 1, n
                       vr( i, ksr ) = zero
                    end do
                    if( pair ) then
                       do i = kr + 1, n
                          vr( i, ksi ) = zero
                       end do
                    end if
                 end if
                 if( pair ) then
                    ksr = ksr + 2_${ik}$
                 else
                    ksr = ksr + 1_${ik}$
                 end if
              end if
           end do loop_120
           return
     end subroutine stdlib${ii}$_shsein

     module subroutine stdlib${ii}$_dhsein( side, eigsrc, initv, select, n, h, ldh, wr, wi,vl, ldvl, vr, ldvr, &
     !! DHSEIN uses inverse iteration to find specified right and/or left
     !! eigenvectors of a real upper Hessenberg matrix H.
     !! The right eigenvector x and the left eigenvector y of the matrix H
     !! corresponding to an eigenvalue w are defined by:
     !! H * x = w * x,     y**h * H = w * y**h
     !! where y**h denotes the conjugate transpose of the vector y.
               mm, m, work, ifaill,ifailr, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: eigsrc, initv, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldh, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           integer(${ik}$), intent(out) :: ifaill(*), ifailr(*)
           real(dp), intent(in) :: h(ldh,*), wi(*)
           real(dp), intent(inout) :: vl(ldvl,*), vr(ldvr,*), wr(*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: bothv, fromqr, leftv, noinit, pair, rightv
           integer(${ik}$) :: i, iinfo, k, kl, kln, kr, ksi, ksr, ldwork
           real(dp) :: bignum, eps3, hnorm, smlnum, ulp, unfl, wki, wkr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           fromqr = stdlib_lsame( eigsrc, 'Q' )
           noinit = stdlib_lsame( initv, 'N' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors, and standardize the array select.
           m = 0_${ik}$
           pair = .false.
           do k = 1, n
              if( pair ) then
                 pair = .false.
                 select( k ) = .false.
              else
                 if( wi( k )==zero ) then
                    if( select( k ) )m = m + 1_${ik}$
                 else
                    pair = .true.
                    if( select( k ) .or. select( k+1 ) ) then
                       select( k ) = .true.
                       m = m + 2_${ik}$
                    end if
                 end if
              end if
           end do
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.fromqr .and. .not.stdlib_lsame( eigsrc, 'N' ) ) then
              info = -2_${ik}$
           else if( .not.noinit .and. .not.stdlib_lsame( initv, 'U' ) ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -11_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -13_${ik}$
           else if( mm<m ) then
              info = -14_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DHSEIN', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set machine-dependent constants.
           unfl = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ulp = stdlib${ii}$_dlamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ldwork = n + 1_${ik}$
           kl = 1_${ik}$
           kln = 0_${ik}$
           if( fromqr ) then
              kr = 0_${ik}$
           else
              kr = n
           end if
           ksr = 1_${ik}$
           loop_120: do k = 1, n
              if( select( k ) ) then
                 ! compute eigenvector(s) corresponding to w(k).
                 if( fromqr ) then
                    ! if affiliation of eigenvalues is known, check whether
                    ! the matrix splits.
                    ! determine kl and kr such that 1 <= kl <= k <= kr <= n
                    ! and h(kl,kl-1) and h(kr+1,kr) are zero (or kl = 1 or
                    ! kr = n).
                    ! then inverse iteration can be performed with the
                    ! submatrix h(kl:n,kl:n) for a left eigenvector, and with
                    ! the submatrix h(1:kr,1:kr) for a right eigenvector.
                    do i = k, kl + 1, -1
                       if( h( i, i-1 )==zero )go to 30
                    end do
                    30 continue
                    kl = i
                    if( k>kr ) then
                       do i = k, n - 1
                          if( h( i+1, i )==zero )go to 50
                       end do
                       50 continue
                       kr = i
                    end if
                 end if
                 if( kl/=kln ) then
                    kln = kl
                    ! compute infinity-norm of submatrix h(kl:kr,kl:kr) if it
                    ! has not ben computed before.
                    hnorm = stdlib${ii}$_dlanhs( 'I', kr-kl+1, h( kl, kl ), ldh, work )
                    if( stdlib${ii}$_disnan( hnorm ) ) then
                       info = -6_${ik}$
                       return
                    else if( hnorm>zero ) then
                       eps3 = hnorm*ulp
                    else
                       eps3 = smlnum
                    end if
                 end if
                 ! perturb eigenvalue if it is close to any previous
                 ! selected eigenvalues affiliated to the submatrix
                 ! h(kl:kr,kl:kr). close roots are modified by eps3.
                 wkr = wr( k )
                 wki = wi( k )
                 60 continue
                 do i = k - 1, kl, -1
                    if( select( i ) .and. abs( wr( i )-wkr )+abs( wi( i )-wki )<eps3 ) &
                              then
                       wkr = wkr + eps3
                       go to 60
                    end if
                 end do
                 wr( k ) = wkr
                 pair = wki/=zero
                 if( pair ) then
                    ksi = ksr + 1_${ik}$
                 else
                    ksi = ksr
                 end if
                 if( leftv ) then
                    ! compute left eigenvector.
                    call stdlib${ii}$_dlaein( .false., noinit, n-kl+1, h( kl, kl ), ldh,wkr, wki, vl( &
                    kl, ksr ), vl( kl, ksi ),work, ldwork, work( n*n+n+1 ), eps3, smlnum,bignum, &
                              iinfo )
                    if( iinfo>0_${ik}$ ) then
                       if( pair ) then
                          info = info + 2_${ik}$
                       else
                          info = info + 1_${ik}$
                       end if
                       ifaill( ksr ) = k
                       ifaill( ksi ) = k
                    else
                       ifaill( ksr ) = 0_${ik}$
                       ifaill( ksi ) = 0_${ik}$
                    end if
                    do i = 1, kl - 1
                       vl( i, ksr ) = zero
                    end do
                    if( pair ) then
                       do i = 1, kl - 1
                          vl( i, ksi ) = zero
                       end do
                    end if
                 end if
                 if( rightv ) then
                    ! compute right eigenvector.
                    call stdlib${ii}$_dlaein( .true., noinit, kr, h, ldh, wkr, wki,vr( 1_${ik}$, ksr ), vr( 1_${ik}$, &
                              ksi ), work, ldwork,work( n*n+n+1 ), eps3, smlnum, bignum,iinfo )
                    if( iinfo>0_${ik}$ ) then
                       if( pair ) then
                          info = info + 2_${ik}$
                       else
                          info = info + 1_${ik}$
                       end if
                       ifailr( ksr ) = k
                       ifailr( ksi ) = k
                    else
                       ifailr( ksr ) = 0_${ik}$
                       ifailr( ksi ) = 0_${ik}$
                    end if
                    do i = kr + 1, n
                       vr( i, ksr ) = zero
                    end do
                    if( pair ) then
                       do i = kr + 1, n
                          vr( i, ksi ) = zero
                       end do
                    end if
                 end if
                 if( pair ) then
                    ksr = ksr + 2_${ik}$
                 else
                    ksr = ksr + 1_${ik}$
                 end if
              end if
           end do loop_120
           return
     end subroutine stdlib${ii}$_dhsein

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$hsein( side, eigsrc, initv, select, n, h, ldh, wr, wi,vl, ldvl, vr, ldvr, &
     !! DHSEIN: uses inverse iteration to find specified right and/or left
     !! eigenvectors of a real upper Hessenberg matrix H.
     !! The right eigenvector x and the left eigenvector y of the matrix H
     !! corresponding to an eigenvalue w are defined by:
     !! H * x = w * x,     y**h * H = w * y**h
     !! where y**h denotes the conjugate transpose of the vector y.
               mm, m, work, ifaill,ifailr, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: eigsrc, initv, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldh, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           integer(${ik}$), intent(out) :: ifaill(*), ifailr(*)
           real(${rk}$), intent(in) :: h(ldh,*), wi(*)
           real(${rk}$), intent(inout) :: vl(ldvl,*), vr(ldvr,*), wr(*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: bothv, fromqr, leftv, noinit, pair, rightv
           integer(${ik}$) :: i, iinfo, k, kl, kln, kr, ksi, ksr, ldwork
           real(${rk}$) :: bignum, eps3, hnorm, smlnum, ulp, unfl, wki, wkr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           fromqr = stdlib_lsame( eigsrc, 'Q' )
           noinit = stdlib_lsame( initv, 'N' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors, and standardize the array select.
           m = 0_${ik}$
           pair = .false.
           do k = 1, n
              if( pair ) then
                 pair = .false.
                 select( k ) = .false.
              else
                 if( wi( k )==zero ) then
                    if( select( k ) )m = m + 1_${ik}$
                 else
                    pair = .true.
                    if( select( k ) .or. select( k+1 ) ) then
                       select( k ) = .true.
                       m = m + 2_${ik}$
                    end if
                 end if
              end if
           end do
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.fromqr .and. .not.stdlib_lsame( eigsrc, 'N' ) ) then
              info = -2_${ik}$
           else if( .not.noinit .and. .not.stdlib_lsame( initv, 'U' ) ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -11_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -13_${ik}$
           else if( mm<m ) then
              info = -14_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DHSEIN', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set machine-dependent constants.
           unfl = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           ulp = stdlib${ii}$_${ri}$lamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ldwork = n + 1_${ik}$
           kl = 1_${ik}$
           kln = 0_${ik}$
           if( fromqr ) then
              kr = 0_${ik}$
           else
              kr = n
           end if
           ksr = 1_${ik}$
           loop_120: do k = 1, n
              if( select( k ) ) then
                 ! compute eigenvector(s) corresponding to w(k).
                 if( fromqr ) then
                    ! if affiliation of eigenvalues is known, check whether
                    ! the matrix splits.
                    ! determine kl and kr such that 1 <= kl <= k <= kr <= n
                    ! and h(kl,kl-1) and h(kr+1,kr) are zero (or kl = 1 or
                    ! kr = n).
                    ! then inverse iteration can be performed with the
                    ! submatrix h(kl:n,kl:n) for a left eigenvector, and with
                    ! the submatrix h(1:kr,1:kr) for a right eigenvector.
                    do i = k, kl + 1, -1
                       if( h( i, i-1 )==zero )go to 30
                    end do
                    30 continue
                    kl = i
                    if( k>kr ) then
                       do i = k, n - 1
                          if( h( i+1, i )==zero )go to 50
                       end do
                       50 continue
                       kr = i
                    end if
                 end if
                 if( kl/=kln ) then
                    kln = kl
                    ! compute infinity-norm of submatrix h(kl:kr,kl:kr) if it
                    ! has not ben computed before.
                    hnorm = stdlib${ii}$_${ri}$lanhs( 'I', kr-kl+1, h( kl, kl ), ldh, work )
                    if( stdlib${ii}$_${ri}$isnan( hnorm ) ) then
                       info = -6_${ik}$
                       return
                    else if( hnorm>zero ) then
                       eps3 = hnorm*ulp
                    else
                       eps3 = smlnum
                    end if
                 end if
                 ! perturb eigenvalue if it is close to any previous
                 ! selected eigenvalues affiliated to the submatrix
                 ! h(kl:kr,kl:kr). close roots are modified by eps3.
                 wkr = wr( k )
                 wki = wi( k )
                 60 continue
                 do i = k - 1, kl, -1
                    if( select( i ) .and. abs( wr( i )-wkr )+abs( wi( i )-wki )<eps3 ) &
                              then
                       wkr = wkr + eps3
                       go to 60
                    end if
                 end do
                 wr( k ) = wkr
                 pair = wki/=zero
                 if( pair ) then
                    ksi = ksr + 1_${ik}$
                 else
                    ksi = ksr
                 end if
                 if( leftv ) then
                    ! compute left eigenvector.
                    call stdlib${ii}$_${ri}$laein( .false., noinit, n-kl+1, h( kl, kl ), ldh,wkr, wki, vl( &
                    kl, ksr ), vl( kl, ksi ),work, ldwork, work( n*n+n+1 ), eps3, smlnum,bignum, &
                              iinfo )
                    if( iinfo>0_${ik}$ ) then
                       if( pair ) then
                          info = info + 2_${ik}$
                       else
                          info = info + 1_${ik}$
                       end if
                       ifaill( ksr ) = k
                       ifaill( ksi ) = k
                    else
                       ifaill( ksr ) = 0_${ik}$
                       ifaill( ksi ) = 0_${ik}$
                    end if
                    do i = 1, kl - 1
                       vl( i, ksr ) = zero
                    end do
                    if( pair ) then
                       do i = 1, kl - 1
                          vl( i, ksi ) = zero
                       end do
                    end if
                 end if
                 if( rightv ) then
                    ! compute right eigenvector.
                    call stdlib${ii}$_${ri}$laein( .true., noinit, kr, h, ldh, wkr, wki,vr( 1_${ik}$, ksr ), vr( 1_${ik}$, &
                              ksi ), work, ldwork,work( n*n+n+1 ), eps3, smlnum, bignum,iinfo )
                    if( iinfo>0_${ik}$ ) then
                       if( pair ) then
                          info = info + 2_${ik}$
                       else
                          info = info + 1_${ik}$
                       end if
                       ifailr( ksr ) = k
                       ifailr( ksi ) = k
                    else
                       ifailr( ksr ) = 0_${ik}$
                       ifailr( ksi ) = 0_${ik}$
                    end if
                    do i = kr + 1, n
                       vr( i, ksr ) = zero
                    end do
                    if( pair ) then
                       do i = kr + 1, n
                          vr( i, ksi ) = zero
                       end do
                    end if
                 end if
                 if( pair ) then
                    ksr = ksr + 2_${ik}$
                 else
                    ksr = ksr + 1_${ik}$
                 end if
              end if
           end do loop_120
           return
     end subroutine stdlib${ii}$_${ri}$hsein

#:endif
#:endfor

     module subroutine stdlib${ii}$_chsein( side, eigsrc, initv, select, n, h, ldh, w, vl,ldvl, vr, ldvr, mm, &
     !! CHSEIN uses inverse iteration to find specified right and/or left
     !! eigenvectors of a complex upper Hessenberg matrix H.
     !! The right eigenvector x and the left eigenvector y of the matrix H
     !! corresponding to an eigenvalue w are defined by:
     !! H * x = w * x,     y**h * H = w * y**h
     !! where y**h denotes the conjugate transpose of the vector y.
               m, work, rwork, ifaill,ifailr, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: eigsrc, initv, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldh, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: ifaill(*), ifailr(*)
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(in) :: h(ldh,*)
           complex(sp), intent(inout) :: vl(ldvl,*), vr(ldvr,*), w(*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           
           ! Local Scalars 
           logical(lk) :: bothv, fromqr, leftv, noinit, rightv
           integer(${ik}$) :: i, iinfo, k, kl, kln, kr, ks, ldwork
           real(sp) :: eps3, hnorm, smlnum, ulp, unfl
           complex(sp) :: cdum, wk
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=sp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters.
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           fromqr = stdlib_lsame( eigsrc, 'Q' )
           noinit = stdlib_lsame( initv, 'N' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           m = 0_${ik}$
           do k = 1, n
              if( select( k ) )m = m + 1_${ik}$
           end do
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.fromqr .and. .not.stdlib_lsame( eigsrc, 'N' ) ) then
              info = -2_${ik}$
           else if( .not.noinit .and. .not.stdlib_lsame( initv, 'U' ) ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -10_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -12_${ik}$
           else if( mm<m ) then
              info = -13_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CHSEIN', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set machine-dependent constants.
           unfl = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ulp = stdlib${ii}$_slamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ldwork = n
           kl = 1_${ik}$
           kln = 0_${ik}$
           if( fromqr ) then
              kr = 0_${ik}$
           else
              kr = n
           end if
           ks = 1_${ik}$
           loop_100: do k = 1, n
              if( select( k ) ) then
                 ! compute eigenvector(s) corresponding to w(k).
                 if( fromqr ) then
                    ! if affiliation of eigenvalues is known, check whether
                    ! the matrix splits.
                    ! determine kl and kr such that 1 <= kl <= k <= kr <= n
                    ! and h(kl,kl-1) and h(kr+1,kr) are czero (or kl = 1 or
                    ! kr = n).
                    ! then inverse iteration can be performed with the
                    ! submatrix h(kl:n,kl:n) for a left eigenvector, and with
                    ! the submatrix h(1:kr,1:kr) for a right eigenvector.
                    do i = k, kl + 1, -1
                       if( h( i, i-1 )==czero )go to 30
                    end do
                    30 continue
                    kl = i
                    if( k>kr ) then
                       do i = k, n - 1
                          if( h( i+1, i )==czero )go to 50
                       end do
                       50 continue
                       kr = i
                    end if
                 end if
                 if( kl/=kln ) then
                    kln = kl
                    ! compute infinity-norm of submatrix h(kl:kr,kl:kr) if it
                    ! has not ben computed before.
                    hnorm = stdlib${ii}$_clanhs( 'I', kr-kl+1, h( kl, kl ), ldh, rwork )
                    if( stdlib${ii}$_sisnan( hnorm ) ) then
                       info = -6_${ik}$
                       return
                    else if( (hnorm>zero) ) then
                       eps3 = hnorm*ulp
                    else
                       eps3 = smlnum
                    end if
                 end if
                 ! perturb eigenvalue if it is close to any previous
                 ! selected eigenvalues affiliated to the submatrix
                 ! h(kl:kr,kl:kr). close roots are modified by eps3.
                 wk = w( k )
                 60 continue
                 do i = k - 1, kl, -1
                    if( select( i ) .and. cabs1( w( i )-wk )<eps3 ) then
                       wk = wk + eps3
                       go to 60
                    end if
                 end do
                 w( k ) = wk
                 if( leftv ) then
                    ! compute left eigenvector.
                    call stdlib${ii}$_claein( .false., noinit, n-kl+1, h( kl, kl ), ldh,wk, vl( kl, ks )&
                              , work, ldwork, rwork, eps3,smlnum, iinfo )
                    if( iinfo>0_${ik}$ ) then
                       info = info + 1_${ik}$
                       ifaill( ks ) = k
                    else
                       ifaill( ks ) = 0_${ik}$
                    end if
                    do i = 1, kl - 1
                       vl( i, ks ) = czero
                    end do
                 end if
                 if( rightv ) then
                    ! compute right eigenvector.
                    call stdlib${ii}$_claein( .true., noinit, kr, h, ldh, wk, vr( 1_${ik}$, ks ),work, ldwork, &
                              rwork, eps3, smlnum, iinfo )
                    if( iinfo>0_${ik}$ ) then
                       info = info + 1_${ik}$
                       ifailr( ks ) = k
                    else
                       ifailr( ks ) = 0_${ik}$
                    end if
                    do i = kr + 1, n
                       vr( i, ks ) = czero
                    end do
                 end if
                 ks = ks + 1_${ik}$
              end if
           end do loop_100
           return
     end subroutine stdlib${ii}$_chsein

     module subroutine stdlib${ii}$_zhsein( side, eigsrc, initv, select, n, h, ldh, w, vl,ldvl, vr, ldvr, mm, &
     !! ZHSEIN uses inverse iteration to find specified right and/or left
     !! eigenvectors of a complex upper Hessenberg matrix H.
     !! The right eigenvector x and the left eigenvector y of the matrix H
     !! corresponding to an eigenvalue w are defined by:
     !! H * x = w * x,     y**h * H = w * y**h
     !! where y**h denotes the conjugate transpose of the vector y.
               m, work, rwork, ifaill,ifailr, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: eigsrc, initv, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldh, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: ifaill(*), ifailr(*)
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(in) :: h(ldh,*)
           complex(dp), intent(inout) :: vl(ldvl,*), vr(ldvr,*), w(*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           
           ! Local Scalars 
           logical(lk) :: bothv, fromqr, leftv, noinit, rightv
           integer(${ik}$) :: i, iinfo, k, kl, kln, kr, ks, ldwork
           real(dp) :: eps3, hnorm, smlnum, ulp, unfl
           complex(dp) :: cdum, wk
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=dp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters.
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           fromqr = stdlib_lsame( eigsrc, 'Q' )
           noinit = stdlib_lsame( initv, 'N' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           m = 0_${ik}$
           do k = 1, n
              if( select( k ) )m = m + 1_${ik}$
           end do
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.fromqr .and. .not.stdlib_lsame( eigsrc, 'N' ) ) then
              info = -2_${ik}$
           else if( .not.noinit .and. .not.stdlib_lsame( initv, 'U' ) ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -10_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -12_${ik}$
           else if( mm<m ) then
              info = -13_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZHSEIN', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set machine-dependent constants.
           unfl = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ulp = stdlib${ii}$_dlamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ldwork = n
           kl = 1_${ik}$
           kln = 0_${ik}$
           if( fromqr ) then
              kr = 0_${ik}$
           else
              kr = n
           end if
           ks = 1_${ik}$
           loop_100: do k = 1, n
              if( select( k ) ) then
                 ! compute eigenvector(s) corresponding to w(k).
                 if( fromqr ) then
                    ! if affiliation of eigenvalues is known, check whether
                    ! the matrix splits.
                    ! determine kl and kr such that 1 <= kl <= k <= kr <= n
                    ! and h(kl,kl-1) and h(kr+1,kr) are czero (or kl = 1 or
                    ! kr = n).
                    ! then inverse iteration can be performed with the
                    ! submatrix h(kl:n,kl:n) for a left eigenvector, and with
                    ! the submatrix h(1:kr,1:kr) for a right eigenvector.
                    do i = k, kl + 1, -1
                       if( h( i, i-1 )==czero )go to 30
                    end do
                    30 continue
                    kl = i
                    if( k>kr ) then
                       do i = k, n - 1
                          if( h( i+1, i )==czero )go to 50
                       end do
                       50 continue
                       kr = i
                    end if
                 end if
                 if( kl/=kln ) then
                    kln = kl
                    ! compute infinity-norm of submatrix h(kl:kr,kl:kr) if it
                    ! has not ben computed before.
                    hnorm = stdlib${ii}$_zlanhs( 'I', kr-kl+1, h( kl, kl ), ldh, rwork )
                    if( stdlib${ii}$_disnan( hnorm ) ) then
                       info = -6_${ik}$
                       return
                    else if( hnorm>zero ) then
                       eps3 = hnorm*ulp
                    else
                       eps3 = smlnum
                    end if
                 end if
                 ! perturb eigenvalue if it is close to any previous
                 ! selected eigenvalues affiliated to the submatrix
                 ! h(kl:kr,kl:kr). close roots are modified by eps3.
                 wk = w( k )
                 60 continue
                 do i = k - 1, kl, -1
                    if( select( i ) .and. cabs1( w( i )-wk )<eps3 ) then
                       wk = wk + eps3
                       go to 60
                    end if
                 end do
                 w( k ) = wk
                 if( leftv ) then
                    ! compute left eigenvector.
                    call stdlib${ii}$_zlaein( .false., noinit, n-kl+1, h( kl, kl ), ldh,wk, vl( kl, ks )&
                              , work, ldwork, rwork, eps3,smlnum, iinfo )
                    if( iinfo>0_${ik}$ ) then
                       info = info + 1_${ik}$
                       ifaill( ks ) = k
                    else
                       ifaill( ks ) = 0_${ik}$
                    end if
                    do i = 1, kl - 1
                       vl( i, ks ) = czero
                    end do
                 end if
                 if( rightv ) then
                    ! compute right eigenvector.
                    call stdlib${ii}$_zlaein( .true., noinit, kr, h, ldh, wk, vr( 1_${ik}$, ks ),work, ldwork, &
                              rwork, eps3, smlnum, iinfo )
                    if( iinfo>0_${ik}$ ) then
                       info = info + 1_${ik}$
                       ifailr( ks ) = k
                    else
                       ifailr( ks ) = 0_${ik}$
                    end if
                    do i = kr + 1, n
                       vr( i, ks ) = czero
                    end do
                 end if
                 ks = ks + 1_${ik}$
              end if
           end do loop_100
           return
     end subroutine stdlib${ii}$_zhsein

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     module subroutine stdlib${ii}$_${ci}$hsein( side, eigsrc, initv, select, n, h, ldh, w, vl,ldvl, vr, ldvr, mm, &
     !! ZHSEIN: uses inverse iteration to find specified right and/or left
     !! eigenvectors of a complex upper Hessenberg matrix H.
     !! The right eigenvector x and the left eigenvector y of the matrix H
     !! corresponding to an eigenvalue w are defined by:
     !! H * x = w * x,     y**h * H = w * y**h
     !! where y**h denotes the conjugate transpose of the vector y.
               m, work, rwork, ifaill,ifailr, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: eigsrc, initv, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldh, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: ifaill(*), ifailr(*)
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(in) :: h(ldh,*)
           complex(${ck}$), intent(inout) :: vl(ldvl,*), vr(ldvr,*), w(*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           
           ! Local Scalars 
           logical(lk) :: bothv, fromqr, leftv, noinit, rightv
           integer(${ik}$) :: i, iinfo, k, kl, kln, kr, ks, ldwork
           real(${ck}$) :: eps3, hnorm, smlnum, ulp, unfl
           complex(${ck}$) :: cdum, wk
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=${ck}$) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters.
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           fromqr = stdlib_lsame( eigsrc, 'Q' )
           noinit = stdlib_lsame( initv, 'N' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           m = 0_${ik}$
           do k = 1, n
              if( select( k ) )m = m + 1_${ik}$
           end do
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.fromqr .and. .not.stdlib_lsame( eigsrc, 'N' ) ) then
              info = -2_${ik}$
           else if( .not.noinit .and. .not.stdlib_lsame( initv, 'U' ) ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( ldh<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -10_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -12_${ik}$
           else if( mm<m ) then
              info = -13_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZHSEIN', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set machine-dependent constants.
           unfl = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           ulp = stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ldwork = n
           kl = 1_${ik}$
           kln = 0_${ik}$
           if( fromqr ) then
              kr = 0_${ik}$
           else
              kr = n
           end if
           ks = 1_${ik}$
           loop_100: do k = 1, n
              if( select( k ) ) then
                 ! compute eigenvector(s) corresponding to w(k).
                 if( fromqr ) then
                    ! if affiliation of eigenvalues is known, check whether
                    ! the matrix splits.
                    ! determine kl and kr such that 1 <= kl <= k <= kr <= n
                    ! and h(kl,kl-1) and h(kr+1,kr) are czero (or kl = 1 or
                    ! kr = n).
                    ! then inverse iteration can be performed with the
                    ! submatrix h(kl:n,kl:n) for a left eigenvector, and with
                    ! the submatrix h(1:kr,1:kr) for a right eigenvector.
                    do i = k, kl + 1, -1
                       if( h( i, i-1 )==czero )go to 30
                    end do
                    30 continue
                    kl = i
                    if( k>kr ) then
                       do i = k, n - 1
                          if( h( i+1, i )==czero )go to 50
                       end do
                       50 continue
                       kr = i
                    end if
                 end if
                 if( kl/=kln ) then
                    kln = kl
                    ! compute infinity-norm of submatrix h(kl:kr,kl:kr) if it
                    ! has not ben computed before.
                    hnorm = stdlib${ii}$_${ci}$lanhs( 'I', kr-kl+1, h( kl, kl ), ldh, rwork )
                    if( stdlib${ii}$_${c2ri(ci)}$isnan( hnorm ) ) then
                       info = -6_${ik}$
                       return
                    else if( hnorm>zero ) then
                       eps3 = hnorm*ulp
                    else
                       eps3 = smlnum
                    end if
                 end if
                 ! perturb eigenvalue if it is close to any previous
                 ! selected eigenvalues affiliated to the submatrix
                 ! h(kl:kr,kl:kr). close roots are modified by eps3.
                 wk = w( k )
                 60 continue
                 do i = k - 1, kl, -1
                    if( select( i ) .and. cabs1( w( i )-wk )<eps3 ) then
                       wk = wk + eps3
                       go to 60
                    end if
                 end do
                 w( k ) = wk
                 if( leftv ) then
                    ! compute left eigenvector.
                    call stdlib${ii}$_${ci}$laein( .false., noinit, n-kl+1, h( kl, kl ), ldh,wk, vl( kl, ks )&
                              , work, ldwork, rwork, eps3,smlnum, iinfo )
                    if( iinfo>0_${ik}$ ) then
                       info = info + 1_${ik}$
                       ifaill( ks ) = k
                    else
                       ifaill( ks ) = 0_${ik}$
                    end if
                    do i = 1, kl - 1
                       vl( i, ks ) = czero
                    end do
                 end if
                 if( rightv ) then
                    ! compute right eigenvector.
                    call stdlib${ii}$_${ci}$laein( .true., noinit, kr, h, ldh, wk, vr( 1_${ik}$, ks ),work, ldwork, &
                              rwork, eps3, smlnum, iinfo )
                    if( iinfo>0_${ik}$ ) then
                       info = info + 1_${ik}$
                       ifailr( ks ) = k
                    else
                       ifailr( ks ) = 0_${ik}$
                    end if
                    do i = kr + 1, n
                       vr( i, ks ) = czero
                    end do
                 end if
                 ks = ks + 1_${ik}$
              end if
           end do loop_100
           return
     end subroutine stdlib${ii}$_${ci}$hsein

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_strevc( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! STREVC computes some or all of the right and/or left eigenvectors of
     !! a real upper quasi-triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a real general matrix:  A = Q*T*Q**T, as computed by SHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal blocks of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix.  If Q is the orthogonal factor that reduces a matrix
     !! A to Schur form T, then Q*X and Q*Y are the matrices of right and
     !! left eigenvectors of A.
               work, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           real(sp), intent(in) :: t(ldt,*)
           real(sp), intent(inout) :: vl(ldvl,*), vr(ldvr,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, over, pair, rightv, somev
           integer(${ik}$) :: i, ierr, ii, ip, is, j, j1, j2, jnxt, k, ki, n2
           real(sp) :: beta, bignum, emax, ovfl, rec, remax, scale, smin, smlnum, ulp, unfl, &
                     vcrit, vmax, wi, wr, xnorm
           ! Intrinsic Functions 
           ! Local Arrays 
           real(sp) :: x(2_${ik}$,2_${ik}$)
           ! Executable Statements 
           ! decode and test the input parameters
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           allv = stdlib_lsame( howmny, 'A' )
           over = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else
              ! set m to the number of columns required to store the selected
              ! eigenvectors, standardize the array select if necessary, and
              ! test mm.
              if( somev ) then
                 m = 0_${ik}$
                 pair = .false.
                 do j = 1, n
                    if( pair ) then
                       pair = .false.
                       select( j ) = .false.
                    else
                       if( j<n ) then
                          if( t( j+1, j )==zero ) then
                             if( select( j ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( j ) .or. select( j+1 ) ) then
                                select( j ) = .true.
                                m = m + 2_${ik}$
                             end if
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -11_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'STREVC', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_slabad( unfl, ovfl )
           ulp = stdlib${ii}$_slamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           work( 1_${ik}$ ) = zero
           do j = 2, n
              work( j ) = zero
              do i = 1, j - 1
                 work( j ) = work( j ) + abs( t( i, j ) )
              end do
           end do
           ! index ip is used to specify the real or complex eigenvalue:
             ! ip = 0, real eigenvalue,
                  ! 1, first of conjugate complex pair: (wr,wi)
                 ! -1, second of conjugate complex pair: (wr,wi)
           n2 = 2_${ik}$*n
           if( rightv ) then
              ! compute right eigenvectors.
              ip = 0_${ik}$
              is = m
              loop_140: do ki = n, 1, -1
                 if( ip==1 )go to 130
                 if( ki==1 )go to 40
                 if( t( ki, ki-1 )==zero )go to 40
                 ip = -1_${ik}$
                 40 continue
                 if( somev ) then
                    if( ip==0_${ik}$ ) then
                       if( .not.select( ki ) )go to 130
                    else
                       if( .not.select( ki-1 ) )go to 130
                    end if
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki-1 ) ) )*sqrt( abs( t( ki-1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! real right eigenvector
                    work( ki+n ) = one
                    ! form right-hand side
                    do k = 1, ki - 1
                       work( k+n ) = -t( k, ki )
                    end do
                    ! solve the upper quasi-triangular system:
                       ! (t(1:ki-1,1:ki-1) - wr)*x = scale*work.
                    jnxt = ki - 1_${ik}$
                    loop_60: do j = ki - 1, 1, -1
                       if( j>jnxt )cycle loop_60
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1 = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_saxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_slaln2( .false., 2_${ik}$, 1_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+n ), n, wr, zero, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x(1,1) and x(2,1) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                          work( j-1+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n ) = x( 2_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_saxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_60
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_scopy( ki, work( 1_${ik}$+n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                       remax = one / abs( vr( ii, is ) )
                       call stdlib${ii}$_sscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is ) = zero
                       end do
                    else
                       if( ki>1_${ik}$ )call stdlib${ii}$_sgemv( 'N', n, ki-1, one, vr, ldvr,work( 1_${ik}$+n ), 1_${ik}$, &
                                 work( ki+n ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vr( ii, ki ) )
                       call stdlib${ii}$_sscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 else
                    ! complex right eigenvector.
                    ! initial solve
                      ! [ (t(ki-1,ki-1) t(ki-1,ki) ) - (wr + i* wi)]*x = 0.
                      ! [ (t(ki,ki-1)   t(ki,ki)   )               ]
                    if( abs( t( ki-1, ki ) )>=abs( t( ki, ki-1 ) ) ) then
                       work( ki-1+n ) = one
                       work( ki+n2 ) = wi / t( ki-1, ki )
                    else
                       work( ki-1+n ) = -wi / t( ki, ki-1 )
                       work( ki+n2 ) = one
                    end if
                    work( ki+n ) = zero
                    work( ki-1+n2 ) = zero
                    ! form right-hand side
                    do k = 1, ki - 2
                       work( k+n ) = -work( ki-1+n )*t( k, ki-1 )
                       work( k+n2 ) = -work( ki+n2 )*t( k, ki )
                    end do
                    ! solve upper quasi-triangular system:
                    ! (t(1:ki-2,1:ki-2) - (wr+i*wi))*x = scale*(work+i*work2)
                    jnxt = ki - 2_${ik}$
                    loop_90: do j = ki - 2, 1, -1
                       if( j>jnxt )cycle loop_90
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1 = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr, wi,x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) and x(1,2) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_saxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-1, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_slaln2( .false., 2_${ik}$, 2_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+n ), n, wr, wi, x, 2_${ik}$, scale,xnorm, ierr )
                          ! scale x to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                rec = one / xnorm
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )*rec
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )*rec
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ )*rec
                                x( 2_${ik}$, 2_${ik}$ ) = x( 2_${ik}$, 2_${ik}$ )*rec
                                scale = scale*rec
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+n2 ), 1_${ik}$ )
                          end if
                          work( j-1+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j-1+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+n2 ) = x( 2_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_saxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-2, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-2, -x( 2_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                       end if
                    end do loop_90
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_scopy( ki, work( 1_${ik}$+n ), 1_${ik}$, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_scopy( ki, work( 1_${ik}$+n2 ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       emax = zero
                       do k = 1, ki
                          emax = max( emax, abs( vr( k, is-1 ) )+abs( vr( k, is ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( ki, remax, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is-1 ) = zero
                          vr( k, is ) = zero
                       end do
                    else
                       if( ki>2_${ik}$ ) then
                          call stdlib${ii}$_sgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$+n ), 1_${ik}$, work( ki-&
                                    1_${ik}$+n ),vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                          call stdlib${ii}$_sgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$+n2 ), 1_${ik}$, work( &
                                    ki+n2 ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_sscal( n, work( ki-1+n ), vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                          call stdlib${ii}$_sscal( n, work( ki+n2 ), vr( 1_${ik}$, ki ), 1_${ik}$ )
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vr( k, ki-1 ) )+abs( vr( k, ki ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( n, remax, vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 end if
                 is = is - 1_${ik}$
                 if( ip/=0_${ik}$ )is = is - 1_${ik}$
                 130 continue
                 if( ip==1_${ik}$ )ip = 0_${ik}$
                 if( ip==-1_${ik}$ )ip = 1_${ik}$
              end do loop_140
           end if
           if( leftv ) then
              ! compute left eigenvectors.
              ip = 0_${ik}$
              is = 1_${ik}$
              loop_260: do ki = 1, n
                 if( ip==-1 )go to 250
                 if( ki==n )go to 150
                 if( t( ki+1, ki )==zero )go to 150
                 ip = 1_${ik}$
                 150 continue
                 if( somev ) then
                    if( .not.select( ki ) )go to 250
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki+1 ) ) )*sqrt( abs( t( ki+1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! real left eigenvector.
                    work( ki+n ) = one
                    ! form right-hand side
                    do k = ki + 1, n
                       work( k+n ) = -t( ki, k )
                    end do
                    ! solve the quasi-triangular system:
                       ! (t(ki+1:n,ki+1:n) - wr)**t*x = scale*work
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 1_${ik}$
                    loop_170: do j = ki + 1, n
                       if( j<jnxt )cycle loop_170
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_sdot( j-ki-1, t( ki+1, j ), 1_${ik}$,work( &
                                    ki+1+n ), 1_${ik}$ )
                          ! solve (t(j,j)-wr)**t*x = work
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                                    
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+n ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_sdot( j-ki-1, t( ki+1, j ), 1_${ik}$,work( &
                                    ki+1+n ), 1_${ik}$ )
                          work( j+1+n ) = work( j+1+n ) -stdlib${ii}$_sdot( j-ki-1, t( ki+1, j+1 ), 1_${ik}$,&
                                    work( ki+1+n ), 1_${ik}$ )
                          ! solve
                            ! [t(j,j)-wr   t(j,j+1)     ]**t* x = scale*( work1 )
                            ! [t(j+1,j)    t(j+1,j+1)-wr]               ( work2 )
                          call stdlib${ii}$_slaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                                    
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+1+n ) = x( 2_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+n ) ),abs( work( j+1+n ) ), vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_170
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_scopy( n-ki+1, work( ki+n ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                       remax = one / abs( vl( ii, is ) )
                       call stdlib${ii}$_sscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                       end do
                    else
                       if( ki<n )call stdlib${ii}$_sgemv( 'N', n, n-ki, one, vl( 1_${ik}$, ki+1 ), ldvl,work( &
                                 ki+1+n ), 1_${ik}$, work( ki+n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vl( ii, ki ) )
                       call stdlib${ii}$_sscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 else
                    ! complex left eigenvector.
                     ! initial solve:
                       ! ((t(ki,ki)    t(ki,ki+1) )**t - (wr - i* wi))*x = 0.
                       ! ((t(ki+1,ki) t(ki+1,ki+1))                )
                    if( abs( t( ki, ki+1 ) )>=abs( t( ki+1, ki ) ) ) then
                       work( ki+n ) = wi / t( ki, ki+1 )
                       work( ki+1+n2 ) = one
                    else
                       work( ki+n ) = one
                       work( ki+1+n2 ) = -wi / t( ki+1, ki )
                    end if
                    work( ki+1+n ) = zero
                    work( ki+n2 ) = zero
                    ! form right-hand side
                    do k = ki + 2, n
                       work( k+n ) = -work( ki+n )*t( ki, k )
                       work( k+n2 ) = -work( ki+1+n2 )*t( ki+1, k )
                    end do
                    ! solve complex quasi-triangular system:
                    ! ( t(ki+2,n:ki+2,n) - (wr-i*wi) )*x = work1+i*work2
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 2_${ik}$
                    loop_200: do j = ki + 2, n
                       if( j<jnxt )cycle loop_200
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when
                          ! forming the right-hand side elements.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+n2 ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n ), 1_${ik}$ )
                          work( j+n2 ) = work( j+n2 ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n2 ), 1_${ik}$ )
                          ! solve (t(j,j)-(wr-i*wi))*(x11+i*x12)= wk+i*wk2
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          vmax = max( abs( work( j+n ) ),abs( work( j+n2 ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side elements.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+n2 ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n ), 1_${ik}$ )
                          work( j+n2 ) = work( j+n2 ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n2 ), 1_${ik}$ )
                          work( j+1+n ) = work( j+1+n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j+1 ), 1_${ik}$,&
                                    work( ki+2+n ), 1_${ik}$ )
                          work( j+1+n2 ) = work( j+1+n2 ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j+1 ), 1_${ik}$,&
                                    work( ki+2+n2 ), 1_${ik}$ )
                          ! solve 2-by-2 complex linear equation
                            ! ([t(j,j)   t(j,j+1)  ]**t-(wr-i*wi)*i)*x = scale*b
                            ! ([t(j+1,j) t(j+1,j+1)]               )
                          call stdlib${ii}$_slaln2( .true., 2_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+1+n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j+1+n2 ) = x( 2_${ik}$, 2_${ik}$ )
                          vmax = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 1_${ik}$, 2_${ik}$ ) ),abs( x( 2_${ik}$, 1_${ik}$ ) ), abs( x(&
                                     2_${ik}$, 2_${ik}$ ) ), vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_200
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_scopy( n-ki+1, work( ki+n ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                       call stdlib${ii}$_scopy( n-ki+1, work( ki+n2 ), 1_${ik}$, vl( ki, is+1 ),1_${ik}$ )
                       emax = zero
                       do k = ki, n
                          emax = max( emax, abs( vl( k, is ) )+abs( vl( k, is+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( n-ki+1, remax, vl( ki, is+1 ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                          vl( k, is+1 ) = zero
                       end do
                    else
                       if( ki<n-1 ) then
                          call stdlib${ii}$_sgemv( 'N', n, n-ki-1, one, vl( 1_${ik}$, ki+2 ),ldvl, work( ki+2+&
                                    n ), 1_${ik}$, work( ki+n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_sgemv( 'N', n, n-ki-1, one, vl( 1_${ik}$, ki+2 ),ldvl, work( ki+2+&
                                    n2 ), 1_${ik}$,work( ki+1+n2 ), vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_sscal( n, work( ki+n ), vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_sscal( n, work( ki+1+n2 ), vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vl( k, ki ) )+abs( vl( k, ki+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( n, remax, vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                    end if
                 end if
                 is = is + 1_${ik}$
                 if( ip/=0_${ik}$ )is = is + 1_${ik}$
                 250 continue
                 if( ip==-1_${ik}$ )ip = 0_${ik}$
                 if( ip==1_${ik}$ )ip = -1_${ik}$
              end do loop_260
           end if
           return
     end subroutine stdlib${ii}$_strevc

     pure module subroutine stdlib${ii}$_dtrevc( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! DTREVC computes some or all of the right and/or left eigenvectors of
     !! a real upper quasi-triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal blocks of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix.  If Q is the orthogonal factor that reduces a matrix
     !! A to Schur form T, then Q*X and Q*Y are the matrices of right and
     !! left eigenvectors of A.
               work, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           real(dp), intent(in) :: t(ldt,*)
           real(dp), intent(inout) :: vl(ldvl,*), vr(ldvr,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, over, pair, rightv, somev
           integer(${ik}$) :: i, ierr, ii, ip, is, j, j1, j2, jnxt, k, ki, n2
           real(dp) :: beta, bignum, emax, ovfl, rec, remax, scale, smin, smlnum, ulp, unfl, &
                     vcrit, vmax, wi, wr, xnorm
           ! Intrinsic Functions 
           ! Local Arrays 
           real(dp) :: x(2_${ik}$,2_${ik}$)
           ! Executable Statements 
           ! decode and test the input parameters
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           allv = stdlib_lsame( howmny, 'A' )
           over = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else
              ! set m to the number of columns required to store the selected
              ! eigenvectors, standardize the array select if necessary, and
              ! test mm.
              if( somev ) then
                 m = 0_${ik}$
                 pair = .false.
                 do j = 1, n
                    if( pair ) then
                       pair = .false.
                       select( j ) = .false.
                    else
                       if( j<n ) then
                          if( t( j+1, j )==zero ) then
                             if( select( j ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( j ) .or. select( j+1 ) ) then
                                select( j ) = .true.
                                m = m + 2_${ik}$
                             end if
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -11_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTREVC', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_dlabad( unfl, ovfl )
           ulp = stdlib${ii}$_dlamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           work( 1_${ik}$ ) = zero
           do j = 2, n
              work( j ) = zero
              do i = 1, j - 1
                 work( j ) = work( j ) + abs( t( i, j ) )
              end do
           end do
           ! index ip is used to specify the real or complex eigenvalue:
             ! ip = 0, real eigenvalue,
                  ! 1, first of conjugate complex pair: (wr,wi)
                 ! -1, second of conjugate complex pair: (wr,wi)
           n2 = 2_${ik}$*n
           if( rightv ) then
              ! compute right eigenvectors.
              ip = 0_${ik}$
              is = m
              loop_140: do ki = n, 1, -1
                 if( ip==1 )go to 130
                 if( ki==1 )go to 40
                 if( t( ki, ki-1 )==zero )go to 40
                 ip = -1_${ik}$
                 40 continue
                 if( somev ) then
                    if( ip==0_${ik}$ ) then
                       if( .not.select( ki ) )go to 130
                    else
                       if( .not.select( ki-1 ) )go to 130
                    end if
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki-1 ) ) )*sqrt( abs( t( ki-1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! real right eigenvector
                    work( ki+n ) = one
                    ! form right-hand side
                    do k = 1, ki - 1
                       work( k+n ) = -t( k, ki )
                    end do
                    ! solve the upper quasi-triangular system:
                       ! (t(1:ki-1,1:ki-1) - wr)*x = scale*work.
                    jnxt = ki - 1_${ik}$
                    loop_60: do j = ki - 1, 1, -1
                       if( j>jnxt )cycle loop_60
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1 = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_daxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 1_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+n ), n, wr, zero, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x(1,1) and x(2,1) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                          work( j-1+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n ) = x( 2_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_daxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_60
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_dcopy( ki, work( 1_${ik}$+n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                       remax = one / abs( vr( ii, is ) )
                       call stdlib${ii}$_dscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is ) = zero
                       end do
                    else
                       if( ki>1_${ik}$ )call stdlib${ii}$_dgemv( 'N', n, ki-1, one, vr, ldvr,work( 1_${ik}$+n ), 1_${ik}$, &
                                 work( ki+n ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vr( ii, ki ) )
                       call stdlib${ii}$_dscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 else
                    ! complex right eigenvector.
                    ! initial solve
                      ! [ (t(ki-1,ki-1) t(ki-1,ki) ) - (wr + i* wi)]*x = 0.
                      ! [ (t(ki,ki-1)   t(ki,ki)   )               ]
                    if( abs( t( ki-1, ki ) )>=abs( t( ki, ki-1 ) ) ) then
                       work( ki-1+n ) = one
                       work( ki+n2 ) = wi / t( ki-1, ki )
                    else
                       work( ki-1+n ) = -wi / t( ki, ki-1 )
                       work( ki+n2 ) = one
                    end if
                    work( ki+n ) = zero
                    work( ki-1+n2 ) = zero
                    ! form right-hand side
                    do k = 1, ki - 2
                       work( k+n ) = -work( ki-1+n )*t( k, ki-1 )
                       work( k+n2 ) = -work( ki+n2 )*t( k, ki )
                    end do
                    ! solve upper quasi-triangular system:
                    ! (t(1:ki-2,1:ki-2) - (wr+i*wi))*x = scale*(work+i*work2)
                    jnxt = ki - 2_${ik}$
                    loop_90: do j = ki - 2, 1, -1
                       if( j>jnxt )cycle loop_90
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1 = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr, wi,x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) and x(1,2) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_daxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-1, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 2_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+n ), n, wr, wi, x, 2_${ik}$, scale,xnorm, ierr )
                          ! scale x to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                rec = one / xnorm
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )*rec
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )*rec
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ )*rec
                                x( 2_${ik}$, 2_${ik}$ ) = x( 2_${ik}$, 2_${ik}$ )*rec
                                scale = scale*rec
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+n2 ), 1_${ik}$ )
                          end if
                          work( j-1+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j-1+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+n2 ) = x( 2_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_daxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-2, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-2, -x( 2_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                       end if
                    end do loop_90
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_dcopy( ki, work( 1_${ik}$+n ), 1_${ik}$, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_dcopy( ki, work( 1_${ik}$+n2 ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       emax = zero
                       do k = 1, ki
                          emax = max( emax, abs( vr( k, is-1 ) )+abs( vr( k, is ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( ki, remax, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is-1 ) = zero
                          vr( k, is ) = zero
                       end do
                    else
                       if( ki>2_${ik}$ ) then
                          call stdlib${ii}$_dgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$+n ), 1_${ik}$, work( ki-&
                                    1_${ik}$+n ),vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                          call stdlib${ii}$_dgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$+n2 ), 1_${ik}$, work( &
                                    ki+n2 ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_dscal( n, work( ki-1+n ), vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                          call stdlib${ii}$_dscal( n, work( ki+n2 ), vr( 1_${ik}$, ki ), 1_${ik}$ )
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vr( k, ki-1 ) )+abs( vr( k, ki ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( n, remax, vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 end if
                 is = is - 1_${ik}$
                 if( ip/=0_${ik}$ )is = is - 1_${ik}$
                 130 continue
                 if( ip==1_${ik}$ )ip = 0_${ik}$
                 if( ip==-1_${ik}$ )ip = 1_${ik}$
              end do loop_140
           end if
           if( leftv ) then
              ! compute left eigenvectors.
              ip = 0_${ik}$
              is = 1_${ik}$
              loop_260: do ki = 1, n
                 if( ip==-1 )go to 250
                 if( ki==n )go to 150
                 if( t( ki+1, ki )==zero )go to 150
                 ip = 1_${ik}$
                 150 continue
                 if( somev ) then
                    if( .not.select( ki ) )go to 250
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki+1 ) ) )*sqrt( abs( t( ki+1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! real left eigenvector.
                    work( ki+n ) = one
                    ! form right-hand side
                    do k = ki + 1, n
                       work( k+n ) = -t( ki, k )
                    end do
                    ! solve the quasi-triangular system:
                       ! (t(ki+1:n,ki+1:n) - wr)**t*x = scale*work
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 1_${ik}$
                    loop_170: do j = ki + 1, n
                       if( j<jnxt )cycle loop_170
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_ddot( j-ki-1, t( ki+1, j ), 1_${ik}$,work( &
                                    ki+1+n ), 1_${ik}$ )
                          ! solve (t(j,j)-wr)**t*x = work
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                                    
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+n ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_ddot( j-ki-1, t( ki+1, j ), 1_${ik}$,work( &
                                    ki+1+n ), 1_${ik}$ )
                          work( j+1+n ) = work( j+1+n ) -stdlib${ii}$_ddot( j-ki-1, t( ki+1, j+1 ), 1_${ik}$,&
                                    work( ki+1+n ), 1_${ik}$ )
                          ! solve
                            ! [t(j,j)-wr   t(j,j+1)     ]**t * x = scale*( work1 )
                            ! [t(j+1,j)    t(j+1,j+1)-wr]                ( work2 )
                          call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                                    
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+1+n ) = x( 2_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+n ) ),abs( work( j+1+n ) ), vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_170
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_dcopy( n-ki+1, work( ki+n ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                       remax = one / abs( vl( ii, is ) )
                       call stdlib${ii}$_dscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                       end do
                    else
                       if( ki<n )call stdlib${ii}$_dgemv( 'N', n, n-ki, one, vl( 1_${ik}$, ki+1 ), ldvl,work( &
                                 ki+1+n ), 1_${ik}$, work( ki+n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vl( ii, ki ) )
                       call stdlib${ii}$_dscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 else
                    ! complex left eigenvector.
                     ! initial solve:
                       ! ((t(ki,ki)    t(ki,ki+1) )**t - (wr - i* wi))*x = 0.
                       ! ((t(ki+1,ki) t(ki+1,ki+1))                )
                    if( abs( t( ki, ki+1 ) )>=abs( t( ki+1, ki ) ) ) then
                       work( ki+n ) = wi / t( ki, ki+1 )
                       work( ki+1+n2 ) = one
                    else
                       work( ki+n ) = one
                       work( ki+1+n2 ) = -wi / t( ki+1, ki )
                    end if
                    work( ki+1+n ) = zero
                    work( ki+n2 ) = zero
                    ! form right-hand side
                    do k = ki + 2, n
                       work( k+n ) = -work( ki+n )*t( ki, k )
                       work( k+n2 ) = -work( ki+1+n2 )*t( ki+1, k )
                    end do
                    ! solve complex quasi-triangular system:
                    ! ( t(ki+2,n:ki+2,n) - (wr-i*wi) )*x = work1+i*work2
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 2_${ik}$
                    loop_200: do j = ki + 2, n
                       if( j<jnxt )cycle loop_200
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when
                          ! forming the right-hand side elements.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+n2 ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n ), 1_${ik}$ )
                          work( j+n2 ) = work( j+n2 ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n2 ), 1_${ik}$ )
                          ! solve (t(j,j)-(wr-i*wi))*(x11+i*x12)= wk+i*wk2
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          vmax = max( abs( work( j+n ) ),abs( work( j+n2 ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side elements.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+n2 ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n ), 1_${ik}$ )
                          work( j+n2 ) = work( j+n2 ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n2 ), 1_${ik}$ )
                          work( j+1+n ) = work( j+1+n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j+1 ), 1_${ik}$,&
                                    work( ki+2+n ), 1_${ik}$ )
                          work( j+1+n2 ) = work( j+1+n2 ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j+1 ), 1_${ik}$,&
                                    work( ki+2+n2 ), 1_${ik}$ )
                          ! solve 2-by-2 complex linear equation
                            ! ([t(j,j)   t(j,j+1)  ]**t-(wr-i*wi)*i)*x = scale*b
                            ! ([t(j+1,j) t(j+1,j+1)]               )
                          call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+1+n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j+1+n2 ) = x( 2_${ik}$, 2_${ik}$ )
                          vmax = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 1_${ik}$, 2_${ik}$ ) ),abs( x( 2_${ik}$, 1_${ik}$ ) ), abs( x(&
                                     2_${ik}$, 2_${ik}$ ) ), vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_200
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_dcopy( n-ki+1, work( ki+n ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                       call stdlib${ii}$_dcopy( n-ki+1, work( ki+n2 ), 1_${ik}$, vl( ki, is+1 ),1_${ik}$ )
                       emax = zero
                       do k = ki, n
                          emax = max( emax, abs( vl( k, is ) )+abs( vl( k, is+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( n-ki+1, remax, vl( ki, is+1 ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                          vl( k, is+1 ) = zero
                       end do
                    else
                       if( ki<n-1 ) then
                          call stdlib${ii}$_dgemv( 'N', n, n-ki-1, one, vl( 1_${ik}$, ki+2 ),ldvl, work( ki+2+&
                                    n ), 1_${ik}$, work( ki+n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_dgemv( 'N', n, n-ki-1, one, vl( 1_${ik}$, ki+2 ),ldvl, work( ki+2+&
                                    n2 ), 1_${ik}$,work( ki+1+n2 ), vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_dscal( n, work( ki+n ), vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_dscal( n, work( ki+1+n2 ), vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vl( k, ki ) )+abs( vl( k, ki+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( n, remax, vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                    end if
                 end if
                 is = is + 1_${ik}$
                 if( ip/=0_${ik}$ )is = is + 1_${ik}$
                 250 continue
                 if( ip==-1_${ik}$ )ip = 0_${ik}$
                 if( ip==1_${ik}$ )ip = -1_${ik}$
              end do loop_260
           end if
           return
     end subroutine stdlib${ii}$_dtrevc

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$trevc( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! DTREVC: computes some or all of the right and/or left eigenvectors of
     !! a real upper quasi-triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal blocks of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix.  If Q is the orthogonal factor that reduces a matrix
     !! A to Schur form T, then Q*X and Q*Y are the matrices of right and
     !! left eigenvectors of A.
               work, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           real(${rk}$), intent(in) :: t(ldt,*)
           real(${rk}$), intent(inout) :: vl(ldvl,*), vr(ldvr,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, over, pair, rightv, somev
           integer(${ik}$) :: i, ierr, ii, ip, is, j, j1, j2, jnxt, k, ki, n2
           real(${rk}$) :: beta, bignum, emax, ovfl, rec, remax, scale, smin, smlnum, ulp, unfl, &
                     vcrit, vmax, wi, wr, xnorm
           ! Intrinsic Functions 
           ! Local Arrays 
           real(${rk}$) :: x(2_${ik}$,2_${ik}$)
           ! Executable Statements 
           ! decode and test the input parameters
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           allv = stdlib_lsame( howmny, 'A' )
           over = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else
              ! set m to the number of columns required to store the selected
              ! eigenvectors, standardize the array select if necessary, and
              ! test mm.
              if( somev ) then
                 m = 0_${ik}$
                 pair = .false.
                 do j = 1, n
                    if( pair ) then
                       pair = .false.
                       select( j ) = .false.
                    else
                       if( j<n ) then
                          if( t( j+1, j )==zero ) then
                             if( select( j ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( j ) .or. select( j+1 ) ) then
                                select( j ) = .true.
                                m = m + 2_${ik}$
                             end if
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -11_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTREVC', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_${ri}$labad( unfl, ovfl )
           ulp = stdlib${ii}$_${ri}$lamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           work( 1_${ik}$ ) = zero
           do j = 2, n
              work( j ) = zero
              do i = 1, j - 1
                 work( j ) = work( j ) + abs( t( i, j ) )
              end do
           end do
           ! index ip is used to specify the real or complex eigenvalue:
             ! ip = 0, real eigenvalue,
                  ! 1, first of conjugate complex pair: (wr,wi)
                 ! -1, second of conjugate complex pair: (wr,wi)
           n2 = 2_${ik}$*n
           if( rightv ) then
              ! compute right eigenvectors.
              ip = 0_${ik}$
              is = m
              loop_140: do ki = n, 1, -1
                 if( ip==1 )go to 130
                 if( ki==1 )go to 40
                 if( t( ki, ki-1 )==zero )go to 40
                 ip = -1_${ik}$
                 40 continue
                 if( somev ) then
                    if( ip==0_${ik}$ ) then
                       if( .not.select( ki ) )go to 130
                    else
                       if( .not.select( ki-1 ) )go to 130
                    end if
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki-1 ) ) )*sqrt( abs( t( ki-1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! real right eigenvector
                    work( ki+n ) = one
                    ! form right-hand side
                    do k = 1, ki - 1
                       work( k+n ) = -t( k, ki )
                    end do
                    ! solve the upper quasi-triangular system:
                       ! (t(1:ki-1,1:ki-1) - wr)*x = scale*work.
                    jnxt = ki - 1_${ik}$
                    loop_60: do j = ki - 1, 1, -1
                       if( j>jnxt )cycle loop_60
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1 = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 1_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+n ), n, wr, zero, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x(1,1) and x(2,1) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                          work( j-1+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n ) = x( 2_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_60
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_${ri}$copy( ki, work( 1_${ik}$+n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                       remax = one / abs( vr( ii, is ) )
                       call stdlib${ii}$_${ri}$scal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is ) = zero
                       end do
                    else
                       if( ki>1_${ik}$ )call stdlib${ii}$_${ri}$gemv( 'N', n, ki-1, one, vr, ldvr,work( 1_${ik}$+n ), 1_${ik}$, &
                                 work( ki+n ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vr( ii, ki ) )
                       call stdlib${ii}$_${ri}$scal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 else
                    ! complex right eigenvector.
                    ! initial solve
                      ! [ (t(ki-1,ki-1) t(ki-1,ki) ) - (wr + i* wi)]*x = 0.
                      ! [ (t(ki,ki-1)   t(ki,ki)   )               ]
                    if( abs( t( ki-1, ki ) )>=abs( t( ki, ki-1 ) ) ) then
                       work( ki-1+n ) = one
                       work( ki+n2 ) = wi / t( ki-1, ki )
                    else
                       work( ki-1+n ) = -wi / t( ki, ki-1 )
                       work( ki+n2 ) = one
                    end if
                    work( ki+n ) = zero
                    work( ki-1+n2 ) = zero
                    ! form right-hand side
                    do k = 1, ki - 2
                       work( k+n ) = -work( ki-1+n )*t( k, ki-1 )
                       work( k+n2 ) = -work( ki+n2 )*t( k, ki )
                    end do
                    ! solve upper quasi-triangular system:
                    ! (t(1:ki-2,1:ki-2) - (wr+i*wi))*x = scale*(work+i*work2)
                    jnxt = ki - 2_${ik}$
                    loop_90: do j = ki - 2, 1, -1
                       if( j>jnxt )cycle loop_90
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1 = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr, wi,x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) and x(1,2) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-1, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 2_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+n ), n, wr, wi, x, 2_${ik}$, scale,xnorm, ierr )
                          ! scale x to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                rec = one / xnorm
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )*rec
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )*rec
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ )*rec
                                x( 2_${ik}$, 2_${ik}$ ) = x( 2_${ik}$, 2_${ik}$ )*rec
                                scale = scale*rec
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+n2 ), 1_${ik}$ )
                          end if
                          work( j-1+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j-1+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+n2 ) = x( 2_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 2_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+n2 ), 1_${ik}$ )
                                    
                       end if
                    end do loop_90
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_${ri}$copy( ki, work( 1_${ik}$+n ), 1_${ik}$, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$copy( ki, work( 1_${ik}$+n2 ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       emax = zero
                       do k = 1, ki
                          emax = max( emax, abs( vr( k, is-1 ) )+abs( vr( k, is ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( ki, remax, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is-1 ) = zero
                          vr( k, is ) = zero
                       end do
                    else
                       if( ki>2_${ik}$ ) then
                          call stdlib${ii}$_${ri}$gemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$+n ), 1_${ik}$, work( ki-&
                                    1_${ik}$+n ),vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                          call stdlib${ii}$_${ri}$gemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$+n2 ), 1_${ik}$, work( &
                                    ki+n2 ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_${ri}$scal( n, work( ki-1+n ), vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                          call stdlib${ii}$_${ri}$scal( n, work( ki+n2 ), vr( 1_${ik}$, ki ), 1_${ik}$ )
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vr( k, ki-1 ) )+abs( vr( k, ki ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( n, remax, vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 end if
                 is = is - 1_${ik}$
                 if( ip/=0_${ik}$ )is = is - 1_${ik}$
                 130 continue
                 if( ip==1_${ik}$ )ip = 0_${ik}$
                 if( ip==-1_${ik}$ )ip = 1_${ik}$
              end do loop_140
           end if
           if( leftv ) then
              ! compute left eigenvectors.
              ip = 0_${ik}$
              is = 1_${ik}$
              loop_260: do ki = 1, n
                 if( ip==-1 )go to 250
                 if( ki==n )go to 150
                 if( t( ki+1, ki )==zero )go to 150
                 ip = 1_${ik}$
                 150 continue
                 if( somev ) then
                    if( .not.select( ki ) )go to 250
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki+1 ) ) )*sqrt( abs( t( ki+1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! real left eigenvector.
                    work( ki+n ) = one
                    ! form right-hand side
                    do k = ki + 1, n
                       work( k+n ) = -t( ki, k )
                    end do
                    ! solve the quasi-triangular system:
                       ! (t(ki+1:n,ki+1:n) - wr)**t*x = scale*work
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 1_${ik}$
                    loop_170: do j = ki + 1, n
                       if( j<jnxt )cycle loop_170
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_${ri}$dot( j-ki-1, t( ki+1, j ), 1_${ik}$,work( &
                                    ki+1+n ), 1_${ik}$ )
                          ! solve (t(j,j)-wr)**t*x = work
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                                    
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+n ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_${ri}$dot( j-ki-1, t( ki+1, j ), 1_${ik}$,work( &
                                    ki+1+n ), 1_${ik}$ )
                          work( j+1+n ) = work( j+1+n ) -stdlib${ii}$_${ri}$dot( j-ki-1, t( ki+1, j+1 ), 1_${ik}$,&
                                    work( ki+1+n ), 1_${ik}$ )
                          ! solve
                            ! [t(j,j)-wr   t(j,j+1)     ]**t * x = scale*( work1 )
                            ! [t(j+1,j)    t(j+1,j+1)-wr]                ( work2 )
                          call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                                    
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+1+n ) = x( 2_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+n ) ),abs( work( j+1+n ) ), vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_170
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_${ri}$copy( n-ki+1, work( ki+n ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                       remax = one / abs( vl( ii, is ) )
                       call stdlib${ii}$_${ri}$scal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                       end do
                    else
                       if( ki<n )call stdlib${ii}$_${ri}$gemv( 'N', n, n-ki, one, vl( 1_${ik}$, ki+1 ), ldvl,work( &
                                 ki+1+n ), 1_${ik}$, work( ki+n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vl( ii, ki ) )
                       call stdlib${ii}$_${ri}$scal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    end if
                 else
                    ! complex left eigenvector.
                     ! initial solve:
                       ! ((t(ki,ki)    t(ki,ki+1) )**t - (wr - i* wi))*x = 0.
                       ! ((t(ki+1,ki) t(ki+1,ki+1))                )
                    if( abs( t( ki, ki+1 ) )>=abs( t( ki+1, ki ) ) ) then
                       work( ki+n ) = wi / t( ki, ki+1 )
                       work( ki+1+n2 ) = one
                    else
                       work( ki+n ) = one
                       work( ki+1+n2 ) = -wi / t( ki+1, ki )
                    end if
                    work( ki+1+n ) = zero
                    work( ki+n2 ) = zero
                    ! form right-hand side
                    do k = ki + 2, n
                       work( k+n ) = -work( ki+n )*t( ki, k )
                       work( k+n2 ) = -work( ki+1+n2 )*t( ki+1, k )
                    end do
                    ! solve complex quasi-triangular system:
                    ! ( t(ki+2,n:ki+2,n) - (wr-i*wi) )*x = work1+i*work2
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 2_${ik}$
                    loop_200: do j = ki + 2, n
                       if( j<jnxt )cycle loop_200
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when
                          ! forming the right-hand side elements.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+n2 ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n ), 1_${ik}$ )
                          work( j+n2 ) = work( j+n2 ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n2 ), 1_${ik}$ )
                          ! solve (t(j,j)-(wr-i*wi))*(x11+i*x12)= wk+i*wk2
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          vmax = max( abs( work( j+n ) ),abs( work( j+n2 ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side elements.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+n2 ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+n ) = work( j+n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n ), 1_${ik}$ )
                          work( j+n2 ) = work( j+n2 ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j ), 1_${ik}$,work( &
                                    ki+2+n2 ), 1_${ik}$ )
                          work( j+1+n ) = work( j+1+n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j+1 ), 1_${ik}$,&
                                    work( ki+2+n ), 1_${ik}$ )
                          work( j+1+n2 ) = work( j+1+n2 ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j+1 ), 1_${ik}$,&
                                    work( ki+2+n2 ), 1_${ik}$ )
                          ! solve 2-by-2 complex linear equation
                            ! ([t(j,j)   t(j,j+1)  ]**t-(wr-i*wi)*i)*x = scale*b
                            ! ([t(j+1,j) t(j+1,j+1)]               )
                          call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+n2 ), 1_${ik}$ )
                          end if
                          work( j+n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+n2 ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+1+n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j+1+n2 ) = x( 2_${ik}$, 2_${ik}$ )
                          vmax = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 1_${ik}$, 2_${ik}$ ) ),abs( x( 2_${ik}$, 1_${ik}$ ) ), abs( x(&
                                     2_${ik}$, 2_${ik}$ ) ), vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_200
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       call stdlib${ii}$_${ri}$copy( n-ki+1, work( ki+n ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$copy( n-ki+1, work( ki+n2 ), 1_${ik}$, vl( ki, is+1 ),1_${ik}$ )
                       emax = zero
                       do k = ki, n
                          emax = max( emax, abs( vl( k, is ) )+abs( vl( k, is+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n-ki+1, remax, vl( ki, is+1 ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                          vl( k, is+1 ) = zero
                       end do
                    else
                       if( ki<n-1 ) then
                          call stdlib${ii}$_${ri}$gemv( 'N', n, n-ki-1, one, vl( 1_${ik}$, ki+2 ),ldvl, work( ki+2+&
                                    n ), 1_${ik}$, work( ki+n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_${ri}$gemv( 'N', n, n-ki-1, one, vl( 1_${ik}$, ki+2 ),ldvl, work( ki+2+&
                                    n2 ), 1_${ik}$,work( ki+1+n2 ), vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_${ri}$scal( n, work( ki+n ), vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_${ri}$scal( n, work( ki+1+n2 ), vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vl( k, ki ) )+abs( vl( k, ki+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n, remax, vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                    end if
                 end if
                 is = is + 1_${ik}$
                 if( ip/=0_${ik}$ )is = is + 1_${ik}$
                 250 continue
                 if( ip==-1_${ik}$ )ip = 0_${ik}$
                 if( ip==1_${ik}$ )ip = -1_${ik}$
              end do loop_260
           end if
           return
     end subroutine stdlib${ii}$_${ri}$trevc

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_ctrevc( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! CTREVC computes some or all of the right and/or left eigenvectors of
     !! a complex upper triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a complex general matrix:  A = Q*T*Q**H, as computed by CHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix.  If Q is the unitary factor that reduces a matrix A to
     !! Schur form T, then Q*X and Q*Y are the matrices of right and left
     !! eigenvectors of A.
               work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(inout) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           complex(sp), parameter :: cmzero = (0.0e+0_sp,0.0e+0_sp)
           complex(sp), parameter :: cmone = (1.0e+0_sp,0.0e+0_sp)
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, over, rightv, somev
           integer(${ik}$) :: i, ii, is, j, k, ki
           real(sp) :: ovfl, remax, scale, smin, smlnum, ulp, unfl
           complex(sp) :: cdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=sp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           allv = stdlib_lsame( howmny, 'A' )
           over = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           if( somev ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CTREVC', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_slabad( unfl, ovfl )
           ulp = stdlib${ii}$_slamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ! store the diagonal elements of t in working array work.
           do i = 1, n
              work( i+n ) = t( i, i )
           end do
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           rwork( 1_${ik}$ ) = zero
           do j = 2, n
              rwork( j ) = stdlib${ii}$_scasum( j-1, t( 1_${ik}$, j ), 1_${ik}$ )
           end do
           if( rightv ) then
              ! compute right eigenvectors.
              is = m
              loop_80: do ki = n, 1, -1
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_80
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 work( 1_${ik}$ ) = cmone
                 ! form right-hand side.
                 do k = 1, ki - 1
                    work( k ) = -t( k, ki )
                 end do
                 ! solve the triangular system:
                    ! (t(1:ki-1,1:ki-1) - t(ki,ki))*x = scale*work.
                 do k = 1, ki - 1
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki>1_${ik}$ ) then
                    call stdlib${ii}$_clatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', 'Y',ki-1, t, ldt, &
                              work( 1_${ik}$ ), scale, rwork,info )
                    work( ki ) = scale
                 end if
                 ! copy the vector x or q*x to vr and normalize.
                 if( .not.over ) then
                    call stdlib${ii}$_ccopy( ki, work( 1_${ik}$ ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, is ) )
                    call stdlib${ii}$_csscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                    do k = ki + 1, n
                       vr( k, is ) = cmzero
                    end do
                 else
                    if( ki>1_${ik}$ )call stdlib${ii}$_cgemv( 'N', n, ki-1, cmone, vr, ldvr, work( 1_${ik}$ ),1_${ik}$, &
                              cmplx( scale,KIND=sp), vr( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, ki ) )
                    call stdlib${ii}$_csscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                 end if
                 ! set back the original diagonal elements of t.
                 do k = 1, ki - 1
                    t( k, k ) = work( k+n )
                 end do
                 is = is - 1_${ik}$
              end do loop_80
           end if
           if( leftv ) then
              ! compute left eigenvectors.
              is = 1_${ik}$
              loop_130: do ki = 1, n
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_130
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 work( n ) = cmone
                 ! form right-hand side.
                 do k = ki + 1, n
                    work( k ) = -conjg( t( ki, k ) )
                 end do
                 ! solve the triangular system:
                    ! (t(ki+1:n,ki+1:n) - t(ki,ki))**h*x = scale*work.
                 do k = ki + 1, n
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki<n ) then
                    call stdlib${ii}$_clatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT','Y', n-ki, t( &
                              ki+1, ki+1 ), ldt,work( ki+1 ), scale, rwork, info )
                    work( ki ) = scale
                 end if
                 ! copy the vector x or q*x to vl and normalize.
                 if( .not.over ) then
                    call stdlib${ii}$_ccopy( n-ki+1, work( ki ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                    remax = one / cabs1( vl( ii, is ) )
                    call stdlib${ii}$_csscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                    do k = 1, ki - 1
                       vl( k, is ) = cmzero
                    end do
                 else
                    if( ki<n )call stdlib${ii}$_cgemv( 'N', n, n-ki, cmone, vl( 1_${ik}$, ki+1 ), ldvl,work( &
                              ki+1 ), 1_${ik}$, cmplx( scale,KIND=sp),vl( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vl( ii, ki ) )
                    call stdlib${ii}$_csscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                 end if
                 ! set back the original diagonal elements of t.
                 do k = ki + 1, n
                    t( k, k ) = work( k+n )
                 end do
                 is = is + 1_${ik}$
              end do loop_130
           end if
           return
     end subroutine stdlib${ii}$_ctrevc

     pure module subroutine stdlib${ii}$_ztrevc( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! ZTREVC computes some or all of the right and/or left eigenvectors of
     !! a complex upper triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix.  If Q is the unitary factor that reduces a matrix A to
     !! Schur form T, then Q*X and Q*Y are the matrices of right and left
     !! eigenvectors of A.
               work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(inout) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           complex(dp), parameter :: cmzero = (0.0e+0_dp,0.0e+0_dp)
           complex(dp), parameter :: cmone = (1.0e+0_dp,0.0e+0_dp)
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, over, rightv, somev
           integer(${ik}$) :: i, ii, is, j, k, ki
           real(dp) :: ovfl, remax, scale, smin, smlnum, ulp, unfl
           complex(dp) :: cdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=dp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           allv = stdlib_lsame( howmny, 'A' )
           over = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           if( somev ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTREVC', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_dlabad( unfl, ovfl )
           ulp = stdlib${ii}$_dlamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ! store the diagonal elements of t in working array work.
           do i = 1, n
              work( i+n ) = t( i, i )
           end do
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           rwork( 1_${ik}$ ) = zero
           do j = 2, n
              rwork( j ) = stdlib${ii}$_dzasum( j-1, t( 1_${ik}$, j ), 1_${ik}$ )
           end do
           if( rightv ) then
              ! compute right eigenvectors.
              is = m
              loop_80: do ki = n, 1, -1
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_80
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 work( 1_${ik}$ ) = cmone
                 ! form right-hand side.
                 do k = 1, ki - 1
                    work( k ) = -t( k, ki )
                 end do
                 ! solve the triangular system:
                    ! (t(1:ki-1,1:ki-1) - t(ki,ki))*x = scale*work.
                 do k = 1, ki - 1
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki>1_${ik}$ ) then
                    call stdlib${ii}$_zlatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', 'Y',ki-1, t, ldt, &
                              work( 1_${ik}$ ), scale, rwork,info )
                    work( ki ) = scale
                 end if
                 ! copy the vector x or q*x to vr and normalize.
                 if( .not.over ) then
                    call stdlib${ii}$_zcopy( ki, work( 1_${ik}$ ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, is ) )
                    call stdlib${ii}$_zdscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                    do k = ki + 1, n
                       vr( k, is ) = cmzero
                    end do
                 else
                    if( ki>1_${ik}$ )call stdlib${ii}$_zgemv( 'N', n, ki-1, cmone, vr, ldvr, work( 1_${ik}$ ),1_${ik}$, &
                              cmplx( scale,KIND=dp), vr( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, ki ) )
                    call stdlib${ii}$_zdscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                 end if
                 ! set back the original diagonal elements of t.
                 do k = 1, ki - 1
                    t( k, k ) = work( k+n )
                 end do
                 is = is - 1_${ik}$
              end do loop_80
           end if
           if( leftv ) then
              ! compute left eigenvectors.
              is = 1_${ik}$
              loop_130: do ki = 1, n
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_130
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 work( n ) = cmone
                 ! form right-hand side.
                 do k = ki + 1, n
                    work( k ) = -conjg( t( ki, k ) )
                 end do
                 ! solve the triangular system:
                    ! (t(ki+1:n,ki+1:n) - t(ki,ki))**h * x = scale*work.
                 do k = ki + 1, n
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki<n ) then
                    call stdlib${ii}$_zlatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT','Y', n-ki, t( &
                              ki+1, ki+1 ), ldt,work( ki+1 ), scale, rwork, info )
                    work( ki ) = scale
                 end if
                 ! copy the vector x or q*x to vl and normalize.
                 if( .not.over ) then
                    call stdlib${ii}$_zcopy( n-ki+1, work( ki ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                    remax = one / cabs1( vl( ii, is ) )
                    call stdlib${ii}$_zdscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                    do k = 1, ki - 1
                       vl( k, is ) = cmzero
                    end do
                 else
                    if( ki<n )call stdlib${ii}$_zgemv( 'N', n, n-ki, cmone, vl( 1_${ik}$, ki+1 ), ldvl,work( &
                              ki+1 ), 1_${ik}$, cmplx( scale,KIND=dp),vl( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vl( ii, ki ) )
                    call stdlib${ii}$_zdscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                 end if
                 ! set back the original diagonal elements of t.
                 do k = ki + 1, n
                    t( k, k ) = work( k+n )
                 end do
                 is = is + 1_${ik}$
              end do loop_130
           end if
           return
     end subroutine stdlib${ii}$_ztrevc

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$trevc( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! ZTREVC: computes some or all of the right and/or left eigenvectors of
     !! a complex upper triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix.  If Q is the unitary factor that reduces a matrix A to
     !! Schur form T, then Q*X and Q*Y are the matrices of right and left
     !! eigenvectors of A.
               work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(inout) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           complex(${ck}$), parameter :: cmzero = (0.0e+0_${ck}$,0.0e+0_${ck}$)
           complex(${ck}$), parameter :: cmone = (1.0e+0_${ck}$,0.0e+0_${ck}$)
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, over, rightv, somev
           integer(${ik}$) :: i, ii, is, j, k, ki
           real(${ck}$) :: ovfl, remax, scale, smin, smlnum, ulp, unfl
           complex(${ck}$) :: cdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=${ck}$) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           bothv = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv = stdlib_lsame( side, 'L' ) .or. bothv
           allv = stdlib_lsame( howmny, 'A' )
           over = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           if( somev ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTREVC', -info )
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_${c2ri(ci)}$labad( unfl, ovfl )
           ulp = stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ! store the diagonal elements of t in working array work.
           do i = 1, n
              work( i+n ) = t( i, i )
           end do
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           rwork( 1_${ik}$ ) = zero
           do j = 2, n
              rwork( j ) = stdlib${ii}$_${c2ri(ci)}$zasum( j-1, t( 1_${ik}$, j ), 1_${ik}$ )
           end do
           if( rightv ) then
              ! compute right eigenvectors.
              is = m
              loop_80: do ki = n, 1, -1
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_80
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 work( 1_${ik}$ ) = cmone
                 ! form right-hand side.
                 do k = 1, ki - 1
                    work( k ) = -t( k, ki )
                 end do
                 ! solve the triangular system:
                    ! (t(1:ki-1,1:ki-1) - t(ki,ki))*x = scale*work.
                 do k = 1, ki - 1
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki>1_${ik}$ ) then
                    call stdlib${ii}$_${ci}$latrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', 'Y',ki-1, t, ldt, &
                              work( 1_${ik}$ ), scale, rwork,info )
                    work( ki ) = scale
                 end if
                 ! copy the vector x or q*x to vr and normalize.
                 if( .not.over ) then
                    call stdlib${ii}$_${ci}$copy( ki, work( 1_${ik}$ ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, is ) )
                    call stdlib${ii}$_${ci}$dscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                    do k = ki + 1, n
                       vr( k, is ) = cmzero
                    end do
                 else
                    if( ki>1_${ik}$ )call stdlib${ii}$_${ci}$gemv( 'N', n, ki-1, cmone, vr, ldvr, work( 1_${ik}$ ),1_${ik}$, &
                              cmplx( scale,KIND=${ck}$), vr( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, ki ) )
                    call stdlib${ii}$_${ci}$dscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                 end if
                 ! set back the original diagonal elements of t.
                 do k = 1, ki - 1
                    t( k, k ) = work( k+n )
                 end do
                 is = is - 1_${ik}$
              end do loop_80
           end if
           if( leftv ) then
              ! compute left eigenvectors.
              is = 1_${ik}$
              loop_130: do ki = 1, n
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_130
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 work( n ) = cmone
                 ! form right-hand side.
                 do k = ki + 1, n
                    work( k ) = -conjg( t( ki, k ) )
                 end do
                 ! solve the triangular system:
                    ! (t(ki+1:n,ki+1:n) - t(ki,ki))**h * x = scale*work.
                 do k = ki + 1, n
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki<n ) then
                    call stdlib${ii}$_${ci}$latrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT','Y', n-ki, t( &
                              ki+1, ki+1 ), ldt,work( ki+1 ), scale, rwork, info )
                    work( ki ) = scale
                 end if
                 ! copy the vector x or q*x to vl and normalize.
                 if( .not.over ) then
                    call stdlib${ii}$_${ci}$copy( n-ki+1, work( ki ), 1_${ik}$, vl( ki, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                    remax = one / cabs1( vl( ii, is ) )
                    call stdlib${ii}$_${ci}$dscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                    do k = 1, ki - 1
                       vl( k, is ) = cmzero
                    end do
                 else
                    if( ki<n )call stdlib${ii}$_${ci}$gemv( 'N', n, n-ki, cmone, vl( 1_${ik}$, ki+1 ), ldvl,work( &
                              ki+1 ), 1_${ik}$, cmplx( scale,KIND=${ck}$),vl( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vl( ii, ki ) )
                    call stdlib${ii}$_${ci}$dscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                 end if
                 ! set back the original diagonal elements of t.
                 do k = ki + 1, n
                    t( k, k ) = work( k+n )
                 end do
                 is = is + 1_${ik}$
              end do loop_130
           end if
           return
     end subroutine stdlib${ii}$_${ci}$trevc

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_strevc3( side, howmny, select, n, t, ldt, vl, ldvl,vr, ldvr, mm, m, &
     !! STREVC3 computes some or all of the right and/or left eigenvectors of
     !! a real upper quasi-triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a real general matrix:  A = Q*T*Q**T, as computed by SHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**T)*T = w*(y**T)
     !! where y**T denotes the transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal blocks of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix. If Q is the orthogonal factor that reduces a matrix
     !! A to Schur form T, then Q*X and Q*Y are the matrices of right and
     !! left eigenvectors of A.
     !! This uses a Level 3 BLAS version of the back transformation.
               work, lwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, lwork, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           real(sp), intent(in) :: t(ldt,*)
           real(sp), intent(inout) :: vl(ldvl,*), vr(ldvr,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmin = 8_${ik}$
           integer(${ik}$), parameter :: nbmax = 128_${ik}$
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, lquery, over, pair, rightv, somev
           integer(${ik}$) :: i, ierr, ii, ip, is, j, j1, j2, jnxt, k, ki, iv, maxwrk, nb, &
                     ki2
           real(sp) :: beta, bignum, emax, ovfl, rec, remax, scale, smin, smlnum, ulp, unfl, &
                     vcrit, vmax, wi, wr, xnorm
           ! Intrinsic Functions 
           ! Local Arrays 
           real(sp) :: x(2_${ik}$,2_${ik}$)
           integer(${ik}$) :: iscomplex(nbmax)
           ! Executable Statements 
           ! decode and test the input parameters
           bothv  = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv  = stdlib_lsame( side, 'L' ) .or. bothv
           allv  = stdlib_lsame( howmny, 'A' )
           over  = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'STREVC', side // howmny, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           maxwrk = n + 2_${ik}$*n*nb
           work(1_${ik}$) = maxwrk
           lquery = ( lwork==-1_${ik}$ )
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( lwork<max( 1_${ik}$, 3_${ik}$*n ) .and. .not.lquery ) then
              info = -14_${ik}$
           else
              ! set m to the number of columns required to store the selected
              ! eigenvectors, standardize the array select if necessary, and
              ! test mm.
              if( somev ) then
                 m = 0_${ik}$
                 pair = .false.
                 do j = 1, n
                    if( pair ) then
                       pair = .false.
                       select( j ) = .false.
                    else
                       if( j<n ) then
                          if( t( j+1, j )==zero ) then
                             if( select( j ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( j ) .or. select( j+1 ) ) then
                                select( j ) = .true.
                                m = m + 2_${ik}$
                             end if
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -11_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'STREVC3', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! use blocked version of back-transformation if sufficient workspace.
           ! zero-out the workspace to avoid potential nan propagation.
           if( over .and. lwork >= n + 2_${ik}$*n*nbmin ) then
              nb = (lwork - n) / (2_${ik}$*n)
              nb = min( nb, nbmax )
              call stdlib${ii}$_slaset( 'F', n, 1_${ik}$+2*nb, zero, zero, work, n )
           else
              nb = 1_${ik}$
           end if
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_slabad( unfl, ovfl )
           ulp = stdlib${ii}$_slamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           work( 1_${ik}$ ) = zero
           do j = 2, n
              work( j ) = zero
              do i = 1, j - 1
                 work( j ) = work( j ) + abs( t( i, j ) )
              end do
           end do
           ! index ip is used to specify the real or complex eigenvalue:
             ! ip = 0, real eigenvalue,
                  ! 1, first  of conjugate complex pair: (wr,wi)
                 ! -1, second of conjugate complex pair: (wr,wi)
             ! iscomplex array stores ip for each column in current block.
           if( rightv ) then
              ! ============================================================
              ! compute right eigenvectors.
              ! iv is index of column in current block.
              ! for complex right vector, uses iv-1 for real part and iv for complex part.
              ! non-blocked version always uses iv=2;
              ! blocked     version starts with iv=nb, goes down to 1 or 2.
              ! (note the "0-th" column is used for 1-norms computed above.)
              iv = 2_${ik}$
              if( nb>2_${ik}$ ) then
                 iv = nb
              end if
              ip = 0_${ik}$
              is = m
              loop_140: do ki = n, 1, -1
                 if( ip==-1_${ik}$ ) then
                    ! previous iteration (ki+1) was second of conjugate pair,
                    ! so this ki is first of conjugate pair; skip to end of loop
                    ip = 1_${ik}$
                    cycle loop_140
                 else if( ki==1_${ik}$ ) then
                    ! last column, so this ki must be real eigenvalue
                    ip = 0_${ik}$
                 else if( t( ki, ki-1 )==zero ) then
                    ! zero on sub-diagonal, so this ki is real eigenvalue
                    ip = 0_${ik}$
                 else
                    ! non-zero on sub-diagonal, so this ki is second of conjugate pair
                    ip = -1_${ik}$
                 end if
                 if( somev ) then
                    if( ip==0_${ik}$ ) then
                       if( .not.select( ki ) )cycle loop_140
                    else
                       if( .not.select( ki-1 ) )cycle loop_140
                    end if
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki-1 ) ) )*sqrt( abs( t( ki-1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! real right eigenvector
                    work( ki + iv*n ) = one
                    ! form right-hand side.
                    do k = 1, ki - 1
                       work( k + iv*n ) = -t( k, ki )
                    end do
                    ! solve upper quasi-triangular system:
                    ! [ t(1:ki-1,1:ki-1) - wr ]*x = scale*work.
                    jnxt = ki - 1_${ik}$
                    loop_60: do j = ki - 1, 1, -1
                       if( j>jnxt )cycle loop_60
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1   = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          work( j+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_saxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_slaln2( .false., 2_${ik}$, 1_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+iv*n ), n, wr, zero, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x(1,1) and x(2,1) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          work( j-1+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +iv*n ) = x( 2_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_saxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_60
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vr and normalize.
                       call stdlib${ii}$_scopy( ki, work( 1_${ik}$ + iv*n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                       remax = one / abs( vr( ii, is ) )
                       call stdlib${ii}$_sscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki>1_${ik}$ )call stdlib${ii}$_sgemv( 'N', n, ki-1, one, vr, ldvr,work( 1_${ik}$ + iv*n ), &
                                 1_${ik}$, work( ki + iv*n ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vr( ii, ki ) )
                       call stdlib${ii}$_sscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out below vector
                       do k = ki + 1, n
                          work( k + iv*n ) = zero
                       end do
                       iscomplex( iv ) = ip
                       ! back-transform and normalization is done below
                    end if
                 else
                    ! --------------------------------------------------------
                    ! complex right eigenvector.
                    ! initial solve
                    ! [ ( t(ki-1,ki-1) t(ki-1,ki) ) - (wr + i*wi) ]*x = 0.
                    ! [ ( t(ki,  ki-1) t(ki,  ki) )               ]
                    if( abs( t( ki-1, ki ) )>=abs( t( ki, ki-1 ) ) ) then
                       work( ki-1 + (iv-1)*n ) = one
                       work( ki   + (iv  )*n ) = wi / t( ki-1, ki )
                    else
                       work( ki-1 + (iv-1)*n ) = -wi / t( ki, ki-1 )
                       work( ki   + (iv  )*n ) = one
                    end if
                    work( ki   + (iv-1)*n ) = zero
                    work( ki-1 + (iv  )*n ) = zero
                    ! form right-hand side.
                    do k = 1, ki - 2
                       work( k+(iv-1)*n ) = -work( ki-1+(iv-1)*n )*t(k,ki-1)
                       work( k+(iv  )*n ) = -work( ki  +(iv  )*n )*t(k,ki  )
                    end do
                    ! solve upper quasi-triangular system:
                    ! [ t(1:ki-2,1:ki-2) - (wr+i*wi) ]*x = scale*(work+i*work2)
                    jnxt = ki - 2_${ik}$
                    loop_90: do j = ki - 2, 1, -1
                       if( j>jnxt )cycle loop_90
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1   = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+(iv-1)*n ), n,wr, wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) and x(1,2) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                          end if
                          work( j+(iv-1)*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+(iv  )*n ) = x( 1_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_saxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_saxpy( j-1, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_slaln2( .false., 2_${ik}$, 2_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+(iv-1)*n ), n, wr, wi, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                rec = one / xnorm
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )*rec
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )*rec
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ )*rec
                                x( 2_${ik}$, 2_${ik}$ ) = x( 2_${ik}$, 2_${ik}$ )*rec
                                scale = scale*rec
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                             call stdlib${ii}$_sscal( ki, scale, work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                          end if
                          work( j-1+(iv-1)*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +(iv-1)*n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j-1+(iv  )*n ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j  +(iv  )*n ) = x( 2_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_saxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n   ),&
                                     1_${ik}$ )
                          call stdlib${ii}$_saxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n   ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_saxpy( j-2, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_saxpy( j-2, -x( 2_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_90
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vr and normalize.
                       call stdlib${ii}$_scopy( ki, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$, vr(1_${ik}$,is-1), 1_${ik}$ )
                       call stdlib${ii}$_scopy( ki, work( 1_${ik}$+(iv  )*n ), 1_${ik}$, vr(1_${ik}$,is  ), 1_${ik}$ )
                       emax = zero
                       do k = 1, ki
                          emax = max( emax, abs( vr( k, is-1 ) )+abs( vr( k, is   ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( ki, remax, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( ki, remax, vr( 1_${ik}$, is   ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is-1 ) = zero
                          vr( k, is   ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki>2_${ik}$ ) then
                          call stdlib${ii}$_sgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$    + (iv-1)*n ), &
                                    1_${ik}$,work( ki-1 + (iv-1)*n ), vr(1_${ik}$,ki-1), 1_${ik}$)
                          call stdlib${ii}$_sgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$  + (iv)*n ), 1_${ik}$,&
                                    work( ki + (iv)*n ), vr( 1_${ik}$, ki ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_sscal( n, work(ki-1+(iv-1)*n), vr(1_${ik}$,ki-1), 1_${ik}$)
                          call stdlib${ii}$_sscal( n, work(ki  +(iv  )*n), vr(1_${ik}$,ki  ), 1_${ik}$)
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vr( k, ki-1 ) )+abs( vr( k, ki   ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( n, remax, vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( n, remax, vr( 1_${ik}$, ki   ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out below vector
                       do k = ki + 1, n
                          work( k + (iv-1)*n ) = zero
                          work( k + (iv  )*n ) = zero
                       end do
                       iscomplex( iv-1 ) = -ip
                       iscomplex( iv   ) =  ip
                       iv = iv - 1_${ik}$
                       ! back-transform and normalization is done below
                    end if
                 end if
                 if( nb>1_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! blocked version of back-transform
                    ! for complex case, ki2 includes both vectors (ki-1 and ki)
                    if( ip==0_${ik}$ ) then
                       ki2 = ki
                    else
                       ki2 = ki - 1_${ik}$
                    end if
                    ! columns iv:nb of work are valid vectors.
                    ! when the number of vectors stored reaches nb-1 or nb,
                    ! or if this was last vector, do the gemm
                    if( (iv<=2_${ik}$) .or. (ki2==1_${ik}$) ) then
                       call stdlib${ii}$_sgemm( 'N', 'N', n, nb-iv+1, ki2+nb-iv, one,vr, ldvr,work( 1_${ik}$ + &
                                 (iv)*n    ), n,zero,work( 1_${ik}$ + (nb+iv)*n ), n )
                       ! normalize vectors
                       do k = iv, nb
                          if( iscomplex(k)==0_${ik}$ ) then
                             ! real eigenvector
                             ii = stdlib${ii}$_isamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                             remax = one / abs( work( ii + (nb+k)*n ) )
                          else if( iscomplex(k)==1_${ik}$ ) then
                             ! first eigenvector of conjugate pair
                             emax = zero
                             do ii = 1, n
                                emax = max( emax,abs( work( ii + (nb+k  )*n ) )+abs( work( ii + (&
                                          nb+k+1)*n ) ) )
                             end do
                             remax = one / emax
                          ! else if iscomplex(k)==-1
                             ! second eigenvector of conjugate pair
                             ! reuse same remax as previous k
                          end if
                          call stdlib${ii}$_sscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_slacpy( 'F', n, nb-iv+1,work( 1_${ik}$ + (nb+iv)*n ), n,vr( 1_${ik}$, ki2 ), &
                                 ldvr )
                       iv = nb
                    else
                       iv = iv - 1_${ik}$
                    end if
                 end if ! blocked back-transform
                 is = is - 1_${ik}$
                 if( ip/=0_${ik}$ )is = is - 1_${ik}$
              end do loop_140
           end if
           if( leftv ) then
              ! ============================================================
              ! compute left eigenvectors.
              ! iv is index of column in current block.
              ! for complex left vector, uses iv for real part and iv+1 for complex part.
              ! non-blocked version always uses iv=1;
              ! blocked     version starts with iv=1, goes up to nb-1 or nb.
              ! (note the "0-th" column is used for 1-norms computed above.)
              iv = 1_${ik}$
              ip = 0_${ik}$
              is = 1_${ik}$
              loop_260: do ki = 1, n
                 if( ip==1_${ik}$ ) then
                    ! previous iteration (ki-1) was first of conjugate pair,
                    ! so this ki is second of conjugate pair; skip to end of loop
                    ip = -1_${ik}$
                    cycle loop_260
                 else if( ki==n ) then
                    ! last column, so this ki must be real eigenvalue
                    ip = 0_${ik}$
                 else if( t( ki+1, ki )==zero ) then
                    ! zero on sub-diagonal, so this ki is real eigenvalue
                    ip = 0_${ik}$
                 else
                    ! non-zero on sub-diagonal, so this ki is first of conjugate pair
                    ip = 1_${ik}$
                 end if
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_260
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki+1 ) ) )*sqrt( abs( t( ki+1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! real left eigenvector
                    work( ki + iv*n ) = one
                    ! form right-hand side.
                    do k = ki + 1, n
                       work( k + iv*n ) = -t( ki, k )
                    end do
                    ! solve transposed quasi-triangular system:
                    ! [ t(ki+1:n,ki+1:n) - wr ]**t * x = scale*work
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 1_${ik}$
                    loop_170: do j = ki + 1, n
                       if( j<jnxt )cycle loop_170
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+iv*n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+iv*n ) = work( j+iv*n ) -stdlib${ii}$_sdot( j-ki-1, t( ki+1, j ), 1_${ik}$,&
                                    work( ki+1+iv*n ), 1_${ik}$ )
                          ! solve [ t(j,j) - wr ]**t * x = work
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+iv*n ), 1_${ik}$ )
                                    
                          work( j+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+iv*n ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work( ki+iv*n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+iv*n ) = work( j+iv*n ) -stdlib${ii}$_sdot( j-ki-1, t( ki+1, j ), 1_${ik}$,&
                                    work( ki+1+iv*n ), 1_${ik}$ )
                          work( j+1+iv*n ) = work( j+1+iv*n ) -stdlib${ii}$_sdot( j-ki-1, t( ki+1, j+1 )&
                                    , 1_${ik}$,work( ki+1+iv*n ), 1_${ik}$ )
                          ! solve
                          ! [ t(j,j)-wr   t(j,j+1)      ]**t * x = scale*( work1 )
                          ! [ t(j+1,j)    t(j+1,j+1)-wr ]                ( work2 )
                          call stdlib${ii}$_slaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_sscal( n-ki+1, scale, work( ki+iv*n ), 1_${ik}$ )
                                    
                          work( j  +iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+1+iv*n ) = x( 2_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j  +iv*n ) ),abs( work( j+1+iv*n ) ), vmax )
                                    
                          vcrit = bignum / vmax
                       end if
                    end do loop_170
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vl and normalize.
                       call stdlib${ii}$_scopy( n-ki+1, work( ki + iv*n ), 1_${ik}$,vl( ki, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                       remax = one / abs( vl( ii, is ) )
                       call stdlib${ii}$_sscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki<n )call stdlib${ii}$_sgemv( 'N', n, n-ki, one,vl( 1_${ik}$, ki+1 ), ldvl,work( &
                                 ki+1 + iv*n ), 1_${ik}$,work( ki   + iv*n ), vl( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_isamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vl( ii, ki ) )
                       call stdlib${ii}$_sscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out above vector
                       ! could go from ki-nv+1 to ki-1
                       do k = 1, ki - 1
                          work( k + iv*n ) = zero
                       end do
                       iscomplex( iv ) = ip
                       ! back-transform and normalization is done below
                    end if
                 else
                    ! --------------------------------------------------------
                    ! complex left eigenvector.
                    ! initial solve:
                    ! [ ( t(ki,ki)    t(ki,ki+1)  )**t - (wr - i* wi) ]*x = 0.
                    ! [ ( t(ki+1,ki) t(ki+1,ki+1) )                   ]
                    if( abs( t( ki, ki+1 ) )>=abs( t( ki+1, ki ) ) ) then
                       work( ki   + (iv  )*n ) = wi / t( ki, ki+1 )
                       work( ki+1 + (iv+1)*n ) = one
                    else
                       work( ki   + (iv  )*n ) = one
                       work( ki+1 + (iv+1)*n ) = -wi / t( ki+1, ki )
                    end if
                    work( ki+1 + (iv  )*n ) = zero
                    work( ki   + (iv+1)*n ) = zero
                    ! form right-hand side.
                    do k = ki + 2, n
                       work( k+(iv  )*n ) = -work( ki  +(iv  )*n )*t(ki,  k)
                       work( k+(iv+1)*n ) = -work( ki+1+(iv+1)*n )*t(ki+1,k)
                    end do
                    ! solve transposed quasi-triangular system:
                    ! [ t(ki+2:n,ki+2:n)**t - (wr-i*wi) ]*x = work1+i*work2
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 2_${ik}$
                    loop_200: do j = ki + 2, n
                       if( j<jnxt )cycle loop_200
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when
                          ! forming the right-hand side elements.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work(ki+(iv  )*n), 1_${ik}$ )
                             call stdlib${ii}$_sscal( n-ki+1, rec, work(ki+(iv+1)*n), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+(iv  )*n ) = work( j+(iv)*n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, j )&
                                    , 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j+(iv+1)*n ) = work( j+(iv+1)*n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, &
                                    j ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          ! solve [ t(j,j)-(wr-i*wi) ]*(x11+i*x12)= wk+i*wk2
                          call stdlib${ii}$_slaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( n-ki+1, scale, work(ki+(iv  )*n), 1_${ik}$)
                             call stdlib${ii}$_sscal( n-ki+1, scale, work(ki+(iv+1)*n), 1_${ik}$)
                          end if
                          work( j+(iv  )*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+(iv+1)*n ) = x( 1_${ik}$, 2_${ik}$ )
                          vmax = max( abs( work( j+(iv  )*n ) ),abs( work( j+(iv+1)*n ) ), vmax )
                                    
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side elements.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_sscal( n-ki+1, rec, work(ki+(iv  )*n), 1_${ik}$ )
                             call stdlib${ii}$_sscal( n-ki+1, rec, work(ki+(iv+1)*n), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j  +(iv  )*n ) = work( j+(iv)*n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2, &
                                    j ), 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j  +(iv+1)*n ) = work( j+(iv+1)*n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2,&
                                     j ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          work( j+1+(iv  )*n ) = work( j+1+(iv)*n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+2,&
                                     j+1 ), 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j+1+(iv+1)*n ) = work( j+1+(iv+1)*n ) -stdlib${ii}$_sdot( j-ki-2, t( ki+&
                                    2_${ik}$, j+1 ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          ! solve 2-by-2 complex linear equation
                          ! [ (t(j,j)   t(j,j+1)  )**t - (wr-i*wi)*i ]*x = scale*b
                          ! [ (t(j+1,j) t(j+1,j+1))                  ]
                          call stdlib${ii}$_slaln2( .true., 2_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_sscal( n-ki+1, scale, work(ki+(iv  )*n), 1_${ik}$)
                             call stdlib${ii}$_sscal( n-ki+1, scale, work(ki+(iv+1)*n), 1_${ik}$)
                          end if
                          work( j  +(iv  )*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +(iv+1)*n ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+1+(iv  )*n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j+1+(iv+1)*n ) = x( 2_${ik}$, 2_${ik}$ )
                          vmax = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 1_${ik}$, 2_${ik}$ ) ),abs( x( 2_${ik}$, 1_${ik}$ ) ), abs( x(&
                                     2_${ik}$, 2_${ik}$ ) ),vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_200
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vl and normalize.
                       call stdlib${ii}$_scopy( n-ki+1, work( ki + (iv  )*n ), 1_${ik}$,vl( ki, is   ), 1_${ik}$ )
                                 
                       call stdlib${ii}$_scopy( n-ki+1, work( ki + (iv+1)*n ), 1_${ik}$,vl( ki, is+1 ), 1_${ik}$ )
                                 
                       emax = zero
                       do k = ki, n
                          emax = max( emax, abs( vl( k, is   ) )+abs( vl( k, is+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( n-ki+1, remax, vl( ki, is   ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( n-ki+1, remax, vl( ki, is+1 ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is   ) = zero
                          vl( k, is+1 ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki<n-1 ) then
                          call stdlib${ii}$_sgemv( 'N', n, n-ki-1, one,vl( 1_${ik}$, ki+2 ), ldvl,work( ki+2 + &
                                    (iv)*n ), 1_${ik}$,work( ki   + (iv)*n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_sgemv( 'N', n, n-ki-1, one,vl( 1_${ik}$, ki+2 ), ldvl,work( ki+2 + &
                                    (iv+1)*n ), 1_${ik}$,work( ki+1 + (iv+1)*n ),vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_sscal( n, work(ki+  (iv  )*n), vl(1_${ik}$, ki  ), 1_${ik}$)
                          call stdlib${ii}$_sscal( n, work(ki+1+(iv+1)*n), vl(1_${ik}$, ki+1), 1_${ik}$)
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vl( k, ki   ) )+abs( vl( k, ki+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_sscal( n, remax, vl( 1_${ik}$, ki   ), 1_${ik}$ )
                       call stdlib${ii}$_sscal( n, remax, vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out above vector
                       ! could go from ki-nv+1 to ki-1
                       do k = 1, ki - 1
                          work( k + (iv  )*n ) = zero
                          work( k + (iv+1)*n ) = zero
                       end do
                       iscomplex( iv   ) =  ip
                       iscomplex( iv+1 ) = -ip
                       iv = iv + 1_${ik}$
                       ! back-transform and normalization is done below
                    end if
                 end if
                 if( nb>1_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! blocked version of back-transform
                    ! for complex case, ki2 includes both vectors (ki and ki+1)
                    if( ip==0_${ik}$ ) then
                       ki2 = ki
                    else
                       ki2 = ki + 1_${ik}$
                    end if
                    ! columns 1:iv of work are valid vectors.
                    ! when the number of vectors stored reaches nb-1 or nb,
                    ! or if this was last vector, do the gemm
                    if( (iv>=nb-1) .or. (ki2==n) ) then
                       call stdlib${ii}$_sgemm( 'N', 'N', n, iv, n-ki2+iv, one,vl( 1_${ik}$, ki2-iv+1 ), ldvl,&
                                 work( ki2-iv+1 + (1_${ik}$)*n ), n,zero,work( 1_${ik}$ + (nb+1)*n ), n )
                       ! normalize vectors
                       do k = 1, iv
                          if( iscomplex(k)==0_${ik}$) then
                             ! real eigenvector
                             ii = stdlib${ii}$_isamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                             remax = one / abs( work( ii + (nb+k)*n ) )
                          else if( iscomplex(k)==1_${ik}$) then
                             ! first eigenvector of conjugate pair
                             emax = zero
                             do ii = 1, n
                                emax = max( emax,abs( work( ii + (nb+k  )*n ) )+abs( work( ii + (&
                                          nb+k+1)*n ) ) )
                             end do
                             remax = one / emax
                          ! else if iscomplex(k)==-1
                             ! second eigenvector of conjugate pair
                             ! reuse same remax as previous k
                          end if
                          call stdlib${ii}$_sscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_slacpy( 'F', n, iv,work( 1_${ik}$ + (nb+1)*n ), n,vl( 1_${ik}$, ki2-iv+1 ), &
                                 ldvl )
                       iv = 1_${ik}$
                    else
                       iv = iv + 1_${ik}$
                    end if
                 end if ! blocked back-transform
                 is = is + 1_${ik}$
                 if( ip/=0_${ik}$ )is = is + 1_${ik}$
              end do loop_260
           end if
           return
     end subroutine stdlib${ii}$_strevc3

     pure module subroutine stdlib${ii}$_dtrevc3( side, howmny, select, n, t, ldt, vl, ldvl,vr, ldvr, mm, m, &
     !! DTREVC3 computes some or all of the right and/or left eigenvectors of
     !! a real upper quasi-triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**T)*T = w*(y**T)
     !! where y**T denotes the transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal blocks of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix. If Q is the orthogonal factor that reduces a matrix
     !! A to Schur form T, then Q*X and Q*Y are the matrices of right and
     !! left eigenvectors of A.
     !! This uses a Level 3 BLAS version of the back transformation.
               work, lwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, lwork, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           real(dp), intent(in) :: t(ldt,*)
           real(dp), intent(inout) :: vl(ldvl,*), vr(ldvr,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmin = 8_${ik}$
           integer(${ik}$), parameter :: nbmax = 128_${ik}$
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, lquery, over, pair, rightv, somev
           integer(${ik}$) :: i, ierr, ii, ip, is, j, j1, j2, jnxt, k, ki, iv, maxwrk, nb, &
                     ki2
           real(dp) :: beta, bignum, emax, ovfl, rec, remax, scale, smin, smlnum, ulp, unfl, &
                     vcrit, vmax, wi, wr, xnorm
           ! Intrinsic Functions 
           ! Local Arrays 
           real(dp) :: x(2_${ik}$,2_${ik}$)
           integer(${ik}$) :: iscomplex(nbmax)
           ! Executable Statements 
           ! decode and test the input parameters
           bothv  = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv  = stdlib_lsame( side, 'L' ) .or. bothv
           allv  = stdlib_lsame( howmny, 'A' )
           over  = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DTREVC', side // howmny, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           maxwrk = n + 2_${ik}$*n*nb
           work(1_${ik}$) = maxwrk
           lquery = ( lwork==-1_${ik}$ )
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( lwork<max( 1_${ik}$, 3_${ik}$*n ) .and. .not.lquery ) then
              info = -14_${ik}$
           else
              ! set m to the number of columns required to store the selected
              ! eigenvectors, standardize the array select if necessary, and
              ! test mm.
              if( somev ) then
                 m = 0_${ik}$
                 pair = .false.
                 do j = 1, n
                    if( pair ) then
                       pair = .false.
                       select( j ) = .false.
                    else
                       if( j<n ) then
                          if( t( j+1, j )==zero ) then
                             if( select( j ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( j ) .or. select( j+1 ) ) then
                                select( j ) = .true.
                                m = m + 2_${ik}$
                             end if
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -11_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTREVC3', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! use blocked version of back-transformation if sufficient workspace.
           ! zero-out the workspace to avoid potential nan propagation.
           if( over .and. lwork >= n + 2_${ik}$*n*nbmin ) then
              nb = (lwork - n) / (2_${ik}$*n)
              nb = min( nb, nbmax )
              call stdlib${ii}$_dlaset( 'F', n, 1_${ik}$+2*nb, zero, zero, work, n )
           else
              nb = 1_${ik}$
           end if
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_dlabad( unfl, ovfl )
           ulp = stdlib${ii}$_dlamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           work( 1_${ik}$ ) = zero
           do j = 2, n
              work( j ) = zero
              do i = 1, j - 1
                 work( j ) = work( j ) + abs( t( i, j ) )
              end do
           end do
           ! index ip is used to specify the real or complex eigenvalue:
             ! ip = 0, real eigenvalue,
                  ! 1, first  of conjugate complex pair: (wr,wi)
                 ! -1, second of conjugate complex pair: (wr,wi)
             ! iscomplex array stores ip for each column in current block.
           if( rightv ) then
              ! ============================================================
              ! compute right eigenvectors.
              ! iv is index of column in current block.
              ! for complex right vector, uses iv-1 for real part and iv for complex part.
              ! non-blocked version always uses iv=2;
              ! blocked     version starts with iv=nb, goes down to 1 or 2.
              ! (note the "0-th" column is used for 1-norms computed above.)
              iv = 2_${ik}$
              if( nb>2_${ik}$ ) then
                 iv = nb
              end if
              ip = 0_${ik}$
              is = m
              loop_140: do ki = n, 1, -1
                 if( ip==-1_${ik}$ ) then
                    ! previous iteration (ki+1) was second of conjugate pair,
                    ! so this ki is first of conjugate pair; skip to end of loop
                    ip = 1_${ik}$
                    cycle loop_140
                 else if( ki==1_${ik}$ ) then
                    ! last column, so this ki must be real eigenvalue
                    ip = 0_${ik}$
                 else if( t( ki, ki-1 )==zero ) then
                    ! zero on sub-diagonal, so this ki is real eigenvalue
                    ip = 0_${ik}$
                 else
                    ! non-zero on sub-diagonal, so this ki is second of conjugate pair
                    ip = -1_${ik}$
                 end if
                 if( somev ) then
                    if( ip==0_${ik}$ ) then
                       if( .not.select( ki ) )cycle loop_140
                    else
                       if( .not.select( ki-1 ) )cycle loop_140
                    end if
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki-1 ) ) )*sqrt( abs( t( ki-1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! real right eigenvector
                    work( ki + iv*n ) = one
                    ! form right-hand side.
                    do k = 1, ki - 1
                       work( k + iv*n ) = -t( k, ki )
                    end do
                    ! solve upper quasi-triangular system:
                    ! [ t(1:ki-1,1:ki-1) - wr ]*x = scale*work.
                    jnxt = ki - 1_${ik}$
                    loop_60: do j = ki - 1, 1, -1
                       if( j>jnxt )cycle loop_60
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1   = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          work( j+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_daxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 1_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+iv*n ), n, wr, zero, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x(1,1) and x(2,1) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          work( j-1+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +iv*n ) = x( 2_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_daxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_60
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vr and normalize.
                       call stdlib${ii}$_dcopy( ki, work( 1_${ik}$ + iv*n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                       remax = one / abs( vr( ii, is ) )
                       call stdlib${ii}$_dscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki>1_${ik}$ )call stdlib${ii}$_dgemv( 'N', n, ki-1, one, vr, ldvr,work( 1_${ik}$ + iv*n ), &
                                 1_${ik}$, work( ki + iv*n ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vr( ii, ki ) )
                       call stdlib${ii}$_dscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out below vector
                       do k = ki + 1, n
                          work( k + iv*n ) = zero
                       end do
                       iscomplex( iv ) = ip
                       ! back-transform and normalization is done below
                    end if
                 else
                    ! --------------------------------------------------------
                    ! complex right eigenvector.
                    ! initial solve
                    ! [ ( t(ki-1,ki-1) t(ki-1,ki) ) - (wr + i*wi) ]*x = 0.
                    ! [ ( t(ki,  ki-1) t(ki,  ki) )               ]
                    if( abs( t( ki-1, ki ) )>=abs( t( ki, ki-1 ) ) ) then
                       work( ki-1 + (iv-1)*n ) = one
                       work( ki   + (iv  )*n ) = wi / t( ki-1, ki )
                    else
                       work( ki-1 + (iv-1)*n ) = -wi / t( ki, ki-1 )
                       work( ki   + (iv  )*n ) = one
                    end if
                    work( ki   + (iv-1)*n ) = zero
                    work( ki-1 + (iv  )*n ) = zero
                    ! form right-hand side.
                    do k = 1, ki - 2
                       work( k+(iv-1)*n ) = -work( ki-1+(iv-1)*n )*t(k,ki-1)
                       work( k+(iv  )*n ) = -work( ki  +(iv  )*n )*t(k,ki  )
                    end do
                    ! solve upper quasi-triangular system:
                    ! [ t(1:ki-2,1:ki-2) - (wr+i*wi) ]*x = scale*(work+i*work2)
                    jnxt = ki - 2_${ik}$
                    loop_90: do j = ki - 2, 1, -1
                       if( j>jnxt )cycle loop_90
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1   = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+(iv-1)*n ), n,wr, wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) and x(1,2) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                          end if
                          work( j+(iv-1)*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+(iv  )*n ) = x( 1_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_daxpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_daxpy( j-1, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 2_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+(iv-1)*n ), n, wr, wi, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                rec = one / xnorm
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )*rec
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )*rec
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ )*rec
                                x( 2_${ik}$, 2_${ik}$ ) = x( 2_${ik}$, 2_${ik}$ )*rec
                                scale = scale*rec
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                             call stdlib${ii}$_dscal( ki, scale, work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                          end if
                          work( j-1+(iv-1)*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +(iv-1)*n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j-1+(iv  )*n ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j  +(iv  )*n ) = x( 2_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_daxpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n   ),&
                                     1_${ik}$ )
                          call stdlib${ii}$_daxpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n   ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_daxpy( j-2, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_daxpy( j-2, -x( 2_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_90
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vr and normalize.
                       call stdlib${ii}$_dcopy( ki, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$, vr(1_${ik}$,is-1), 1_${ik}$ )
                       call stdlib${ii}$_dcopy( ki, work( 1_${ik}$+(iv  )*n ), 1_${ik}$, vr(1_${ik}$,is  ), 1_${ik}$ )
                       emax = zero
                       do k = 1, ki
                          emax = max( emax, abs( vr( k, is-1 ) )+abs( vr( k, is   ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( ki, remax, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( ki, remax, vr( 1_${ik}$, is   ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is-1 ) = zero
                          vr( k, is   ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki>2_${ik}$ ) then
                          call stdlib${ii}$_dgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$    + (iv-1)*n ), &
                                    1_${ik}$,work( ki-1 + (iv-1)*n ), vr(1_${ik}$,ki-1), 1_${ik}$)
                          call stdlib${ii}$_dgemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$  + (iv)*n ), 1_${ik}$,&
                                    work( ki + (iv)*n ), vr( 1_${ik}$, ki ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_dscal( n, work(ki-1+(iv-1)*n), vr(1_${ik}$,ki-1), 1_${ik}$)
                          call stdlib${ii}$_dscal( n, work(ki  +(iv  )*n), vr(1_${ik}$,ki  ), 1_${ik}$)
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vr( k, ki-1 ) )+abs( vr( k, ki   ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( n, remax, vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( n, remax, vr( 1_${ik}$, ki   ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out below vector
                       do k = ki + 1, n
                          work( k + (iv-1)*n ) = zero
                          work( k + (iv  )*n ) = zero
                       end do
                       iscomplex( iv-1 ) = -ip
                       iscomplex( iv   ) =  ip
                       iv = iv - 1_${ik}$
                       ! back-transform and normalization is done below
                    end if
                 end if
                 if( nb>1_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! blocked version of back-transform
                    ! for complex case, ki2 includes both vectors (ki-1 and ki)
                    if( ip==0_${ik}$ ) then
                       ki2 = ki
                    else
                       ki2 = ki - 1_${ik}$
                    end if
                    ! columns iv:nb of work are valid vectors.
                    ! when the number of vectors stored reaches nb-1 or nb,
                    ! or if this was last vector, do the gemm
                    if( (iv<=2_${ik}$) .or. (ki2==1_${ik}$) ) then
                       call stdlib${ii}$_dgemm( 'N', 'N', n, nb-iv+1, ki2+nb-iv, one,vr, ldvr,work( 1_${ik}$ + &
                                 (iv)*n    ), n,zero,work( 1_${ik}$ + (nb+iv)*n ), n )
                       ! normalize vectors
                       do k = iv, nb
                          if( iscomplex(k)==0_${ik}$ ) then
                             ! real eigenvector
                             ii = stdlib${ii}$_idamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                             remax = one / abs( work( ii + (nb+k)*n ) )
                          else if( iscomplex(k)==1_${ik}$ ) then
                             ! first eigenvector of conjugate pair
                             emax = zero
                             do ii = 1, n
                                emax = max( emax,abs( work( ii + (nb+k  )*n ) )+abs( work( ii + (&
                                          nb+k+1)*n ) ) )
                             end do
                             remax = one / emax
                          ! else if iscomplex(k)==-1
                             ! second eigenvector of conjugate pair
                             ! reuse same remax as previous k
                          end if
                          call stdlib${ii}$_dscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_dlacpy( 'F', n, nb-iv+1,work( 1_${ik}$ + (nb+iv)*n ), n,vr( 1_${ik}$, ki2 ), &
                                 ldvr )
                       iv = nb
                    else
                       iv = iv - 1_${ik}$
                    end if
                 end if ! blocked back-transform
                 is = is - 1_${ik}$
                 if( ip/=0_${ik}$ )is = is - 1_${ik}$
              end do loop_140
           end if
           if( leftv ) then
              ! ============================================================
              ! compute left eigenvectors.
              ! iv is index of column in current block.
              ! for complex left vector, uses iv for real part and iv+1 for complex part.
              ! non-blocked version always uses iv=1;
              ! blocked     version starts with iv=1, goes up to nb-1 or nb.
              ! (note the "0-th" column is used for 1-norms computed above.)
              iv = 1_${ik}$
              ip = 0_${ik}$
              is = 1_${ik}$
              loop_260: do ki = 1, n
                 if( ip==1_${ik}$ ) then
                    ! previous iteration (ki-1) was first of conjugate pair,
                    ! so this ki is second of conjugate pair; skip to end of loop
                    ip = -1_${ik}$
                    cycle loop_260
                 else if( ki==n ) then
                    ! last column, so this ki must be real eigenvalue
                    ip = 0_${ik}$
                 else if( t( ki+1, ki )==zero ) then
                    ! zero on sub-diagonal, so this ki is real eigenvalue
                    ip = 0_${ik}$
                 else
                    ! non-zero on sub-diagonal, so this ki is first of conjugate pair
                    ip = 1_${ik}$
                 end if
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_260
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki+1 ) ) )*sqrt( abs( t( ki+1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! real left eigenvector
                    work( ki + iv*n ) = one
                    ! form right-hand side.
                    do k = ki + 1, n
                       work( k + iv*n ) = -t( ki, k )
                    end do
                    ! solve transposed quasi-triangular system:
                    ! [ t(ki+1:n,ki+1:n) - wr ]**t * x = scale*work
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 1_${ik}$
                    loop_170: do j = ki + 1, n
                       if( j<jnxt )cycle loop_170
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+iv*n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+iv*n ) = work( j+iv*n ) -stdlib${ii}$_ddot( j-ki-1, t( ki+1, j ), 1_${ik}$,&
                                    work( ki+1+iv*n ), 1_${ik}$ )
                          ! solve [ t(j,j) - wr ]**t * x = work
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+iv*n ), 1_${ik}$ )
                                    
                          work( j+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+iv*n ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work( ki+iv*n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+iv*n ) = work( j+iv*n ) -stdlib${ii}$_ddot( j-ki-1, t( ki+1, j ), 1_${ik}$,&
                                    work( ki+1+iv*n ), 1_${ik}$ )
                          work( j+1+iv*n ) = work( j+1+iv*n ) -stdlib${ii}$_ddot( j-ki-1, t( ki+1, j+1 )&
                                    , 1_${ik}$,work( ki+1+iv*n ), 1_${ik}$ )
                          ! solve
                          ! [ t(j,j)-wr   t(j,j+1)      ]**t * x = scale*( work1 )
                          ! [ t(j+1,j)    t(j+1,j+1)-wr ]                ( work2 )
                          call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_dscal( n-ki+1, scale, work( ki+iv*n ), 1_${ik}$ )
                                    
                          work( j  +iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+1+iv*n ) = x( 2_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j  +iv*n ) ),abs( work( j+1+iv*n ) ), vmax )
                                    
                          vcrit = bignum / vmax
                       end if
                    end do loop_170
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vl and normalize.
                       call stdlib${ii}$_dcopy( n-ki+1, work( ki + iv*n ), 1_${ik}$,vl( ki, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                       remax = one / abs( vl( ii, is ) )
                       call stdlib${ii}$_dscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki<n )call stdlib${ii}$_dgemv( 'N', n, n-ki, one,vl( 1_${ik}$, ki+1 ), ldvl,work( &
                                 ki+1 + iv*n ), 1_${ik}$,work( ki   + iv*n ), vl( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_idamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vl( ii, ki ) )
                       call stdlib${ii}$_dscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out above vector
                       ! could go from ki-nv+1 to ki-1
                       do k = 1, ki - 1
                          work( k + iv*n ) = zero
                       end do
                       iscomplex( iv ) = ip
                       ! back-transform and normalization is done below
                    end if
                 else
                    ! --------------------------------------------------------
                    ! complex left eigenvector.
                    ! initial solve:
                    ! [ ( t(ki,ki)    t(ki,ki+1)  )**t - (wr - i* wi) ]*x = 0.
                    ! [ ( t(ki+1,ki) t(ki+1,ki+1) )                   ]
                    if( abs( t( ki, ki+1 ) )>=abs( t( ki+1, ki ) ) ) then
                       work( ki   + (iv  )*n ) = wi / t( ki, ki+1 )
                       work( ki+1 + (iv+1)*n ) = one
                    else
                       work( ki   + (iv  )*n ) = one
                       work( ki+1 + (iv+1)*n ) = -wi / t( ki+1, ki )
                    end if
                    work( ki+1 + (iv  )*n ) = zero
                    work( ki   + (iv+1)*n ) = zero
                    ! form right-hand side.
                    do k = ki + 2, n
                       work( k+(iv  )*n ) = -work( ki  +(iv  )*n )*t(ki,  k)
                       work( k+(iv+1)*n ) = -work( ki+1+(iv+1)*n )*t(ki+1,k)
                    end do
                    ! solve transposed quasi-triangular system:
                    ! [ t(ki+2:n,ki+2:n)**t - (wr-i*wi) ]*x = work1+i*work2
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 2_${ik}$
                    loop_200: do j = ki + 2, n
                       if( j<jnxt )cycle loop_200
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when
                          ! forming the right-hand side elements.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work(ki+(iv  )*n), 1_${ik}$ )
                             call stdlib${ii}$_dscal( n-ki+1, rec, work(ki+(iv+1)*n), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+(iv  )*n ) = work( j+(iv)*n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, j )&
                                    , 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j+(iv+1)*n ) = work( j+(iv+1)*n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, &
                                    j ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          ! solve [ t(j,j)-(wr-i*wi) ]*(x11+i*x12)= wk+i*wk2
                          call stdlib${ii}$_dlaln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( n-ki+1, scale, work(ki+(iv  )*n), 1_${ik}$)
                             call stdlib${ii}$_dscal( n-ki+1, scale, work(ki+(iv+1)*n), 1_${ik}$)
                          end if
                          work( j+(iv  )*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+(iv+1)*n ) = x( 1_${ik}$, 2_${ik}$ )
                          vmax = max( abs( work( j+(iv  )*n ) ),abs( work( j+(iv+1)*n ) ), vmax )
                                    
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side elements.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_dscal( n-ki+1, rec, work(ki+(iv  )*n), 1_${ik}$ )
                             call stdlib${ii}$_dscal( n-ki+1, rec, work(ki+(iv+1)*n), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j  +(iv  )*n ) = work( j+(iv)*n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2, &
                                    j ), 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j  +(iv+1)*n ) = work( j+(iv+1)*n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2,&
                                     j ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          work( j+1+(iv  )*n ) = work( j+1+(iv)*n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+2,&
                                     j+1 ), 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j+1+(iv+1)*n ) = work( j+1+(iv+1)*n ) -stdlib${ii}$_ddot( j-ki-2, t( ki+&
                                    2_${ik}$, j+1 ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          ! solve 2-by-2 complex linear equation
                          ! [ (t(j,j)   t(j,j+1)  )**t - (wr-i*wi)*i ]*x = scale*b
                          ! [ (t(j+1,j) t(j+1,j+1))                  ]
                          call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_dscal( n-ki+1, scale, work(ki+(iv  )*n), 1_${ik}$)
                             call stdlib${ii}$_dscal( n-ki+1, scale, work(ki+(iv+1)*n), 1_${ik}$)
                          end if
                          work( j  +(iv  )*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +(iv+1)*n ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+1+(iv  )*n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j+1+(iv+1)*n ) = x( 2_${ik}$, 2_${ik}$ )
                          vmax = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 1_${ik}$, 2_${ik}$ ) ),abs( x( 2_${ik}$, 1_${ik}$ ) ), abs( x(&
                                     2_${ik}$, 2_${ik}$ ) ),vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_200
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vl and normalize.
                       call stdlib${ii}$_dcopy( n-ki+1, work( ki + (iv  )*n ), 1_${ik}$,vl( ki, is   ), 1_${ik}$ )
                                 
                       call stdlib${ii}$_dcopy( n-ki+1, work( ki + (iv+1)*n ), 1_${ik}$,vl( ki, is+1 ), 1_${ik}$ )
                                 
                       emax = zero
                       do k = ki, n
                          emax = max( emax, abs( vl( k, is   ) )+abs( vl( k, is+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( n-ki+1, remax, vl( ki, is   ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( n-ki+1, remax, vl( ki, is+1 ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is   ) = zero
                          vl( k, is+1 ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki<n-1 ) then
                          call stdlib${ii}$_dgemv( 'N', n, n-ki-1, one,vl( 1_${ik}$, ki+2 ), ldvl,work( ki+2 + &
                                    (iv)*n ), 1_${ik}$,work( ki   + (iv)*n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_dgemv( 'N', n, n-ki-1, one,vl( 1_${ik}$, ki+2 ), ldvl,work( ki+2 + &
                                    (iv+1)*n ), 1_${ik}$,work( ki+1 + (iv+1)*n ),vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_dscal( n, work(ki+  (iv  )*n), vl(1_${ik}$, ki  ), 1_${ik}$)
                          call stdlib${ii}$_dscal( n, work(ki+1+(iv+1)*n), vl(1_${ik}$, ki+1), 1_${ik}$)
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vl( k, ki   ) )+abs( vl( k, ki+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_dscal( n, remax, vl( 1_${ik}$, ki   ), 1_${ik}$ )
                       call stdlib${ii}$_dscal( n, remax, vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out above vector
                       ! could go from ki-nv+1 to ki-1
                       do k = 1, ki - 1
                          work( k + (iv  )*n ) = zero
                          work( k + (iv+1)*n ) = zero
                       end do
                       iscomplex( iv   ) =  ip
                       iscomplex( iv+1 ) = -ip
                       iv = iv + 1_${ik}$
                       ! back-transform and normalization is done below
                    end if
                 end if
                 if( nb>1_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! blocked version of back-transform
                    ! for complex case, ki2 includes both vectors (ki and ki+1)
                    if( ip==0_${ik}$ ) then
                       ki2 = ki
                    else
                       ki2 = ki + 1_${ik}$
                    end if
                    ! columns 1:iv of work are valid vectors.
                    ! when the number of vectors stored reaches nb-1 or nb,
                    ! or if this was last vector, do the gemm
                    if( (iv>=nb-1) .or. (ki2==n) ) then
                       call stdlib${ii}$_dgemm( 'N', 'N', n, iv, n-ki2+iv, one,vl( 1_${ik}$, ki2-iv+1 ), ldvl,&
                                 work( ki2-iv+1 + (1_${ik}$)*n ), n,zero,work( 1_${ik}$ + (nb+1)*n ), n )
                       ! normalize vectors
                       do k = 1, iv
                          if( iscomplex(k)==0_${ik}$) then
                             ! real eigenvector
                             ii = stdlib${ii}$_idamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                             remax = one / abs( work( ii + (nb+k)*n ) )
                          else if( iscomplex(k)==1_${ik}$) then
                             ! first eigenvector of conjugate pair
                             emax = zero
                             do ii = 1, n
                                emax = max( emax,abs( work( ii + (nb+k  )*n ) )+abs( work( ii + (&
                                          nb+k+1)*n ) ) )
                             end do
                             remax = one / emax
                          ! else if iscomplex(k)==-1
                             ! second eigenvector of conjugate pair
                             ! reuse same remax as previous k
                          end if
                          call stdlib${ii}$_dscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_dlacpy( 'F', n, iv,work( 1_${ik}$ + (nb+1)*n ), n,vl( 1_${ik}$, ki2-iv+1 ), &
                                 ldvl )
                       iv = 1_${ik}$
                    else
                       iv = iv + 1_${ik}$
                    end if
                 end if ! blocked back-transform
                 is = is + 1_${ik}$
                 if( ip/=0_${ik}$ )is = is + 1_${ik}$
              end do loop_260
           end if
           return
     end subroutine stdlib${ii}$_dtrevc3

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$trevc3( side, howmny, select, n, t, ldt, vl, ldvl,vr, ldvr, mm, m, &
     !! DTREVC3: computes some or all of the right and/or left eigenvectors of
     !! a real upper quasi-triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a real general matrix:  A = Q*T*Q**T, as computed by DHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**T)*T = w*(y**T)
     !! where y**T denotes the transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal blocks of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix. If Q is the orthogonal factor that reduces a matrix
     !! A to Schur form T, then Q*X and Q*Y are the matrices of right and
     !! left eigenvectors of A.
     !! This uses a Level 3 BLAS version of the back transformation.
               work, lwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, lwork, mm, n
           ! Array Arguments 
           logical(lk), intent(inout) :: select(*)
           real(${rk}$), intent(in) :: t(ldt,*)
           real(${rk}$), intent(inout) :: vl(ldvl,*), vr(ldvr,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmin = 8_${ik}$
           integer(${ik}$), parameter :: nbmax = 128_${ik}$
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, lquery, over, pair, rightv, somev
           integer(${ik}$) :: i, ierr, ii, ip, is, j, j1, j2, jnxt, k, ki, iv, maxwrk, nb, &
                     ki2
           real(${rk}$) :: beta, bignum, emax, ovfl, rec, remax, scale, smin, smlnum, ulp, unfl, &
                     vcrit, vmax, wi, wr, xnorm
           ! Intrinsic Functions 
           ! Local Arrays 
           real(${rk}$) :: x(2_${ik}$,2_${ik}$)
           integer(${ik}$) :: iscomplex(nbmax)
           ! Executable Statements 
           ! decode and test the input parameters
           bothv  = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv  = stdlib_lsame( side, 'L' ) .or. bothv
           allv  = stdlib_lsame( howmny, 'A' )
           over  = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DTREVC', side // howmny, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           maxwrk = n + 2_${ik}$*n*nb
           work(1_${ik}$) = maxwrk
           lquery = ( lwork==-1_${ik}$ )
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( lwork<max( 1_${ik}$, 3_${ik}$*n ) .and. .not.lquery ) then
              info = -14_${ik}$
           else
              ! set m to the number of columns required to store the selected
              ! eigenvectors, standardize the array select if necessary, and
              ! test mm.
              if( somev ) then
                 m = 0_${ik}$
                 pair = .false.
                 do j = 1, n
                    if( pair ) then
                       pair = .false.
                       select( j ) = .false.
                    else
                       if( j<n ) then
                          if( t( j+1, j )==zero ) then
                             if( select( j ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( j ) .or. select( j+1 ) ) then
                                select( j ) = .true.
                                m = m + 2_${ik}$
                             end if
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -11_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTREVC3', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! use blocked version of back-transformation if sufficient workspace.
           ! zero-out the workspace to avoid potential nan propagation.
           if( over .and. lwork >= n + 2_${ik}$*n*nbmin ) then
              nb = (lwork - n) / (2_${ik}$*n)
              nb = min( nb, nbmax )
              call stdlib${ii}$_${ri}$laset( 'F', n, 1_${ik}$+2*nb, zero, zero, work, n )
           else
              nb = 1_${ik}$
           end if
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_${ri}$labad( unfl, ovfl )
           ulp = stdlib${ii}$_${ri}$lamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           bignum = ( one-ulp ) / smlnum
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           work( 1_${ik}$ ) = zero
           do j = 2, n
              work( j ) = zero
              do i = 1, j - 1
                 work( j ) = work( j ) + abs( t( i, j ) )
              end do
           end do
           ! index ip is used to specify the real or complex eigenvalue:
             ! ip = 0, real eigenvalue,
                  ! 1, first  of conjugate complex pair: (wr,wi)
                 ! -1, second of conjugate complex pair: (wr,wi)
             ! iscomplex array stores ip for each column in current block.
           if( rightv ) then
              ! ============================================================
              ! compute right eigenvectors.
              ! iv is index of column in current block.
              ! for complex right vector, uses iv-1 for real part and iv for complex part.
              ! non-blocked version always uses iv=2;
              ! blocked     version starts with iv=nb, goes down to 1 or 2.
              ! (note the "0-th" column is used for 1-norms computed above.)
              iv = 2_${ik}$
              if( nb>2_${ik}$ ) then
                 iv = nb
              end if
              ip = 0_${ik}$
              is = m
              loop_140: do ki = n, 1, -1
                 if( ip==-1_${ik}$ ) then
                    ! previous iteration (ki+1) was second of conjugate pair,
                    ! so this ki is first of conjugate pair; skip to end of loop
                    ip = 1_${ik}$
                    cycle loop_140
                 else if( ki==1_${ik}$ ) then
                    ! last column, so this ki must be real eigenvalue
                    ip = 0_${ik}$
                 else if( t( ki, ki-1 )==zero ) then
                    ! zero on sub-diagonal, so this ki is real eigenvalue
                    ip = 0_${ik}$
                 else
                    ! non-zero on sub-diagonal, so this ki is second of conjugate pair
                    ip = -1_${ik}$
                 end if
                 if( somev ) then
                    if( ip==0_${ik}$ ) then
                       if( .not.select( ki ) )cycle loop_140
                    else
                       if( .not.select( ki-1 ) )cycle loop_140
                    end if
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki-1 ) ) )*sqrt( abs( t( ki-1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! real right eigenvector
                    work( ki + iv*n ) = one
                    ! form right-hand side.
                    do k = 1, ki - 1
                       work( k + iv*n ) = -t( k, ki )
                    end do
                    ! solve upper quasi-triangular system:
                    ! [ t(1:ki-1,1:ki-1) - wr ]*x = scale*work.
                    jnxt = ki - 1_${ik}$
                    loop_60: do j = ki - 1, 1, -1
                       if( j>jnxt )cycle loop_60
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1   = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          work( j+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 1_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+iv*n ), n, wr, zero, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x(1,1) and x(2,1) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          work( j-1+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +iv*n ) = x( 2_${ik}$, 1_${ik}$ )
                          ! update right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+iv*n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_60
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vr and normalize.
                       call stdlib${ii}$_${ri}$copy( ki, work( 1_${ik}$ + iv*n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                       remax = one / abs( vr( ii, is ) )
                       call stdlib${ii}$_${ri}$scal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki>1_${ik}$ )call stdlib${ii}$_${ri}$gemv( 'N', n, ki-1, one, vr, ldvr,work( 1_${ik}$ + iv*n ), &
                                 1_${ik}$, work( ki + iv*n ),vr( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vr( ii, ki ) )
                       call stdlib${ii}$_${ri}$scal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out below vector
                       do k = ki + 1, n
                          work( k + iv*n ) = zero
                       end do
                       iscomplex( iv ) = ip
                       ! back-transform and normalization is done below
                    end if
                 else
                    ! --------------------------------------------------------
                    ! complex right eigenvector.
                    ! initial solve
                    ! [ ( t(ki-1,ki-1) t(ki-1,ki) ) - (wr + i*wi) ]*x = 0.
                    ! [ ( t(ki,  ki-1) t(ki,  ki) )               ]
                    if( abs( t( ki-1, ki ) )>=abs( t( ki, ki-1 ) ) ) then
                       work( ki-1 + (iv-1)*n ) = one
                       work( ki   + (iv  )*n ) = wi / t( ki-1, ki )
                    else
                       work( ki-1 + (iv-1)*n ) = -wi / t( ki, ki-1 )
                       work( ki   + (iv  )*n ) = one
                    end if
                    work( ki   + (iv-1)*n ) = zero
                    work( ki-1 + (iv  )*n ) = zero
                    ! form right-hand side.
                    do k = 1, ki - 2
                       work( k+(iv-1)*n ) = -work( ki-1+(iv-1)*n )*t(k,ki-1)
                       work( k+(iv  )*n ) = -work( ki  +(iv  )*n )*t(k,ki  )
                    end do
                    ! solve upper quasi-triangular system:
                    ! [ t(1:ki-2,1:ki-2) - (wr+i*wi) ]*x = scale*(work+i*work2)
                    jnxt = ki - 2_${ik}$
                    loop_90: do j = ki - 2, 1, -1
                       if( j>jnxt )cycle loop_90
                       j1 = j
                       j2 = j
                       jnxt = j - 1_${ik}$
                       if( j>1_${ik}$ ) then
                          if( t( j, j-1 )/=zero ) then
                             j1   = j - 1_${ik}$
                             jnxt = j - 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+(iv-1)*n ), n,wr, wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale x(1,1) and x(1,2) to avoid overflow when
                          ! updating the right-hand side.
                          if( xnorm>one ) then
                             if( work( j )>bignum / xnorm ) then
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ ) / xnorm
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ ) / xnorm
                                scale = scale / xnorm
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                          end if
                          work( j+(iv-1)*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+(iv  )*n ) = x( 1_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-1, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                                    
                          call stdlib${ii}$_${ri}$axpy( j-1, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                                    
                       else
                          ! 2-by-2 diagonal block
                          call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 2_${ik}$, smin, one,t( j-1, j-1 ), ldt, one, &
                                    one,work( j-1+(iv-1)*n ), n, wr, wi, x, 2_${ik}$,scale, xnorm, ierr )
                          ! scale x to avoid overflow when updating
                          ! the right-hand side.
                          if( xnorm>one ) then
                             beta = max( work( j-1 ), work( j ) )
                             if( beta>bignum / xnorm ) then
                                rec = one / xnorm
                                x( 1_${ik}$, 1_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )*rec
                                x( 1_${ik}$, 2_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )*rec
                                x( 2_${ik}$, 1_${ik}$ ) = x( 2_${ik}$, 1_${ik}$ )*rec
                                x( 2_${ik}$, 2_${ik}$ ) = x( 2_${ik}$, 2_${ik}$ )*rec
                                scale = scale*rec
                             end if
                          end if
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( ki, scale, work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                          end if
                          work( j-1+(iv-1)*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +(iv-1)*n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j-1+(iv  )*n ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j  +(iv  )*n ) = x( 2_${ik}$, 2_${ik}$ )
                          ! update the right-hand side
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 1_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n   ),&
                                     1_${ik}$ )
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 2_${ik}$, 1_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv-1)*n   ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 1_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j-1 ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_${ri}$axpy( j-2, -x( 2_${ik}$, 2_${ik}$ ), t( 1_${ik}$, j ), 1_${ik}$,work( 1_${ik}$+(iv  )*n ), 1_${ik}$ )
                                    
                       end if
                    end do loop_90
                    ! copy the vector x or q*x to vr and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vr and normalize.
                       call stdlib${ii}$_${ri}$copy( ki, work( 1_${ik}$+(iv-1)*n ), 1_${ik}$, vr(1_${ik}$,is-1), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$copy( ki, work( 1_${ik}$+(iv  )*n ), 1_${ik}$, vr(1_${ik}$,is  ), 1_${ik}$ )
                       emax = zero
                       do k = 1, ki
                          emax = max( emax, abs( vr( k, is-1 ) )+abs( vr( k, is   ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( ki, remax, vr( 1_${ik}$, is-1 ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( ki, remax, vr( 1_${ik}$, is   ), 1_${ik}$ )
                       do k = ki + 1, n
                          vr( k, is-1 ) = zero
                          vr( k, is   ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki>2_${ik}$ ) then
                          call stdlib${ii}$_${ri}$gemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$    + (iv-1)*n ), &
                                    1_${ik}$,work( ki-1 + (iv-1)*n ), vr(1_${ik}$,ki-1), 1_${ik}$)
                          call stdlib${ii}$_${ri}$gemv( 'N', n, ki-2, one, vr, ldvr,work( 1_${ik}$  + (iv)*n ), 1_${ik}$,&
                                    work( ki + (iv)*n ), vr( 1_${ik}$, ki ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_${ri}$scal( n, work(ki-1+(iv-1)*n), vr(1_${ik}$,ki-1), 1_${ik}$)
                          call stdlib${ii}$_${ri}$scal( n, work(ki  +(iv  )*n), vr(1_${ik}$,ki  ), 1_${ik}$)
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vr( k, ki-1 ) )+abs( vr( k, ki   ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( n, remax, vr( 1_${ik}$, ki-1 ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n, remax, vr( 1_${ik}$, ki   ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out below vector
                       do k = ki + 1, n
                          work( k + (iv-1)*n ) = zero
                          work( k + (iv  )*n ) = zero
                       end do
                       iscomplex( iv-1 ) = -ip
                       iscomplex( iv   ) =  ip
                       iv = iv - 1_${ik}$
                       ! back-transform and normalization is done below
                    end if
                 end if
                 if( nb>1_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! blocked version of back-transform
                    ! for complex case, ki2 includes both vectors (ki-1 and ki)
                    if( ip==0_${ik}$ ) then
                       ki2 = ki
                    else
                       ki2 = ki - 1_${ik}$
                    end if
                    ! columns iv:nb of work are valid vectors.
                    ! when the number of vectors stored reaches nb-1 or nb,
                    ! or if this was last vector, do the gemm
                    if( (iv<=2_${ik}$) .or. (ki2==1_${ik}$) ) then
                       call stdlib${ii}$_${ri}$gemm( 'N', 'N', n, nb-iv+1, ki2+nb-iv, one,vr, ldvr,work( 1_${ik}$ + &
                                 (iv)*n    ), n,zero,work( 1_${ik}$ + (nb+iv)*n ), n )
                       ! normalize vectors
                       do k = iv, nb
                          if( iscomplex(k)==0_${ik}$ ) then
                             ! real eigenvector
                             ii = stdlib${ii}$_i${ri}$amax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                             remax = one / abs( work( ii + (nb+k)*n ) )
                          else if( iscomplex(k)==1_${ik}$ ) then
                             ! first eigenvector of conjugate pair
                             emax = zero
                             do ii = 1, n
                                emax = max( emax,abs( work( ii + (nb+k  )*n ) )+abs( work( ii + (&
                                          nb+k+1)*n ) ) )
                             end do
                             remax = one / emax
                          ! else if iscomplex(k)==-1
                             ! second eigenvector of conjugate pair
                             ! reuse same remax as previous k
                          end if
                          call stdlib${ii}$_${ri}$scal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_${ri}$lacpy( 'F', n, nb-iv+1,work( 1_${ik}$ + (nb+iv)*n ), n,vr( 1_${ik}$, ki2 ), &
                                 ldvr )
                       iv = nb
                    else
                       iv = iv - 1_${ik}$
                    end if
                 end if ! blocked back-transform
                 is = is - 1_${ik}$
                 if( ip/=0_${ik}$ )is = is - 1_${ik}$
              end do loop_140
           end if
           if( leftv ) then
              ! ============================================================
              ! compute left eigenvectors.
              ! iv is index of column in current block.
              ! for complex left vector, uses iv for real part and iv+1 for complex part.
              ! non-blocked version always uses iv=1;
              ! blocked     version starts with iv=1, goes up to nb-1 or nb.
              ! (note the "0-th" column is used for 1-norms computed above.)
              iv = 1_${ik}$
              ip = 0_${ik}$
              is = 1_${ik}$
              loop_260: do ki = 1, n
                 if( ip==1_${ik}$ ) then
                    ! previous iteration (ki-1) was first of conjugate pair,
                    ! so this ki is second of conjugate pair; skip to end of loop
                    ip = -1_${ik}$
                    cycle loop_260
                 else if( ki==n ) then
                    ! last column, so this ki must be real eigenvalue
                    ip = 0_${ik}$
                 else if( t( ki+1, ki )==zero ) then
                    ! zero on sub-diagonal, so this ki is real eigenvalue
                    ip = 0_${ik}$
                 else
                    ! non-zero on sub-diagonal, so this ki is first of conjugate pair
                    ip = 1_${ik}$
                 end if
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_260
                 end if
                 ! compute the ki-th eigenvalue (wr,wi).
                 wr = t( ki, ki )
                 wi = zero
                 if( ip/=0_${ik}$ )wi = sqrt( abs( t( ki, ki+1 ) ) )*sqrt( abs( t( ki+1, ki ) ) )
                 smin = max( ulp*( abs( wr )+abs( wi ) ), smlnum )
                 if( ip==0_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! real left eigenvector
                    work( ki + iv*n ) = one
                    ! form right-hand side.
                    do k = ki + 1, n
                       work( k + iv*n ) = -t( ki, k )
                    end do
                    ! solve transposed quasi-triangular system:
                    ! [ t(ki+1:n,ki+1:n) - wr ]**t * x = scale*work
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 1_${ik}$
                    loop_170: do j = ki + 1, n
                       if( j<jnxt )cycle loop_170
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+iv*n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+iv*n ) = work( j+iv*n ) -stdlib${ii}$_${ri}$dot( j-ki-1, t( ki+1, j ), 1_${ik}$,&
                                    work( ki+1+iv*n ), 1_${ik}$ )
                          ! solve [ t(j,j) - wr ]**t * x = work
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+iv*n ), 1_${ik}$ )
                                    
                          work( j+iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j+iv*n ) ), vmax )
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work( ki+iv*n ), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+iv*n ) = work( j+iv*n ) -stdlib${ii}$_${ri}$dot( j-ki-1, t( ki+1, j ), 1_${ik}$,&
                                    work( ki+1+iv*n ), 1_${ik}$ )
                          work( j+1+iv*n ) = work( j+1+iv*n ) -stdlib${ii}$_${ri}$dot( j-ki-1, t( ki+1, j+1 )&
                                    , 1_${ik}$,work( ki+1+iv*n ), 1_${ik}$ )
                          ! solve
                          ! [ t(j,j)-wr   t(j,j+1)      ]**t * x = scale*( work1 )
                          ! [ t(j+1,j)    t(j+1,j+1)-wr ]                ( work2 )
                          call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 1_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,zero, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one )call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work( ki+iv*n ), 1_${ik}$ )
                                    
                          work( j  +iv*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+1+iv*n ) = x( 2_${ik}$, 1_${ik}$ )
                          vmax = max( abs( work( j  +iv*n ) ),abs( work( j+1+iv*n ) ), vmax )
                                    
                          vcrit = bignum / vmax
                       end if
                    end do loop_170
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vl and normalize.
                       call stdlib${ii}$_${ri}$copy( n-ki+1, work( ki + iv*n ), 1_${ik}$,vl( ki, is ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                       remax = one / abs( vl( ii, is ) )
                       call stdlib${ii}$_${ri}$scal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki<n )call stdlib${ii}$_${ri}$gemv( 'N', n, n-ki, one,vl( 1_${ik}$, ki+1 ), ldvl,work( &
                                 ki+1 + iv*n ), 1_${ik}$,work( ki   + iv*n ), vl( 1_${ik}$, ki ), 1_${ik}$ )
                       ii = stdlib${ii}$_i${ri}$amax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                       remax = one / abs( vl( ii, ki ) )
                       call stdlib${ii}$_${ri}$scal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out above vector
                       ! could go from ki-nv+1 to ki-1
                       do k = 1, ki - 1
                          work( k + iv*n ) = zero
                       end do
                       iscomplex( iv ) = ip
                       ! back-transform and normalization is done below
                    end if
                 else
                    ! --------------------------------------------------------
                    ! complex left eigenvector.
                    ! initial solve:
                    ! [ ( t(ki,ki)    t(ki,ki+1)  )**t - (wr - i* wi) ]*x = 0.
                    ! [ ( t(ki+1,ki) t(ki+1,ki+1) )                   ]
                    if( abs( t( ki, ki+1 ) )>=abs( t( ki+1, ki ) ) ) then
                       work( ki   + (iv  )*n ) = wi / t( ki, ki+1 )
                       work( ki+1 + (iv+1)*n ) = one
                    else
                       work( ki   + (iv  )*n ) = one
                       work( ki+1 + (iv+1)*n ) = -wi / t( ki+1, ki )
                    end if
                    work( ki+1 + (iv  )*n ) = zero
                    work( ki   + (iv+1)*n ) = zero
                    ! form right-hand side.
                    do k = ki + 2, n
                       work( k+(iv  )*n ) = -work( ki  +(iv  )*n )*t(ki,  k)
                       work( k+(iv+1)*n ) = -work( ki+1+(iv+1)*n )*t(ki+1,k)
                    end do
                    ! solve transposed quasi-triangular system:
                    ! [ t(ki+2:n,ki+2:n)**t - (wr-i*wi) ]*x = work1+i*work2
                    vmax = one
                    vcrit = bignum
                    jnxt = ki + 2_${ik}$
                    loop_200: do j = ki + 2, n
                       if( j<jnxt )cycle loop_200
                       j1 = j
                       j2 = j
                       jnxt = j + 1_${ik}$
                       if( j<n ) then
                          if( t( j+1, j )/=zero ) then
                             j2 = j + 1_${ik}$
                             jnxt = j + 2_${ik}$
                          end if
                       end if
                       if( j1==j2 ) then
                          ! 1-by-1 diagonal block
                          ! scale if necessary to avoid overflow when
                          ! forming the right-hand side elements.
                          if( work( j )>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work(ki+(iv  )*n), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work(ki+(iv+1)*n), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j+(iv  )*n ) = work( j+(iv)*n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, j )&
                                    , 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j+(iv+1)*n ) = work( j+(iv+1)*n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, &
                                    j ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          ! solve [ t(j,j)-(wr-i*wi) ]*(x11+i*x12)= wk+i*wk2
                          call stdlib${ii}$_${ri}$laln2( .false., 1_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work(ki+(iv  )*n), 1_${ik}$)
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work(ki+(iv+1)*n), 1_${ik}$)
                          end if
                          work( j+(iv  )*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j+(iv+1)*n ) = x( 1_${ik}$, 2_${ik}$ )
                          vmax = max( abs( work( j+(iv  )*n ) ),abs( work( j+(iv+1)*n ) ), vmax )
                                    
                          vcrit = bignum / vmax
                       else
                          ! 2-by-2 diagonal block
                          ! scale if necessary to avoid overflow when forming
                          ! the right-hand side elements.
                          beta = max( work( j ), work( j+1 ) )
                          if( beta>vcrit ) then
                             rec = one / vmax
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work(ki+(iv  )*n), 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n-ki+1, rec, work(ki+(iv+1)*n), 1_${ik}$ )
                             vmax = one
                             vcrit = bignum
                          end if
                          work( j  +(iv  )*n ) = work( j+(iv)*n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2, &
                                    j ), 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j  +(iv+1)*n ) = work( j+(iv+1)*n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2,&
                                     j ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          work( j+1+(iv  )*n ) = work( j+1+(iv)*n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+2,&
                                     j+1 ), 1_${ik}$,work( ki+2+(iv)*n ), 1_${ik}$ )
                          work( j+1+(iv+1)*n ) = work( j+1+(iv+1)*n ) -stdlib${ii}$_${ri}$dot( j-ki-2, t( ki+&
                                    2_${ik}$, j+1 ), 1_${ik}$,work( ki+2+(iv+1)*n ), 1_${ik}$ )
                          ! solve 2-by-2 complex linear equation
                          ! [ (t(j,j)   t(j,j+1)  )**t - (wr-i*wi)*i ]*x = scale*b
                          ! [ (t(j+1,j) t(j+1,j+1))                  ]
                          call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 2_${ik}$, smin, one, t( j, j ),ldt, one, one, &
                                    work( j+iv*n ), n, wr,-wi, x, 2_${ik}$, scale, xnorm, ierr )
                          ! scale if necessary
                          if( scale/=one ) then
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work(ki+(iv  )*n), 1_${ik}$)
                             call stdlib${ii}$_${ri}$scal( n-ki+1, scale, work(ki+(iv+1)*n), 1_${ik}$)
                          end if
                          work( j  +(iv  )*n ) = x( 1_${ik}$, 1_${ik}$ )
                          work( j  +(iv+1)*n ) = x( 1_${ik}$, 2_${ik}$ )
                          work( j+1+(iv  )*n ) = x( 2_${ik}$, 1_${ik}$ )
                          work( j+1+(iv+1)*n ) = x( 2_${ik}$, 2_${ik}$ )
                          vmax = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 1_${ik}$, 2_${ik}$ ) ),abs( x( 2_${ik}$, 1_${ik}$ ) ), abs( x(&
                                     2_${ik}$, 2_${ik}$ ) ),vmax )
                          vcrit = bignum / vmax
                       end if
                    end do loop_200
                    ! copy the vector x or q*x to vl and normalize.
                    if( .not.over ) then
                       ! ------------------------------
                       ! no back-transform: copy x to vl and normalize.
                       call stdlib${ii}$_${ri}$copy( n-ki+1, work( ki + (iv  )*n ), 1_${ik}$,vl( ki, is   ), 1_${ik}$ )
                                 
                       call stdlib${ii}$_${ri}$copy( n-ki+1, work( ki + (iv+1)*n ), 1_${ik}$,vl( ki, is+1 ), 1_${ik}$ )
                                 
                       emax = zero
                       do k = ki, n
                          emax = max( emax, abs( vl( k, is   ) )+abs( vl( k, is+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( n-ki+1, remax, vl( ki, is   ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n-ki+1, remax, vl( ki, is+1 ), 1_${ik}$ )
                       do k = 1, ki - 1
                          vl( k, is   ) = zero
                          vl( k, is+1 ) = zero
                       end do
                    else if( nb==1_${ik}$ ) then
                       ! ------------------------------
                       ! version 1: back-transform each vector with gemv, q*x.
                       if( ki<n-1 ) then
                          call stdlib${ii}$_${ri}$gemv( 'N', n, n-ki-1, one,vl( 1_${ik}$, ki+2 ), ldvl,work( ki+2 + &
                                    (iv)*n ), 1_${ik}$,work( ki   + (iv)*n ),vl( 1_${ik}$, ki ), 1_${ik}$ )
                          call stdlib${ii}$_${ri}$gemv( 'N', n, n-ki-1, one,vl( 1_${ik}$, ki+2 ), ldvl,work( ki+2 + &
                                    (iv+1)*n ), 1_${ik}$,work( ki+1 + (iv+1)*n ),vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                       else
                          call stdlib${ii}$_${ri}$scal( n, work(ki+  (iv  )*n), vl(1_${ik}$, ki  ), 1_${ik}$)
                          call stdlib${ii}$_${ri}$scal( n, work(ki+1+(iv+1)*n), vl(1_${ik}$, ki+1), 1_${ik}$)
                       end if
                       emax = zero
                       do k = 1, n
                          emax = max( emax, abs( vl( k, ki   ) )+abs( vl( k, ki+1 ) ) )
                       end do
                       remax = one / emax
                       call stdlib${ii}$_${ri}$scal( n, remax, vl( 1_${ik}$, ki   ), 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n, remax, vl( 1_${ik}$, ki+1 ), 1_${ik}$ )
                    else
                       ! ------------------------------
                       ! version 2: back-transform block of vectors with gemm
                       ! zero out above vector
                       ! could go from ki-nv+1 to ki-1
                       do k = 1, ki - 1
                          work( k + (iv  )*n ) = zero
                          work( k + (iv+1)*n ) = zero
                       end do
                       iscomplex( iv   ) =  ip
                       iscomplex( iv+1 ) = -ip
                       iv = iv + 1_${ik}$
                       ! back-transform and normalization is done below
                    end if
                 end if
                 if( nb>1_${ik}$ ) then
                    ! --------------------------------------------------------
                    ! blocked version of back-transform
                    ! for complex case, ki2 includes both vectors (ki and ki+1)
                    if( ip==0_${ik}$ ) then
                       ki2 = ki
                    else
                       ki2 = ki + 1_${ik}$
                    end if
                    ! columns 1:iv of work are valid vectors.
                    ! when the number of vectors stored reaches nb-1 or nb,
                    ! or if this was last vector, do the gemm
                    if( (iv>=nb-1) .or. (ki2==n) ) then
                       call stdlib${ii}$_${ri}$gemm( 'N', 'N', n, iv, n-ki2+iv, one,vl( 1_${ik}$, ki2-iv+1 ), ldvl,&
                                 work( ki2-iv+1 + (1_${ik}$)*n ), n,zero,work( 1_${ik}$ + (nb+1)*n ), n )
                       ! normalize vectors
                       do k = 1, iv
                          if( iscomplex(k)==0_${ik}$) then
                             ! real eigenvector
                             ii = stdlib${ii}$_i${ri}$amax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                             remax = one / abs( work( ii + (nb+k)*n ) )
                          else if( iscomplex(k)==1_${ik}$) then
                             ! first eigenvector of conjugate pair
                             emax = zero
                             do ii = 1, n
                                emax = max( emax,abs( work( ii + (nb+k  )*n ) )+abs( work( ii + (&
                                          nb+k+1)*n ) ) )
                             end do
                             remax = one / emax
                          ! else if iscomplex(k)==-1
                             ! second eigenvector of conjugate pair
                             ! reuse same remax as previous k
                          end if
                          call stdlib${ii}$_${ri}$scal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_${ri}$lacpy( 'F', n, iv,work( 1_${ik}$ + (nb+1)*n ), n,vl( 1_${ik}$, ki2-iv+1 ), &
                                 ldvl )
                       iv = 1_${ik}$
                    else
                       iv = iv + 1_${ik}$
                    end if
                 end if ! blocked back-transform
                 is = is + 1_${ik}$
                 if( ip/=0_${ik}$ )is = is + 1_${ik}$
              end do loop_260
           end if
           return
     end subroutine stdlib${ii}$_${ri}$trevc3

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_ctrevc3( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! CTREVC3 computes some or all of the right and/or left eigenvectors of
     !! a complex upper triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a complex general matrix:  A = Q*T*Q**H, as computed by CHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix. If Q is the unitary factor that reduces a matrix A to
     !! Schur form T, then Q*X and Q*Y are the matrices of right and left
     !! eigenvectors of A.
     !! This uses a Level 3 BLAS version of the back transformation.
               work, lwork, rwork, lrwork, info)
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, lwork, lrwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(inout) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmin = 8_${ik}$
           integer(${ik}$), parameter :: nbmax = 128_${ik}$
           
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, lquery, over, rightv, somev
           integer(${ik}$) :: i, ii, is, j, k, ki, iv, maxwrk, nb
           real(sp) :: ovfl, remax, scale, smin, smlnum, ulp, unfl
           complex(sp) :: cdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=sp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           bothv  = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv  = stdlib_lsame( side, 'L' ) .or. bothv
           allv  = stdlib_lsame( howmny, 'A' )
           over  = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           if( somev ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CTREVC', side // howmny, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           maxwrk = n + 2_${ik}$*n*nb
           work(1_${ik}$) = maxwrk
           rwork(1_${ik}$) = n
           lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ )
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -11_${ik}$
           else if( lwork<max( 1_${ik}$, 2_${ik}$*n ) .and. .not.lquery ) then
              info = -14_${ik}$
           else if ( lrwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -16_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CTREVC3', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! use blocked version of back-transformation if sufficient workspace.
           ! zero-out the workspace to avoid potential nan propagation.
           if( over .and. lwork >= n + 2_${ik}$*n*nbmin ) then
              nb = (lwork - n) / (2_${ik}$*n)
              nb = min( nb, nbmax )
              call stdlib${ii}$_claset( 'F', n, 1_${ik}$+2*nb, czero, czero, work, n )
           else
              nb = 1_${ik}$
           end if
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_slabad( unfl, ovfl )
           ulp = stdlib${ii}$_slamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ! store the diagonal elements of t in working array work.
           do i = 1, n
              work( i ) = t( i, i )
           end do
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           rwork( 1_${ik}$ ) = zero
           do j = 2, n
              rwork( j ) = stdlib${ii}$_scasum( j-1, t( 1_${ik}$, j ), 1_${ik}$ )
           end do
           if( rightv ) then
              ! ============================================================
              ! compute right eigenvectors.
              ! iv is index of column in current block.
              ! non-blocked version always uses iv=nb=1;
              ! blocked     version starts with iv=nb, goes down to 1.
              ! (note the "0-th" column is used to store the original diagonal.)
              iv = nb
              is = m
              loop_80: do ki = n, 1, -1
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_80
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 ! --------------------------------------------------------
                 ! complex right eigenvector
                 work( ki + iv*n ) = cone
                 ! form right-hand side.
                 do k = 1, ki - 1
                    work( k + iv*n ) = -t( k, ki )
                 end do
                 ! solve upper triangular system:
                 ! [ t(1:ki-1,1:ki-1) - t(ki,ki) ]*x = scale*work.
                 do k = 1, ki - 1
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki>1_${ik}$ ) then
                    call stdlib${ii}$_clatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', 'Y',ki-1, t, ldt, &
                              work( 1_${ik}$ + iv*n ), scale,rwork, info )
                    work( ki + iv*n ) = scale
                 end if
                 ! copy the vector x or q*x to vr and normalize.
                 if( .not.over ) then
                    ! ------------------------------
                    ! no back-transform: copy x to vr and normalize.
                    call stdlib${ii}$_ccopy( ki, work( 1_${ik}$ + iv*n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, is ) )
                    call stdlib${ii}$_csscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                    do k = ki + 1, n
                       vr( k, is ) = czero
                    end do
                 else if( nb==1_${ik}$ ) then
                    ! ------------------------------
                    ! version 1: back-transform each vector with gemv, q*x.
                    if( ki>1_${ik}$ )call stdlib${ii}$_cgemv( 'N', n, ki-1, cone, vr, ldvr,work( 1_${ik}$ + iv*n ), 1_${ik}$,&
                               cmplx( scale,KIND=sp),vr( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, ki ) )
                    call stdlib${ii}$_csscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                 else
                    ! ------------------------------
                    ! version 2: back-transform block of vectors with gemm
                    ! zero out below vector
                    do k = ki + 1, n
                       work( k + iv*n ) = czero
                    end do
                    ! columns iv:nb of work are valid vectors.
                    ! when the number of vectors stored reaches nb,
                    ! or if this was last vector, do the gemm
                    if( (iv==1_${ik}$) .or. (ki==1_${ik}$) ) then
                       call stdlib${ii}$_cgemm( 'N', 'N', n, nb-iv+1, ki+nb-iv, cone,vr, ldvr,work( 1_${ik}$ + &
                                 (iv)*n    ), n,czero,work( 1_${ik}$ + (nb+iv)*n ), n )
                       ! normalize vectors
                       do k = iv, nb
                          ii = stdlib${ii}$_icamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                          remax = one / cabs1( work( ii + (nb+k)*n ) )
                          call stdlib${ii}$_csscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_clacpy( 'F', n, nb-iv+1,work( 1_${ik}$ + (nb+iv)*n ), n,vr( 1_${ik}$, ki ), &
                                 ldvr )
                       iv = nb
                    else
                       iv = iv - 1_${ik}$
                    end if
                 end if
                 ! restore the original diagonal elements of t.
                 do k = 1, ki - 1
                    t( k, k ) = work( k )
                 end do
                 is = is - 1_${ik}$
              end do loop_80
           end if
           if( leftv ) then
              ! ============================================================
              ! compute left eigenvectors.
              ! iv is index of column in current block.
              ! non-blocked version always uses iv=1;
              ! blocked     version starts with iv=1, goes up to nb.
              ! (note the "0-th" column is used to store the original diagonal.)
              iv = 1_${ik}$
              is = 1_${ik}$
              loop_130: do ki = 1, n
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_130
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 ! --------------------------------------------------------
                 ! complex left eigenvector
                 work( ki + iv*n ) = cone
                 ! form right-hand side.
                 do k = ki + 1, n
                    work( k + iv*n ) = -conjg( t( ki, k ) )
                 end do
                 ! solve conjugate-transposed triangular system:
                 ! [ t(ki+1:n,ki+1:n) - t(ki,ki) ]**h * x = scale*work.
                 do k = ki + 1, n
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki<n ) then
                    call stdlib${ii}$_clatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT','Y', n-ki, t( &
                              ki+1, ki+1 ), ldt,work( ki+1 + iv*n ), scale, rwork, info )
                    work( ki + iv*n ) = scale
                 end if
                 ! copy the vector x or q*x to vl and normalize.
                 if( .not.over ) then
                    ! ------------------------------
                    ! no back-transform: copy x to vl and normalize.
                    call stdlib${ii}$_ccopy( n-ki+1, work( ki + iv*n ), 1_${ik}$, vl(ki,is), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                    remax = one / cabs1( vl( ii, is ) )
                    call stdlib${ii}$_csscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                    do k = 1, ki - 1
                       vl( k, is ) = czero
                    end do
                 else if( nb==1_${ik}$ ) then
                    ! ------------------------------
                    ! version 1: back-transform each vector with gemv, q*x.
                    if( ki<n )call stdlib${ii}$_cgemv( 'N', n, n-ki, cone, vl( 1_${ik}$, ki+1 ), ldvl,work( ki+&
                              1_${ik}$ + iv*n ), 1_${ik}$, cmplx( scale,KIND=sp),vl( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_icamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vl( ii, ki ) )
                    call stdlib${ii}$_csscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                 else
                    ! ------------------------------
                    ! version 2: back-transform block of vectors with gemm
                    ! zero out above vector
                    ! could go from ki-nv+1 to ki-1
                    do k = 1, ki - 1
                       work( k + iv*n ) = czero
                    end do
                    ! columns 1:iv of work are valid vectors.
                    ! when the number of vectors stored reaches nb,
                    ! or if this was last vector, do the gemm
                    if( (iv==nb) .or. (ki==n) ) then
                       call stdlib${ii}$_cgemm( 'N', 'N', n, iv, n-ki+iv, cone,vl( 1_${ik}$, ki-iv+1 ), ldvl,&
                                 work( ki-iv+1 + (1_${ik}$)*n ), n,czero,work( 1_${ik}$ + (nb+1)*n ), n )
                       ! normalize vectors
                       do k = 1, iv
                          ii = stdlib${ii}$_icamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                          remax = one / cabs1( work( ii + (nb+k)*n ) )
                          call stdlib${ii}$_csscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_clacpy( 'F', n, iv,work( 1_${ik}$ + (nb+1)*n ), n,vl( 1_${ik}$, ki-iv+1 ), &
                                 ldvl )
                       iv = 1_${ik}$
                    else
                       iv = iv + 1_${ik}$
                    end if
                 end if
                 ! restore the original diagonal elements of t.
                 do k = ki + 1, n
                    t( k, k ) = work( k )
                 end do
                 is = is + 1_${ik}$
              end do loop_130
           end if
           return
     end subroutine stdlib${ii}$_ctrevc3

     pure module subroutine stdlib${ii}$_ztrevc3( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! ZTREVC3 computes some or all of the right and/or left eigenvectors of
     !! a complex upper triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix. If Q is the unitary factor that reduces a matrix A to
     !! Schur form T, then Q*X and Q*Y are the matrices of right and left
     !! eigenvectors of A.
     !! This uses a Level 3 BLAS version of the back transformation.
               work, lwork, rwork, lrwork, info)
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, lwork, lrwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(inout) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmin = 8_${ik}$
           integer(${ik}$), parameter :: nbmax = 128_${ik}$
           
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, lquery, over, rightv, somev
           integer(${ik}$) :: i, ii, is, j, k, ki, iv, maxwrk, nb
           real(dp) :: ovfl, remax, scale, smin, smlnum, ulp, unfl
           complex(dp) :: cdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=dp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           bothv  = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv  = stdlib_lsame( side, 'L' ) .or. bothv
           allv  = stdlib_lsame( howmny, 'A' )
           over  = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           if( somev ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZTREVC', side // howmny, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           maxwrk = n + 2_${ik}$*n*nb
           work(1_${ik}$) = maxwrk
           rwork(1_${ik}$) = n
           lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ )
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -11_${ik}$
           else if( lwork<max( 1_${ik}$, 2_${ik}$*n ) .and. .not.lquery ) then
              info = -14_${ik}$
           else if ( lrwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -16_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTREVC3', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! use blocked version of back-transformation if sufficient workspace.
           ! zero-out the workspace to avoid potential nan propagation.
           if( over .and. lwork >= n + 2_${ik}$*n*nbmin ) then
              nb = (lwork - n) / (2_${ik}$*n)
              nb = min( nb, nbmax )
              call stdlib${ii}$_zlaset( 'F', n, 1_${ik}$+2*nb, czero, czero, work, n )
           else
              nb = 1_${ik}$
           end if
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_dlabad( unfl, ovfl )
           ulp = stdlib${ii}$_dlamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ! store the diagonal elements of t in working array work.
           do i = 1, n
              work( i ) = t( i, i )
           end do
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           rwork( 1_${ik}$ ) = zero
           do j = 2, n
              rwork( j ) = stdlib${ii}$_dzasum( j-1, t( 1_${ik}$, j ), 1_${ik}$ )
           end do
           if( rightv ) then
              ! ============================================================
              ! compute right eigenvectors.
              ! iv is index of column in current block.
              ! non-blocked version always uses iv=nb=1;
              ! blocked     version starts with iv=nb, goes down to 1.
              ! (note the "0-th" column is used to store the original diagonal.)
              iv = nb
              is = m
              loop_80: do ki = n, 1, -1
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_80
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 ! --------------------------------------------------------
                 ! complex right eigenvector
                 work( ki + iv*n ) = cone
                 ! form right-hand side.
                 do k = 1, ki - 1
                    work( k + iv*n ) = -t( k, ki )
                 end do
                 ! solve upper triangular system:
                 ! [ t(1:ki-1,1:ki-1) - t(ki,ki) ]*x = scale*work.
                 do k = 1, ki - 1
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki>1_${ik}$ ) then
                    call stdlib${ii}$_zlatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', 'Y',ki-1, t, ldt, &
                              work( 1_${ik}$ + iv*n ), scale,rwork, info )
                    work( ki + iv*n ) = scale
                 end if
                 ! copy the vector x or q*x to vr and normalize.
                 if( .not.over ) then
                    ! ------------------------------
                    ! no back-transform: copy x to vr and normalize.
                    call stdlib${ii}$_zcopy( ki, work( 1_${ik}$ + iv*n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, is ) )
                    call stdlib${ii}$_zdscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                    do k = ki + 1, n
                       vr( k, is ) = czero
                    end do
                 else if( nb==1_${ik}$ ) then
                    ! ------------------------------
                    ! version 1: back-transform each vector with gemv, q*x.
                    if( ki>1_${ik}$ )call stdlib${ii}$_zgemv( 'N', n, ki-1, cone, vr, ldvr,work( 1_${ik}$ + iv*n ), 1_${ik}$,&
                               cmplx( scale,KIND=dp),vr( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, ki ) )
                    call stdlib${ii}$_zdscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                 else
                    ! ------------------------------
                    ! version 2: back-transform block of vectors with gemm
                    ! zero out below vector
                    do k = ki + 1, n
                       work( k + iv*n ) = czero
                    end do
                    ! columns iv:nb of work are valid vectors.
                    ! when the number of vectors stored reaches nb,
                    ! or if this was last vector, do the gemm
                    if( (iv==1_${ik}$) .or. (ki==1_${ik}$) ) then
                       call stdlib${ii}$_zgemm( 'N', 'N', n, nb-iv+1, ki+nb-iv, cone,vr, ldvr,work( 1_${ik}$ + &
                                 (iv)*n    ), n,czero,work( 1_${ik}$ + (nb+iv)*n ), n )
                       ! normalize vectors
                       do k = iv, nb
                          ii = stdlib${ii}$_izamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                          remax = one / cabs1( work( ii + (nb+k)*n ) )
                          call stdlib${ii}$_zdscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_zlacpy( 'F', n, nb-iv+1,work( 1_${ik}$ + (nb+iv)*n ), n,vr( 1_${ik}$, ki ), &
                                 ldvr )
                       iv = nb
                    else
                       iv = iv - 1_${ik}$
                    end if
                 end if
                 ! restore the original diagonal elements of t.
                 do k = 1, ki - 1
                    t( k, k ) = work( k )
                 end do
                 is = is - 1_${ik}$
              end do loop_80
           end if
           if( leftv ) then
              ! ============================================================
              ! compute left eigenvectors.
              ! iv is index of column in current block.
              ! non-blocked version always uses iv=1;
              ! blocked     version starts with iv=1, goes up to nb.
              ! (note the "0-th" column is used to store the original diagonal.)
              iv = 1_${ik}$
              is = 1_${ik}$
              loop_130: do ki = 1, n
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_130
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 ! --------------------------------------------------------
                 ! complex left eigenvector
                 work( ki + iv*n ) = cone
                 ! form right-hand side.
                 do k = ki + 1, n
                    work( k + iv*n ) = -conjg( t( ki, k ) )
                 end do
                 ! solve conjugate-transposed triangular system:
                 ! [ t(ki+1:n,ki+1:n) - t(ki,ki) ]**h * x = scale*work.
                 do k = ki + 1, n
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki<n ) then
                    call stdlib${ii}$_zlatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT','Y', n-ki, t( &
                              ki+1, ki+1 ), ldt,work( ki+1 + iv*n ), scale, rwork, info )
                    work( ki + iv*n ) = scale
                 end if
                 ! copy the vector x or q*x to vl and normalize.
                 if( .not.over ) then
                    ! ------------------------------
                    ! no back-transform: copy x to vl and normalize.
                    call stdlib${ii}$_zcopy( n-ki+1, work( ki + iv*n ), 1_${ik}$, vl(ki,is), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                    remax = one / cabs1( vl( ii, is ) )
                    call stdlib${ii}$_zdscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                    do k = 1, ki - 1
                       vl( k, is ) = czero
                    end do
                 else if( nb==1_${ik}$ ) then
                    ! ------------------------------
                    ! version 1: back-transform each vector with gemv, q*x.
                    if( ki<n )call stdlib${ii}$_zgemv( 'N', n, n-ki, cone, vl( 1_${ik}$, ki+1 ), ldvl,work( ki+&
                              1_${ik}$ + iv*n ), 1_${ik}$, cmplx( scale,KIND=dp),vl( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_izamax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vl( ii, ki ) )
                    call stdlib${ii}$_zdscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                 else
                    ! ------------------------------
                    ! version 2: back-transform block of vectors with gemm
                    ! zero out above vector
                    ! could go from ki-nv+1 to ki-1
                    do k = 1, ki - 1
                       work( k + iv*n ) = czero
                    end do
                    ! columns 1:iv of work are valid vectors.
                    ! when the number of vectors stored reaches nb,
                    ! or if this was last vector, do the gemm
                    if( (iv==nb) .or. (ki==n) ) then
                       call stdlib${ii}$_zgemm( 'N', 'N', n, iv, n-ki+iv, cone,vl( 1_${ik}$, ki-iv+1 ), ldvl,&
                                 work( ki-iv+1 + (1_${ik}$)*n ), n,czero,work( 1_${ik}$ + (nb+1)*n ), n )
                       ! normalize vectors
                       do k = 1, iv
                          ii = stdlib${ii}$_izamax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                          remax = one / cabs1( work( ii + (nb+k)*n ) )
                          call stdlib${ii}$_zdscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_zlacpy( 'F', n, iv,work( 1_${ik}$ + (nb+1)*n ), n,vl( 1_${ik}$, ki-iv+1 ), &
                                 ldvl )
                       iv = 1_${ik}$
                    else
                       iv = iv + 1_${ik}$
                    end if
                 end if
                 ! restore the original diagonal elements of t.
                 do k = ki + 1, n
                    t( k, k ) = work( k )
                 end do
                 is = is + 1_${ik}$
              end do loop_130
           end if
           return
     end subroutine stdlib${ii}$_ztrevc3

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$trevc3( side, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, mm, m, &
     !! ZTREVC3: computes some or all of the right and/or left eigenvectors of
     !! a complex upper triangular matrix T.
     !! Matrices of this type are produced by the Schur factorization of
     !! a complex general matrix:  A = Q*T*Q**H, as computed by ZHSEQR.
     !! The right eigenvector x and the left eigenvector y of T corresponding
     !! to an eigenvalue w are defined by:
     !! T*x = w*x,     (y**H)*T = w*(y**H)
     !! where y**H denotes the conjugate transpose of the vector y.
     !! The eigenvalues are not input to this routine, but are read directly
     !! from the diagonal of T.
     !! This routine returns the matrices X and/or Y of right and left
     !! eigenvectors of T, or the products Q*X and/or Q*Y, where Q is an
     !! input matrix. If Q is the unitary factor that reduces a matrix A to
     !! Schur form T, then Q*X and Q*Y are the matrices of right and left
     !! eigenvectors of A.
     !! This uses a Level 3 BLAS version of the back transformation.
               work, lwork, rwork, lrwork, info)
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, side
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, lwork, lrwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(inout) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmin = 8_${ik}$
           integer(${ik}$), parameter :: nbmax = 128_${ik}$
           
           
           
           ! Local Scalars 
           logical(lk) :: allv, bothv, leftv, lquery, over, rightv, somev
           integer(${ik}$) :: i, ii, is, j, k, ki, iv, maxwrk, nb
           real(${ck}$) :: ovfl, remax, scale, smin, smlnum, ulp, unfl
           complex(${ck}$) :: cdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=${ck}$) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           bothv  = stdlib_lsame( side, 'B' )
           rightv = stdlib_lsame( side, 'R' ) .or. bothv
           leftv  = stdlib_lsame( side, 'L' ) .or. bothv
           allv  = stdlib_lsame( howmny, 'A' )
           over  = stdlib_lsame( howmny, 'B' )
           somev = stdlib_lsame( howmny, 'S' )
           ! set m to the number of columns required to store the selected
           ! eigenvectors.
           if( somev ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZTREVC', side // howmny, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           maxwrk = n + 2_${ik}$*n*nb
           work(1_${ik}$) = maxwrk
           rwork(1_${ik}$) = n
           lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ )
           if( .not.rightv .and. .not.leftv ) then
              info = -1_${ik}$
           else if( .not.allv .and. .not.over .and. .not.somev ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( leftv .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( rightv .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -11_${ik}$
           else if( lwork<max( 1_${ik}$, 2_${ik}$*n ) .and. .not.lquery ) then
              info = -14_${ik}$
           else if ( lrwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -16_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTREVC3', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( n==0 )return
           ! use blocked version of back-transformation if sufficient workspace.
           ! zero-out the workspace to avoid potential nan propagation.
           if( over .and. lwork >= n + 2_${ik}$*n*nbmin ) then
              nb = (lwork - n) / (2_${ik}$*n)
              nb = min( nb, nbmax )
              call stdlib${ii}$_${ci}$laset( 'F', n, 1_${ik}$+2*nb, czero, czero, work, n )
           else
              nb = 1_${ik}$
           end if
           ! set the constants to control overflow.
           unfl = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           ovfl = one / unfl
           call stdlib${ii}$_${c2ri(ci)}$labad( unfl, ovfl )
           ulp = stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           smlnum = unfl*( n / ulp )
           ! store the diagonal elements of t in working array work.
           do i = 1, n
              work( i ) = t( i, i )
           end do
           ! compute 1-norm of each column of strictly upper triangular
           ! part of t to control overflow in triangular solver.
           rwork( 1_${ik}$ ) = zero
           do j = 2, n
              rwork( j ) = stdlib${ii}$_${c2ri(ci)}$zasum( j-1, t( 1_${ik}$, j ), 1_${ik}$ )
           end do
           if( rightv ) then
              ! ============================================================
              ! compute right eigenvectors.
              ! iv is index of column in current block.
              ! non-blocked version always uses iv=nb=1;
              ! blocked     version starts with iv=nb, goes down to 1.
              ! (note the "0-th" column is used to store the original diagonal.)
              iv = nb
              is = m
              loop_80: do ki = n, 1, -1
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_80
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 ! --------------------------------------------------------
                 ! complex right eigenvector
                 work( ki + iv*n ) = cone
                 ! form right-hand side.
                 do k = 1, ki - 1
                    work( k + iv*n ) = -t( k, ki )
                 end do
                 ! solve upper triangular system:
                 ! [ t(1:ki-1,1:ki-1) - t(ki,ki) ]*x = scale*work.
                 do k = 1, ki - 1
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki>1_${ik}$ ) then
                    call stdlib${ii}$_${ci}$latrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', 'Y',ki-1, t, ldt, &
                              work( 1_${ik}$ + iv*n ), scale,rwork, info )
                    work( ki + iv*n ) = scale
                 end if
                 ! copy the vector x or q*x to vr and normalize.
                 if( .not.over ) then
                    ! ------------------------------
                    ! no back-transform: copy x to vr and normalize.
                    call stdlib${ii}$_${ci}$copy( ki, work( 1_${ik}$ + iv*n ), 1_${ik}$, vr( 1_${ik}$, is ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( ki, vr( 1_${ik}$, is ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, is ) )
                    call stdlib${ii}$_${ci}$dscal( ki, remax, vr( 1_${ik}$, is ), 1_${ik}$ )
                    do k = ki + 1, n
                       vr( k, is ) = czero
                    end do
                 else if( nb==1_${ik}$ ) then
                    ! ------------------------------
                    ! version 1: back-transform each vector with gemv, q*x.
                    if( ki>1_${ik}$ )call stdlib${ii}$_${ci}$gemv( 'N', n, ki-1, cone, vr, ldvr,work( 1_${ik}$ + iv*n ), 1_${ik}$,&
                               cmplx( scale,KIND=${ck}$),vr( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( n, vr( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vr( ii, ki ) )
                    call stdlib${ii}$_${ci}$dscal( n, remax, vr( 1_${ik}$, ki ), 1_${ik}$ )
                 else
                    ! ------------------------------
                    ! version 2: back-transform block of vectors with gemm
                    ! zero out below vector
                    do k = ki + 1, n
                       work( k + iv*n ) = czero
                    end do
                    ! columns iv:nb of work are valid vectors.
                    ! when the number of vectors stored reaches nb,
                    ! or if this was last vector, do the gemm
                    if( (iv==1_${ik}$) .or. (ki==1_${ik}$) ) then
                       call stdlib${ii}$_${ci}$gemm( 'N', 'N', n, nb-iv+1, ki+nb-iv, cone,vr, ldvr,work( 1_${ik}$ + &
                                 (iv)*n    ), n,czero,work( 1_${ik}$ + (nb+iv)*n ), n )
                       ! normalize vectors
                       do k = iv, nb
                          ii = stdlib${ii}$_i${ci}$amax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                          remax = one / cabs1( work( ii + (nb+k)*n ) )
                          call stdlib${ii}$_${ci}$dscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_${ci}$lacpy( 'F', n, nb-iv+1,work( 1_${ik}$ + (nb+iv)*n ), n,vr( 1_${ik}$, ki ), &
                                 ldvr )
                       iv = nb
                    else
                       iv = iv - 1_${ik}$
                    end if
                 end if
                 ! restore the original diagonal elements of t.
                 do k = 1, ki - 1
                    t( k, k ) = work( k )
                 end do
                 is = is - 1_${ik}$
              end do loop_80
           end if
           if( leftv ) then
              ! ============================================================
              ! compute left eigenvectors.
              ! iv is index of column in current block.
              ! non-blocked version always uses iv=1;
              ! blocked     version starts with iv=1, goes up to nb.
              ! (note the "0-th" column is used to store the original diagonal.)
              iv = 1_${ik}$
              is = 1_${ik}$
              loop_130: do ki = 1, n
                 if( somev ) then
                    if( .not.select( ki ) )cycle loop_130
                 end if
                 smin = max( ulp*( cabs1( t( ki, ki ) ) ), smlnum )
                 ! --------------------------------------------------------
                 ! complex left eigenvector
                 work( ki + iv*n ) = cone
                 ! form right-hand side.
                 do k = ki + 1, n
                    work( k + iv*n ) = -conjg( t( ki, k ) )
                 end do
                 ! solve conjugate-transposed triangular system:
                 ! [ t(ki+1:n,ki+1:n) - t(ki,ki) ]**h * x = scale*work.
                 do k = ki + 1, n
                    t( k, k ) = t( k, k ) - t( ki, ki )
                    if( cabs1( t( k, k ) )<smin )t( k, k ) = smin
                 end do
                 if( ki<n ) then
                    call stdlib${ii}$_${ci}$latrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT','Y', n-ki, t( &
                              ki+1, ki+1 ), ldt,work( ki+1 + iv*n ), scale, rwork, info )
                    work( ki + iv*n ) = scale
                 end if
                 ! copy the vector x or q*x to vl and normalize.
                 if( .not.over ) then
                    ! ------------------------------
                    ! no back-transform: copy x to vl and normalize.
                    call stdlib${ii}$_${ci}$copy( n-ki+1, work( ki + iv*n ), 1_${ik}$, vl(ki,is), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( n-ki+1, vl( ki, is ), 1_${ik}$ ) + ki - 1_${ik}$
                    remax = one / cabs1( vl( ii, is ) )
                    call stdlib${ii}$_${ci}$dscal( n-ki+1, remax, vl( ki, is ), 1_${ik}$ )
                    do k = 1, ki - 1
                       vl( k, is ) = czero
                    end do
                 else if( nb==1_${ik}$ ) then
                    ! ------------------------------
                    ! version 1: back-transform each vector with gemv, q*x.
                    if( ki<n )call stdlib${ii}$_${ci}$gemv( 'N', n, n-ki, cone, vl( 1_${ik}$, ki+1 ), ldvl,work( ki+&
                              1_${ik}$ + iv*n ), 1_${ik}$, cmplx( scale,KIND=${ck}$),vl( 1_${ik}$, ki ), 1_${ik}$ )
                    ii = stdlib${ii}$_i${ci}$amax( n, vl( 1_${ik}$, ki ), 1_${ik}$ )
                    remax = one / cabs1( vl( ii, ki ) )
                    call stdlib${ii}$_${ci}$dscal( n, remax, vl( 1_${ik}$, ki ), 1_${ik}$ )
                 else
                    ! ------------------------------
                    ! version 2: back-transform block of vectors with gemm
                    ! zero out above vector
                    ! could go from ki-nv+1 to ki-1
                    do k = 1, ki - 1
                       work( k + iv*n ) = czero
                    end do
                    ! columns 1:iv of work are valid vectors.
                    ! when the number of vectors stored reaches nb,
                    ! or if this was last vector, do the gemm
                    if( (iv==nb) .or. (ki==n) ) then
                       call stdlib${ii}$_${ci}$gemm( 'N', 'N', n, iv, n-ki+iv, cone,vl( 1_${ik}$, ki-iv+1 ), ldvl,&
                                 work( ki-iv+1 + (1_${ik}$)*n ), n,czero,work( 1_${ik}$ + (nb+1)*n ), n )
                       ! normalize vectors
                       do k = 1, iv
                          ii = stdlib${ii}$_i${ci}$amax( n, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                          remax = one / cabs1( work( ii + (nb+k)*n ) )
                          call stdlib${ii}$_${ci}$dscal( n, remax, work( 1_${ik}$ + (nb+k)*n ), 1_${ik}$ )
                       end do
                       call stdlib${ii}$_${ci}$lacpy( 'F', n, iv,work( 1_${ik}$ + (nb+1)*n ), n,vl( 1_${ik}$, ki-iv+1 ), &
                                 ldvl )
                       iv = 1_${ik}$
                    else
                       iv = iv + 1_${ik}$
                    end if
                 end if
                 ! restore the original diagonal elements of t.
                 do k = ki + 1, n
                    t( k, k ) = work( k )
                 end do
                 is = is + 1_${ik}$
              end do loop_130
           end if
           return
     end subroutine stdlib${ii}$_${ci}$trevc3

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_slaln2( ltrans, na, nw, smin, ca, a, lda, d1, d2, b,ldb, wr, wi, x, &
     !! SLALN2 solves a system of the form  (ca A - w D ) X = s B
     !! or (ca A**T - w D) X = s B   with possible scaling ("s") and
     !! perturbation of A.  (A**T means A-transpose.)
     !! A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
     !! real diagonal matrix, w is a real or complex value, and X and B are
     !! NA x 1 matrices -- real if w is real, complex if w is complex.  NA
     !! may be 1 or 2.
     !! If w is complex, X and B are represented as NA x 2 matrices,
     !! the first column of each being the real part and the second
     !! being the imaginary part.
     !! "s" is a scaling factor (<= 1), computed by SLALN2, which is
     !! so chosen that X can be computed without overflow.  X is further
     !! scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
     !! than overflow.
     !! If both singular values of (ca A - w D) are less than SMIN,
     !! SMIN*identity will be used instead of (ca A - w D).  If only one
     !! singular value is less than SMIN, one element of (ca A - w D) will be
     !! perturbed enough to make the smallest singular value roughly SMIN.
     !! If both singular values are at least SMIN, (ca A - w D) will not be
     !! perturbed.  In any case, the perturbation will be at most some small
     !! multiple of max( SMIN, ulp*norm(ca A - w D) ).  The singular values
     !! are computed by infinity-norm approximations, and thus will only be
     !! correct to a factor of 2 or so.
     !! Note: all input quantities are assumed to be smaller than overflow
     !! by a reasonable factor.  (See BIGNUM.)
               ldx, scale, xnorm, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: ltrans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldb, ldx, na, nw
           real(sp), intent(in) :: ca, d1, d2, smin, wi, wr
           real(sp), intent(out) :: scale, xnorm
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*), b(ldb,*)
           real(sp), intent(out) :: x(ldx,*)
       ! =====================================================================
           
           
           ! Local Scalars 
           integer(${ik}$) :: icmax, j
           real(sp) :: bbnd, bi1, bi2, bignum, bnorm, br1, br2, ci21, ci22, cmax, cnorm, cr21, &
           cr22, csi, csr, li21, lr21, smini, smlnum, temp, u22abs, ui11, ui11r, ui12, ui12s, &
                     ui22, ur11, ur11r, ur12, ur12s, ur22, xi1, xi2, xr1, xr2
           ! Local Arrays 
           logical(lk) :: cswap(4_${ik}$), rswap(4_${ik}$)
           integer(${ik}$) :: ipivot(4_${ik}$,4_${ik}$)
           real(sp) :: ci(2_${ik}$,2_${ik}$), civ(4_${ik}$), cr(2_${ik}$,2_${ik}$), crv(4_${ik}$)
           ! Intrinsic Functions 
           ! Equivalences 
           equivalence        ( ci( 1_${ik}$, 1_${ik}$ ), civ( 1_${ik}$ ) ),( cr( 1_${ik}$, 1_${ik}$ ), crv( 1_${ik}$ ) )
           ! Data Statements 
           cswap = [.false.,.false.,.true.,.true.]
           rswap = [.false.,.true.,.false.,.true.]
           ipivot = reshape([1_${ik}$,2_${ik}$,3_${ik}$,4_${ik}$,2_${ik}$,1_${ik}$,4_${ik}$,3_${ik}$,3_${ik}$,4_${ik}$,1_${ik}$,2_${ik}$,4_${ik}$,3_${ik}$,2_${ik}$,1_${ik}$],[4_${ik}$,4_${ik}$])
           ! Executable Statements 
           ! compute bignum
           smlnum = two*stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           bignum = one / smlnum
           smini = max( smin, smlnum )
           ! don't check for input errors
           info = 0_${ik}$
           ! standard initializations
           scale = one
           if( na==1_${ik}$ ) then
              ! 1 x 1  (i.e., scalar) system   c x = b
              if( nw==1_${ik}$ ) then
                 ! real 1x1 system.
                 ! c = ca a - w d
                 csr = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
                 cnorm = abs( csr )
                 ! if | c | < smini, use c = smini
                 if( cnorm<smini ) then
                    csr = smini
                    cnorm = smini
                    info = 1_${ik}$
                 end if
                 ! check scaling for  x = b / c
                 bnorm = abs( b( 1_${ik}$, 1_${ik}$ ) )
                 if( cnorm<one .and. bnorm>one ) then
                    if( bnorm>bignum*cnorm )scale = one / bnorm
                 end if
                 ! compute x
                 x( 1_${ik}$, 1_${ik}$ ) = ( b( 1_${ik}$, 1_${ik}$ )*scale ) / csr
                 xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) )
              else
                 ! complex 1x1 system (w is complex)
                 ! c = ca a - w d
                 csr = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
                 csi = -wi*d1
                 cnorm = abs( csr ) + abs( csi )
                 ! if | c | < smini, use c = smini
                 if( cnorm<smini ) then
                    csr = smini
                    csi = zero
                    cnorm = smini
                    info = 1_${ik}$
                 end if
                 ! check scaling for  x = b / c
                 bnorm = abs( b( 1_${ik}$, 1_${ik}$ ) ) + abs( b( 1_${ik}$, 2_${ik}$ ) )
                 if( cnorm<one .and. bnorm>one ) then
                    if( bnorm>bignum*cnorm )scale = one / bnorm
                 end if
                 ! compute x
                 call stdlib${ii}$_sladiv( scale*b( 1_${ik}$, 1_${ik}$ ), scale*b( 1_${ik}$, 2_${ik}$ ), csr, csi,x( 1_${ik}$, 1_${ik}$ ), x( 1_${ik}$, &
                           2_${ik}$ ) )
                 xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) ) + abs( x( 1_${ik}$, 2_${ik}$ ) )
              end if
           else
              ! 2x2 system
              ! compute the realpart of  c = ca a - w d  (or  ca a**t - w d,KIND=sp)
              cr( 1_${ik}$, 1_${ik}$ ) = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
              cr( 2_${ik}$, 2_${ik}$ ) = ca*a( 2_${ik}$, 2_${ik}$ ) - wr*d2
              if( ltrans ) then
                 cr( 1_${ik}$, 2_${ik}$ ) = ca*a( 2_${ik}$, 1_${ik}$ )
                 cr( 2_${ik}$, 1_${ik}$ ) = ca*a( 1_${ik}$, 2_${ik}$ )
              else
                 cr( 2_${ik}$, 1_${ik}$ ) = ca*a( 2_${ik}$, 1_${ik}$ )
                 cr( 1_${ik}$, 2_${ik}$ ) = ca*a( 1_${ik}$, 2_${ik}$ )
              end if
              if( nw==1_${ik}$ ) then
                 ! real2x2 system  (w is real,KIND=sp)
                 ! find the largest element in c
                 cmax = zero
                 icmax = 0_${ik}$
                 do j = 1, 4
                    if( abs( crv( j ) )>cmax ) then
                       cmax = abs( crv( j ) )
                       icmax = j
                    end if
                 end do
                 ! if norm(c) < smini, use smini*identity.
                 if( cmax<smini ) then
                    bnorm = max( abs( b( 1_${ik}$, 1_${ik}$ ) ), abs( b( 2_${ik}$, 1_${ik}$ ) ) )
                    if( smini<one .and. bnorm>one ) then
                       if( bnorm>bignum*smini )scale = one / bnorm
                    end if
                    temp = scale / smini
                    x( 1_${ik}$, 1_${ik}$ ) = temp*b( 1_${ik}$, 1_${ik}$ )
                    x( 2_${ik}$, 1_${ik}$ ) = temp*b( 2_${ik}$, 1_${ik}$ )
                    xnorm = temp*bnorm
                    info = 1_${ik}$
                    return
                 end if
                 ! gaussian elimination with complete pivoting.
                 ur11 = crv( icmax )
                 cr21 = crv( ipivot( 2_${ik}$, icmax ) )
                 ur12 = crv( ipivot( 3_${ik}$, icmax ) )
                 cr22 = crv( ipivot( 4_${ik}$, icmax ) )
                 ur11r = one / ur11
                 lr21 = ur11r*cr21
                 ur22 = cr22 - ur12*lr21
                 ! if smaller pivot < smini, use smini
                 if( abs( ur22 )<smini ) then
                    ur22 = smini
                    info = 1_${ik}$
                 end if
                 if( rswap( icmax ) ) then
                    br1 = b( 2_${ik}$, 1_${ik}$ )
                    br2 = b( 1_${ik}$, 1_${ik}$ )
                 else
                    br1 = b( 1_${ik}$, 1_${ik}$ )
                    br2 = b( 2_${ik}$, 1_${ik}$ )
                 end if
                 br2 = br2 - lr21*br1
                 bbnd = max( abs( br1*( ur22*ur11r ) ), abs( br2 ) )
                 if( bbnd>one .and. abs( ur22 )<one ) then
                    if( bbnd>=bignum*abs( ur22 ) )scale = one / bbnd
                 end if
                 xr2 = ( br2*scale ) / ur22
                 xr1 = ( scale*br1 )*ur11r - xr2*( ur11r*ur12 )
                 if( cswap( icmax ) ) then
                    x( 1_${ik}$, 1_${ik}$ ) = xr2
                    x( 2_${ik}$, 1_${ik}$ ) = xr1
                 else
                    x( 1_${ik}$, 1_${ik}$ ) = xr1
                    x( 2_${ik}$, 1_${ik}$ ) = xr2
                 end if
                 xnorm = max( abs( xr1 ), abs( xr2 ) )
                 ! further scaling if  norm(a) norm(x) > overflow
                 if( xnorm>one .and. cmax>one ) then
                    if( xnorm>bignum / cmax ) then
                       temp = cmax / bignum
                       x( 1_${ik}$, 1_${ik}$ ) = temp*x( 1_${ik}$, 1_${ik}$ )
                       x( 2_${ik}$, 1_${ik}$ ) = temp*x( 2_${ik}$, 1_${ik}$ )
                       xnorm = temp*xnorm
                       scale = temp*scale
                    end if
                 end if
              else
                 ! complex 2x2 system  (w is complex)
                 ! find the largest element in c
                 ci( 1_${ik}$, 1_${ik}$ ) = -wi*d1
                 ci( 2_${ik}$, 1_${ik}$ ) = zero
                 ci( 1_${ik}$, 2_${ik}$ ) = zero
                 ci( 2_${ik}$, 2_${ik}$ ) = -wi*d2
                 cmax = zero
                 icmax = 0_${ik}$
                 do j = 1, 4
                    if( abs( crv( j ) )+abs( civ( j ) )>cmax ) then
                       cmax = abs( crv( j ) ) + abs( civ( j ) )
                       icmax = j
                    end if
                 end do
                 ! if norm(c) < smini, use smini*identity.
                 if( cmax<smini ) then
                    bnorm = max( abs( b( 1_${ik}$, 1_${ik}$ ) )+abs( b( 1_${ik}$, 2_${ik}$ ) ),abs( b( 2_${ik}$, 1_${ik}$ ) )+abs( b( 2_${ik}$, 2_${ik}$ )&
                               ) )
                    if( smini<one .and. bnorm>one ) then
                       if( bnorm>bignum*smini )scale = one / bnorm
                    end if
                    temp = scale / smini
                    x( 1_${ik}$, 1_${ik}$ ) = temp*b( 1_${ik}$, 1_${ik}$ )
                    x( 2_${ik}$, 1_${ik}$ ) = temp*b( 2_${ik}$, 1_${ik}$ )
                    x( 1_${ik}$, 2_${ik}$ ) = temp*b( 1_${ik}$, 2_${ik}$ )
                    x( 2_${ik}$, 2_${ik}$ ) = temp*b( 2_${ik}$, 2_${ik}$ )
                    xnorm = temp*bnorm
                    info = 1_${ik}$
                    return
                 end if
                 ! gaussian elimination with complete pivoting.
                 ur11 = crv( icmax )
                 ui11 = civ( icmax )
                 cr21 = crv( ipivot( 2_${ik}$, icmax ) )
                 ci21 = civ( ipivot( 2_${ik}$, icmax ) )
                 ur12 = crv( ipivot( 3_${ik}$, icmax ) )
                 ui12 = civ( ipivot( 3_${ik}$, icmax ) )
                 cr22 = crv( ipivot( 4_${ik}$, icmax ) )
                 ci22 = civ( ipivot( 4_${ik}$, icmax ) )
                 if( icmax==1_${ik}$ .or. icmax==4_${ik}$ ) then
                    ! code when off-diagonals of pivoted c are real
                    if( abs( ur11 )>abs( ui11 ) ) then
                       temp = ui11 / ur11
                       ur11r = one / ( ur11*( one+temp**2_${ik}$ ) )
                       ui11r = -temp*ur11r
                    else
                       temp = ur11 / ui11
                       ui11r = -one / ( ui11*( one+temp**2_${ik}$ ) )
                       ur11r = -temp*ui11r
                    end if
                    lr21 = cr21*ur11r
                    li21 = cr21*ui11r
                    ur12s = ur12*ur11r
                    ui12s = ur12*ui11r
                    ur22 = cr22 - ur12*lr21
                    ui22 = ci22 - ur12*li21
                 else
                    ! code when diagonals of pivoted c are real
                    ur11r = one / ur11
                    ui11r = zero
                    lr21 = cr21*ur11r
                    li21 = ci21*ur11r
                    ur12s = ur12*ur11r
                    ui12s = ui12*ur11r
                    ur22 = cr22 - ur12*lr21 + ui12*li21
                    ui22 = -ur12*li21 - ui12*lr21
                 end if
                 u22abs = abs( ur22 ) + abs( ui22 )
                 ! if smaller pivot < smini, use smini
                 if( u22abs<smini ) then
                    ur22 = smini
                    ui22 = zero
                    info = 1_${ik}$
                 end if
                 if( rswap( icmax ) ) then
                    br2 = b( 1_${ik}$, 1_${ik}$ )
                    br1 = b( 2_${ik}$, 1_${ik}$ )
                    bi2 = b( 1_${ik}$, 2_${ik}$ )
                    bi1 = b( 2_${ik}$, 2_${ik}$ )
                 else
                    br1 = b( 1_${ik}$, 1_${ik}$ )
                    br2 = b( 2_${ik}$, 1_${ik}$ )
                    bi1 = b( 1_${ik}$, 2_${ik}$ )
                    bi2 = b( 2_${ik}$, 2_${ik}$ )
                 end if
                 br2 = br2 - lr21*br1 + li21*bi1
                 bi2 = bi2 - li21*br1 - lr21*bi1
                 bbnd = max( ( abs( br1 )+abs( bi1 ) )*( u22abs*( abs( ur11r )+abs( ui11r ) ) ),&
                           abs( br2 )+abs( bi2 ) )
                 if( bbnd>one .and. u22abs<one ) then
                    if( bbnd>=bignum*u22abs ) then
                       scale = one / bbnd
                       br1 = scale*br1
                       bi1 = scale*bi1
                       br2 = scale*br2
                       bi2 = scale*bi2
                    end if
                 end if
                 call stdlib${ii}$_sladiv( br2, bi2, ur22, ui22, xr2, xi2 )
                 xr1 = ur11r*br1 - ui11r*bi1 - ur12s*xr2 + ui12s*xi2
                 xi1 = ui11r*br1 + ur11r*bi1 - ui12s*xr2 - ur12s*xi2
                 if( cswap( icmax ) ) then
                    x( 1_${ik}$, 1_${ik}$ ) = xr2
                    x( 2_${ik}$, 1_${ik}$ ) = xr1
                    x( 1_${ik}$, 2_${ik}$ ) = xi2
                    x( 2_${ik}$, 2_${ik}$ ) = xi1
                 else
                    x( 1_${ik}$, 1_${ik}$ ) = xr1
                    x( 2_${ik}$, 1_${ik}$ ) = xr2
                    x( 1_${ik}$, 2_${ik}$ ) = xi1
                    x( 2_${ik}$, 2_${ik}$ ) = xi2
                 end if
                 xnorm = max( abs( xr1 )+abs( xi1 ), abs( xr2 )+abs( xi2 ) )
                 ! further scaling if  norm(a) norm(x) > overflow
                 if( xnorm>one .and. cmax>one ) then
                    if( xnorm>bignum / cmax ) then
                       temp = cmax / bignum
                       x( 1_${ik}$, 1_${ik}$ ) = temp*x( 1_${ik}$, 1_${ik}$ )
                       x( 2_${ik}$, 1_${ik}$ ) = temp*x( 2_${ik}$, 1_${ik}$ )
                       x( 1_${ik}$, 2_${ik}$ ) = temp*x( 1_${ik}$, 2_${ik}$ )
                       x( 2_${ik}$, 2_${ik}$ ) = temp*x( 2_${ik}$, 2_${ik}$ )
                       xnorm = temp*xnorm
                       scale = temp*scale
                    end if
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_slaln2

     pure module subroutine stdlib${ii}$_dlaln2( ltrans, na, nw, smin, ca, a, lda, d1, d2, b,ldb, wr, wi, x, &
     !! DLALN2 solves a system of the form  (ca A - w D ) X = s B
     !! or (ca A**T - w D) X = s B   with possible scaling ("s") and
     !! perturbation of A.  (A**T means A-transpose.)
     !! A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
     !! real diagonal matrix, w is a real or complex value, and X and B are
     !! NA x 1 matrices -- real if w is real, complex if w is complex.  NA
     !! may be 1 or 2.
     !! If w is complex, X and B are represented as NA x 2 matrices,
     !! the first column of each being the real part and the second
     !! being the imaginary part.
     !! "s" is a scaling factor (<= 1), computed by DLALN2, which is
     !! so chosen that X can be computed without overflow.  X is further
     !! scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
     !! than overflow.
     !! If both singular values of (ca A - w D) are less than SMIN,
     !! SMIN*identity will be used instead of (ca A - w D).  If only one
     !! singular value is less than SMIN, one element of (ca A - w D) will be
     !! perturbed enough to make the smallest singular value roughly SMIN.
     !! If both singular values are at least SMIN, (ca A - w D) will not be
     !! perturbed.  In any case, the perturbation will be at most some small
     !! multiple of max( SMIN, ulp*norm(ca A - w D) ).  The singular values
     !! are computed by infinity-norm approximations, and thus will only be
     !! correct to a factor of 2 or so.
     !! Note: all input quantities are assumed to be smaller than overflow
     !! by a reasonable factor.  (See BIGNUM.)
               ldx, scale, xnorm, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: ltrans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldb, ldx, na, nw
           real(dp), intent(in) :: ca, d1, d2, smin, wi, wr
           real(dp), intent(out) :: scale, xnorm
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*), b(ldb,*)
           real(dp), intent(out) :: x(ldx,*)
       ! =====================================================================
           
           
           ! Local Scalars 
           integer(${ik}$) :: icmax, j
           real(dp) :: bbnd, bi1, bi2, bignum, bnorm, br1, br2, ci21, ci22, cmax, cnorm, cr21, &
           cr22, csi, csr, li21, lr21, smini, smlnum, temp, u22abs, ui11, ui11r, ui12, ui12s, &
                     ui22, ur11, ur11r, ur12, ur12s, ur22, xi1, xi2, xr1, xr2
           ! Local Arrays 
           logical(lk) :: rswap(4_${ik}$), zswap(4_${ik}$)
           integer(${ik}$) :: ipivot(4_${ik}$,4_${ik}$)
           real(dp) :: ci(2_${ik}$,2_${ik}$), civ(4_${ik}$), cr(2_${ik}$,2_${ik}$), crv(4_${ik}$)
           ! Intrinsic Functions 
           ! Equivalences 
           equivalence        ( ci( 1_${ik}$, 1_${ik}$ ), civ( 1_${ik}$ ) ),( cr( 1_${ik}$, 1_${ik}$ ), crv( 1_${ik}$ ) )
           ! Data Statements 
           zswap = [.false.,.false.,.true.,.true.]
           rswap = [.false.,.true.,.false.,.true.]
           ipivot = reshape([1_${ik}$,2_${ik}$,3_${ik}$,4_${ik}$,2_${ik}$,1_${ik}$,4_${ik}$,3_${ik}$,3_${ik}$,4_${ik}$,1_${ik}$,2_${ik}$,4_${ik}$,3_${ik}$,2_${ik}$,1_${ik}$],[4_${ik}$,4_${ik}$])
           ! Executable Statements 
           ! compute bignum
           smlnum = two*stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           bignum = one / smlnum
           smini = max( smin, smlnum )
           ! don't check for input errors
           info = 0_${ik}$
           ! standard initializations
           scale = one
           if( na==1_${ik}$ ) then
              ! 1 x 1  (i.e., scalar) system   c x = b
              if( nw==1_${ik}$ ) then
                 ! real 1x1 system.
                 ! c = ca a - w d
                 csr = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
                 cnorm = abs( csr )
                 ! if | c | < smini, use c = smini
                 if( cnorm<smini ) then
                    csr = smini
                    cnorm = smini
                    info = 1_${ik}$
                 end if
                 ! check scaling for  x = b / c
                 bnorm = abs( b( 1_${ik}$, 1_${ik}$ ) )
                 if( cnorm<one .and. bnorm>one ) then
                    if( bnorm>bignum*cnorm )scale = one / bnorm
                 end if
                 ! compute x
                 x( 1_${ik}$, 1_${ik}$ ) = ( b( 1_${ik}$, 1_${ik}$ )*scale ) / csr
                 xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) )
              else
                 ! complex 1x1 system (w is complex)
                 ! c = ca a - w d
                 csr = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
                 csi = -wi*d1
                 cnorm = abs( csr ) + abs( csi )
                 ! if | c | < smini, use c = smini
                 if( cnorm<smini ) then
                    csr = smini
                    csi = zero
                    cnorm = smini
                    info = 1_${ik}$
                 end if
                 ! check scaling for  x = b / c
                 bnorm = abs( b( 1_${ik}$, 1_${ik}$ ) ) + abs( b( 1_${ik}$, 2_${ik}$ ) )
                 if( cnorm<one .and. bnorm>one ) then
                    if( bnorm>bignum*cnorm )scale = one / bnorm
                 end if
                 ! compute x
                 call stdlib${ii}$_dladiv( scale*b( 1_${ik}$, 1_${ik}$ ), scale*b( 1_${ik}$, 2_${ik}$ ), csr, csi,x( 1_${ik}$, 1_${ik}$ ), x( 1_${ik}$, &
                           2_${ik}$ ) )
                 xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) ) + abs( x( 1_${ik}$, 2_${ik}$ ) )
              end if
           else
              ! 2x2 system
              ! compute the realpart of  c = ca a - w d  (or  ca a**t - w d,KIND=dp)
              cr( 1_${ik}$, 1_${ik}$ ) = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
              cr( 2_${ik}$, 2_${ik}$ ) = ca*a( 2_${ik}$, 2_${ik}$ ) - wr*d2
              if( ltrans ) then
                 cr( 1_${ik}$, 2_${ik}$ ) = ca*a( 2_${ik}$, 1_${ik}$ )
                 cr( 2_${ik}$, 1_${ik}$ ) = ca*a( 1_${ik}$, 2_${ik}$ )
              else
                 cr( 2_${ik}$, 1_${ik}$ ) = ca*a( 2_${ik}$, 1_${ik}$ )
                 cr( 1_${ik}$, 2_${ik}$ ) = ca*a( 1_${ik}$, 2_${ik}$ )
              end if
              if( nw==1_${ik}$ ) then
                 ! real2x2 system  (w is real,KIND=dp)
                 ! find the largest element in c
                 cmax = zero
                 icmax = 0_${ik}$
                 do j = 1, 4
                    if( abs( crv( j ) )>cmax ) then
                       cmax = abs( crv( j ) )
                       icmax = j
                    end if
                 end do
                 ! if norm(c) < smini, use smini*identity.
                 if( cmax<smini ) then
                    bnorm = max( abs( b( 1_${ik}$, 1_${ik}$ ) ), abs( b( 2_${ik}$, 1_${ik}$ ) ) )
                    if( smini<one .and. bnorm>one ) then
                       if( bnorm>bignum*smini )scale = one / bnorm
                    end if
                    temp = scale / smini
                    x( 1_${ik}$, 1_${ik}$ ) = temp*b( 1_${ik}$, 1_${ik}$ )
                    x( 2_${ik}$, 1_${ik}$ ) = temp*b( 2_${ik}$, 1_${ik}$ )
                    xnorm = temp*bnorm
                    info = 1_${ik}$
                    return
                 end if
                 ! gaussian elimination with complete pivoting.
                 ur11 = crv( icmax )
                 cr21 = crv( ipivot( 2_${ik}$, icmax ) )
                 ur12 = crv( ipivot( 3_${ik}$, icmax ) )
                 cr22 = crv( ipivot( 4_${ik}$, icmax ) )
                 ur11r = one / ur11
                 lr21 = ur11r*cr21
                 ur22 = cr22 - ur12*lr21
                 ! if smaller pivot < smini, use smini
                 if( abs( ur22 )<smini ) then
                    ur22 = smini
                    info = 1_${ik}$
                 end if
                 if( rswap( icmax ) ) then
                    br1 = b( 2_${ik}$, 1_${ik}$ )
                    br2 = b( 1_${ik}$, 1_${ik}$ )
                 else
                    br1 = b( 1_${ik}$, 1_${ik}$ )
                    br2 = b( 2_${ik}$, 1_${ik}$ )
                 end if
                 br2 = br2 - lr21*br1
                 bbnd = max( abs( br1*( ur22*ur11r ) ), abs( br2 ) )
                 if( bbnd>one .and. abs( ur22 )<one ) then
                    if( bbnd>=bignum*abs( ur22 ) )scale = one / bbnd
                 end if
                 xr2 = ( br2*scale ) / ur22
                 xr1 = ( scale*br1 )*ur11r - xr2*( ur11r*ur12 )
                 if( zswap( icmax ) ) then
                    x( 1_${ik}$, 1_${ik}$ ) = xr2
                    x( 2_${ik}$, 1_${ik}$ ) = xr1
                 else
                    x( 1_${ik}$, 1_${ik}$ ) = xr1
                    x( 2_${ik}$, 1_${ik}$ ) = xr2
                 end if
                 xnorm = max( abs( xr1 ), abs( xr2 ) )
                 ! further scaling if  norm(a) norm(x) > overflow
                 if( xnorm>one .and. cmax>one ) then
                    if( xnorm>bignum / cmax ) then
                       temp = cmax / bignum
                       x( 1_${ik}$, 1_${ik}$ ) = temp*x( 1_${ik}$, 1_${ik}$ )
                       x( 2_${ik}$, 1_${ik}$ ) = temp*x( 2_${ik}$, 1_${ik}$ )
                       xnorm = temp*xnorm
                       scale = temp*scale
                    end if
                 end if
              else
                 ! complex 2x2 system  (w is complex)
                 ! find the largest element in c
                 ci( 1_${ik}$, 1_${ik}$ ) = -wi*d1
                 ci( 2_${ik}$, 1_${ik}$ ) = zero
                 ci( 1_${ik}$, 2_${ik}$ ) = zero
                 ci( 2_${ik}$, 2_${ik}$ ) = -wi*d2
                 cmax = zero
                 icmax = 0_${ik}$
                 do j = 1, 4
                    if( abs( crv( j ) )+abs( civ( j ) )>cmax ) then
                       cmax = abs( crv( j ) ) + abs( civ( j ) )
                       icmax = j
                    end if
                 end do
                 ! if norm(c) < smini, use smini*identity.
                 if( cmax<smini ) then
                    bnorm = max( abs( b( 1_${ik}$, 1_${ik}$ ) )+abs( b( 1_${ik}$, 2_${ik}$ ) ),abs( b( 2_${ik}$, 1_${ik}$ ) )+abs( b( 2_${ik}$, 2_${ik}$ )&
                               ) )
                    if( smini<one .and. bnorm>one ) then
                       if( bnorm>bignum*smini )scale = one / bnorm
                    end if
                    temp = scale / smini
                    x( 1_${ik}$, 1_${ik}$ ) = temp*b( 1_${ik}$, 1_${ik}$ )
                    x( 2_${ik}$, 1_${ik}$ ) = temp*b( 2_${ik}$, 1_${ik}$ )
                    x( 1_${ik}$, 2_${ik}$ ) = temp*b( 1_${ik}$, 2_${ik}$ )
                    x( 2_${ik}$, 2_${ik}$ ) = temp*b( 2_${ik}$, 2_${ik}$ )
                    xnorm = temp*bnorm
                    info = 1_${ik}$
                    return
                 end if
                 ! gaussian elimination with complete pivoting.
                 ur11 = crv( icmax )
                 ui11 = civ( icmax )
                 cr21 = crv( ipivot( 2_${ik}$, icmax ) )
                 ci21 = civ( ipivot( 2_${ik}$, icmax ) )
                 ur12 = crv( ipivot( 3_${ik}$, icmax ) )
                 ui12 = civ( ipivot( 3_${ik}$, icmax ) )
                 cr22 = crv( ipivot( 4_${ik}$, icmax ) )
                 ci22 = civ( ipivot( 4_${ik}$, icmax ) )
                 if( icmax==1_${ik}$ .or. icmax==4_${ik}$ ) then
                    ! code when off-diagonals of pivoted c are real
                    if( abs( ur11 )>abs( ui11 ) ) then
                       temp = ui11 / ur11
                       ur11r = one / ( ur11*( one+temp**2_${ik}$ ) )
                       ui11r = -temp*ur11r
                    else
                       temp = ur11 / ui11
                       ui11r = -one / ( ui11*( one+temp**2_${ik}$ ) )
                       ur11r = -temp*ui11r
                    end if
                    lr21 = cr21*ur11r
                    li21 = cr21*ui11r
                    ur12s = ur12*ur11r
                    ui12s = ur12*ui11r
                    ur22 = cr22 - ur12*lr21
                    ui22 = ci22 - ur12*li21
                 else
                    ! code when diagonals of pivoted c are real
                    ur11r = one / ur11
                    ui11r = zero
                    lr21 = cr21*ur11r
                    li21 = ci21*ur11r
                    ur12s = ur12*ur11r
                    ui12s = ui12*ur11r
                    ur22 = cr22 - ur12*lr21 + ui12*li21
                    ui22 = -ur12*li21 - ui12*lr21
                 end if
                 u22abs = abs( ur22 ) + abs( ui22 )
                 ! if smaller pivot < smini, use smini
                 if( u22abs<smini ) then
                    ur22 = smini
                    ui22 = zero
                    info = 1_${ik}$
                 end if
                 if( rswap( icmax ) ) then
                    br2 = b( 1_${ik}$, 1_${ik}$ )
                    br1 = b( 2_${ik}$, 1_${ik}$ )
                    bi2 = b( 1_${ik}$, 2_${ik}$ )
                    bi1 = b( 2_${ik}$, 2_${ik}$ )
                 else
                    br1 = b( 1_${ik}$, 1_${ik}$ )
                    br2 = b( 2_${ik}$, 1_${ik}$ )
                    bi1 = b( 1_${ik}$, 2_${ik}$ )
                    bi2 = b( 2_${ik}$, 2_${ik}$ )
                 end if
                 br2 = br2 - lr21*br1 + li21*bi1
                 bi2 = bi2 - li21*br1 - lr21*bi1
                 bbnd = max( ( abs( br1 )+abs( bi1 ) )*( u22abs*( abs( ur11r )+abs( ui11r ) ) ),&
                           abs( br2 )+abs( bi2 ) )
                 if( bbnd>one .and. u22abs<one ) then
                    if( bbnd>=bignum*u22abs ) then
                       scale = one / bbnd
                       br1 = scale*br1
                       bi1 = scale*bi1
                       br2 = scale*br2
                       bi2 = scale*bi2
                    end if
                 end if
                 call stdlib${ii}$_dladiv( br2, bi2, ur22, ui22, xr2, xi2 )
                 xr1 = ur11r*br1 - ui11r*bi1 - ur12s*xr2 + ui12s*xi2
                 xi1 = ui11r*br1 + ur11r*bi1 - ui12s*xr2 - ur12s*xi2
                 if( zswap( icmax ) ) then
                    x( 1_${ik}$, 1_${ik}$ ) = xr2
                    x( 2_${ik}$, 1_${ik}$ ) = xr1
                    x( 1_${ik}$, 2_${ik}$ ) = xi2
                    x( 2_${ik}$, 2_${ik}$ ) = xi1
                 else
                    x( 1_${ik}$, 1_${ik}$ ) = xr1
                    x( 2_${ik}$, 1_${ik}$ ) = xr2
                    x( 1_${ik}$, 2_${ik}$ ) = xi1
                    x( 2_${ik}$, 2_${ik}$ ) = xi2
                 end if
                 xnorm = max( abs( xr1 )+abs( xi1 ), abs( xr2 )+abs( xi2 ) )
                 ! further scaling if  norm(a) norm(x) > overflow
                 if( xnorm>one .and. cmax>one ) then
                    if( xnorm>bignum / cmax ) then
                       temp = cmax / bignum
                       x( 1_${ik}$, 1_${ik}$ ) = temp*x( 1_${ik}$, 1_${ik}$ )
                       x( 2_${ik}$, 1_${ik}$ ) = temp*x( 2_${ik}$, 1_${ik}$ )
                       x( 1_${ik}$, 2_${ik}$ ) = temp*x( 1_${ik}$, 2_${ik}$ )
                       x( 2_${ik}$, 2_${ik}$ ) = temp*x( 2_${ik}$, 2_${ik}$ )
                       xnorm = temp*xnorm
                       scale = temp*scale
                    end if
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_dlaln2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$laln2( ltrans, na, nw, smin, ca, a, lda, d1, d2, b,ldb, wr, wi, x, &
     !! DLALN2: solves a system of the form  (ca A - w D ) X = s B
     !! or (ca A**T - w D) X = s B   with possible scaling ("s") and
     !! perturbation of A.  (A**T means A-transpose.)
     !! A is an NA x NA real matrix, ca is a real scalar, D is an NA x NA
     !! real diagonal matrix, w is a real or complex value, and X and B are
     !! NA x 1 matrices -- real if w is real, complex if w is complex.  NA
     !! may be 1 or 2.
     !! If w is complex, X and B are represented as NA x 2 matrices,
     !! the first column of each being the real part and the second
     !! being the imaginary part.
     !! "s" is a scaling factor (<= 1), computed by DLALN2, which is
     !! so chosen that X can be computed without overflow.  X is further
     !! scaled if necessary to assure that norm(ca A - w D)*norm(X) is less
     !! than overflow.
     !! If both singular values of (ca A - w D) are less than SMIN,
     !! SMIN*identity will be used instead of (ca A - w D).  If only one
     !! singular value is less than SMIN, one element of (ca A - w D) will be
     !! perturbed enough to make the smallest singular value roughly SMIN.
     !! If both singular values are at least SMIN, (ca A - w D) will not be
     !! perturbed.  In any case, the perturbation will be at most some small
     !! multiple of max( SMIN, ulp*norm(ca A - w D) ).  The singular values
     !! are computed by infinity-norm approximations, and thus will only be
     !! correct to a factor of 2 or so.
     !! Note: all input quantities are assumed to be smaller than overflow
     !! by a reasonable factor.  (See BIGNUM.)
               ldx, scale, xnorm, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: ltrans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldb, ldx, na, nw
           real(${rk}$), intent(in) :: ca, d1, d2, smin, wi, wr
           real(${rk}$), intent(out) :: scale, xnorm
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*), b(ldb,*)
           real(${rk}$), intent(out) :: x(ldx,*)
       ! =====================================================================
           
           
           ! Local Scalars 
           integer(${ik}$) :: icmax, j
           real(${rk}$) :: bbnd, bi1, bi2, bignum, bnorm, br1, br2, ci21, ci22, cmax, cnorm, cr21, &
           cr22, csi, csr, li21, lr21, smini, smlnum, temp, u22abs, ui11, ui11r, ui12, ui12s, &
                     ui22, ur11, ur11r, ur12, ur12s, ur22, xi1, xi2, xr1, xr2
           ! Local Arrays 
           logical(lk) :: rswap(4_${ik}$), zswap(4_${ik}$)
           integer(${ik}$) :: ipivot(4_${ik}$,4_${ik}$)
           real(${rk}$) :: ci(2_${ik}$,2_${ik}$), civ(4_${ik}$), cr(2_${ik}$,2_${ik}$), crv(4_${ik}$)
           ! Intrinsic Functions 
           ! Equivalences 
           equivalence        ( ci( 1_${ik}$, 1_${ik}$ ), civ( 1_${ik}$ ) ),( cr( 1_${ik}$, 1_${ik}$ ), crv( 1_${ik}$ ) )
           ! Data Statements 
           zswap = [.false.,.false.,.true.,.true.]
           rswap = [.false.,.true.,.false.,.true.]
           ipivot = reshape([1_${ik}$,2_${ik}$,3_${ik}$,4_${ik}$,2_${ik}$,1_${ik}$,4_${ik}$,3_${ik}$,3_${ik}$,4_${ik}$,1_${ik}$,2_${ik}$,4_${ik}$,3_${ik}$,2_${ik}$,1_${ik}$],[4_${ik}$,4_${ik}$])
           ! Executable Statements 
           ! compute bignum
           smlnum = two*stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           bignum = one / smlnum
           smini = max( smin, smlnum )
           ! don't check for input errors
           info = 0_${ik}$
           ! standard initializations
           scale = one
           if( na==1_${ik}$ ) then
              ! 1 x 1  (i.e., scalar) system   c x = b
              if( nw==1_${ik}$ ) then
                 ! real 1x1 system.
                 ! c = ca a - w d
                 csr = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
                 cnorm = abs( csr )
                 ! if | c | < smini, use c = smini
                 if( cnorm<smini ) then
                    csr = smini
                    cnorm = smini
                    info = 1_${ik}$
                 end if
                 ! check scaling for  x = b / c
                 bnorm = abs( b( 1_${ik}$, 1_${ik}$ ) )
                 if( cnorm<one .and. bnorm>one ) then
                    if( bnorm>bignum*cnorm )scale = one / bnorm
                 end if
                 ! compute x
                 x( 1_${ik}$, 1_${ik}$ ) = ( b( 1_${ik}$, 1_${ik}$ )*scale ) / csr
                 xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) )
              else
                 ! complex 1x1 system (w is complex)
                 ! c = ca a - w d
                 csr = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
                 csi = -wi*d1
                 cnorm = abs( csr ) + abs( csi )
                 ! if | c | < smini, use c = smini
                 if( cnorm<smini ) then
                    csr = smini
                    csi = zero
                    cnorm = smini
                    info = 1_${ik}$
                 end if
                 ! check scaling for  x = b / c
                 bnorm = abs( b( 1_${ik}$, 1_${ik}$ ) ) + abs( b( 1_${ik}$, 2_${ik}$ ) )
                 if( cnorm<one .and. bnorm>one ) then
                    if( bnorm>bignum*cnorm )scale = one / bnorm
                 end if
                 ! compute x
                 call stdlib${ii}$_${ri}$ladiv( scale*b( 1_${ik}$, 1_${ik}$ ), scale*b( 1_${ik}$, 2_${ik}$ ), csr, csi,x( 1_${ik}$, 1_${ik}$ ), x( 1_${ik}$, &
                           2_${ik}$ ) )
                 xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) ) + abs( x( 1_${ik}$, 2_${ik}$ ) )
              end if
           else
              ! 2x2 system
              ! compute the realpart of  c = ca a - w d  (or  ca a**t - w d,KIND=${rk}$)
              cr( 1_${ik}$, 1_${ik}$ ) = ca*a( 1_${ik}$, 1_${ik}$ ) - wr*d1
              cr( 2_${ik}$, 2_${ik}$ ) = ca*a( 2_${ik}$, 2_${ik}$ ) - wr*d2
              if( ltrans ) then
                 cr( 1_${ik}$, 2_${ik}$ ) = ca*a( 2_${ik}$, 1_${ik}$ )
                 cr( 2_${ik}$, 1_${ik}$ ) = ca*a( 1_${ik}$, 2_${ik}$ )
              else
                 cr( 2_${ik}$, 1_${ik}$ ) = ca*a( 2_${ik}$, 1_${ik}$ )
                 cr( 1_${ik}$, 2_${ik}$ ) = ca*a( 1_${ik}$, 2_${ik}$ )
              end if
              if( nw==1_${ik}$ ) then
                 ! real2x2 system  (w is real,KIND=${rk}$)
                 ! find the largest element in c
                 cmax = zero
                 icmax = 0_${ik}$
                 do j = 1, 4
                    if( abs( crv( j ) )>cmax ) then
                       cmax = abs( crv( j ) )
                       icmax = j
                    end if
                 end do
                 ! if norm(c) < smini, use smini*identity.
                 if( cmax<smini ) then
                    bnorm = max( abs( b( 1_${ik}$, 1_${ik}$ ) ), abs( b( 2_${ik}$, 1_${ik}$ ) ) )
                    if( smini<one .and. bnorm>one ) then
                       if( bnorm>bignum*smini )scale = one / bnorm
                    end if
                    temp = scale / smini
                    x( 1_${ik}$, 1_${ik}$ ) = temp*b( 1_${ik}$, 1_${ik}$ )
                    x( 2_${ik}$, 1_${ik}$ ) = temp*b( 2_${ik}$, 1_${ik}$ )
                    xnorm = temp*bnorm
                    info = 1_${ik}$
                    return
                 end if
                 ! gaussian elimination with complete pivoting.
                 ur11 = crv( icmax )
                 cr21 = crv( ipivot( 2_${ik}$, icmax ) )
                 ur12 = crv( ipivot( 3_${ik}$, icmax ) )
                 cr22 = crv( ipivot( 4_${ik}$, icmax ) )
                 ur11r = one / ur11
                 lr21 = ur11r*cr21
                 ur22 = cr22 - ur12*lr21
                 ! if smaller pivot < smini, use smini
                 if( abs( ur22 )<smini ) then
                    ur22 = smini
                    info = 1_${ik}$
                 end if
                 if( rswap( icmax ) ) then
                    br1 = b( 2_${ik}$, 1_${ik}$ )
                    br2 = b( 1_${ik}$, 1_${ik}$ )
                 else
                    br1 = b( 1_${ik}$, 1_${ik}$ )
                    br2 = b( 2_${ik}$, 1_${ik}$ )
                 end if
                 br2 = br2 - lr21*br1
                 bbnd = max( abs( br1*( ur22*ur11r ) ), abs( br2 ) )
                 if( bbnd>one .and. abs( ur22 )<one ) then
                    if( bbnd>=bignum*abs( ur22 ) )scale = one / bbnd
                 end if
                 xr2 = ( br2*scale ) / ur22
                 xr1 = ( scale*br1 )*ur11r - xr2*( ur11r*ur12 )
                 if( zswap( icmax ) ) then
                    x( 1_${ik}$, 1_${ik}$ ) = xr2
                    x( 2_${ik}$, 1_${ik}$ ) = xr1
                 else
                    x( 1_${ik}$, 1_${ik}$ ) = xr1
                    x( 2_${ik}$, 1_${ik}$ ) = xr2
                 end if
                 xnorm = max( abs( xr1 ), abs( xr2 ) )
                 ! further scaling if  norm(a) norm(x) > overflow
                 if( xnorm>one .and. cmax>one ) then
                    if( xnorm>bignum / cmax ) then
                       temp = cmax / bignum
                       x( 1_${ik}$, 1_${ik}$ ) = temp*x( 1_${ik}$, 1_${ik}$ )
                       x( 2_${ik}$, 1_${ik}$ ) = temp*x( 2_${ik}$, 1_${ik}$ )
                       xnorm = temp*xnorm
                       scale = temp*scale
                    end if
                 end if
              else
                 ! complex 2x2 system  (w is complex)
                 ! find the largest element in c
                 ci( 1_${ik}$, 1_${ik}$ ) = -wi*d1
                 ci( 2_${ik}$, 1_${ik}$ ) = zero
                 ci( 1_${ik}$, 2_${ik}$ ) = zero
                 ci( 2_${ik}$, 2_${ik}$ ) = -wi*d2
                 cmax = zero
                 icmax = 0_${ik}$
                 do j = 1, 4
                    if( abs( crv( j ) )+abs( civ( j ) )>cmax ) then
                       cmax = abs( crv( j ) ) + abs( civ( j ) )
                       icmax = j
                    end if
                 end do
                 ! if norm(c) < smini, use smini*identity.
                 if( cmax<smini ) then
                    bnorm = max( abs( b( 1_${ik}$, 1_${ik}$ ) )+abs( b( 1_${ik}$, 2_${ik}$ ) ),abs( b( 2_${ik}$, 1_${ik}$ ) )+abs( b( 2_${ik}$, 2_${ik}$ )&
                               ) )
                    if( smini<one .and. bnorm>one ) then
                       if( bnorm>bignum*smini )scale = one / bnorm
                    end if
                    temp = scale / smini
                    x( 1_${ik}$, 1_${ik}$ ) = temp*b( 1_${ik}$, 1_${ik}$ )
                    x( 2_${ik}$, 1_${ik}$ ) = temp*b( 2_${ik}$, 1_${ik}$ )
                    x( 1_${ik}$, 2_${ik}$ ) = temp*b( 1_${ik}$, 2_${ik}$ )
                    x( 2_${ik}$, 2_${ik}$ ) = temp*b( 2_${ik}$, 2_${ik}$ )
                    xnorm = temp*bnorm
                    info = 1_${ik}$
                    return
                 end if
                 ! gaussian elimination with complete pivoting.
                 ur11 = crv( icmax )
                 ui11 = civ( icmax )
                 cr21 = crv( ipivot( 2_${ik}$, icmax ) )
                 ci21 = civ( ipivot( 2_${ik}$, icmax ) )
                 ur12 = crv( ipivot( 3_${ik}$, icmax ) )
                 ui12 = civ( ipivot( 3_${ik}$, icmax ) )
                 cr22 = crv( ipivot( 4_${ik}$, icmax ) )
                 ci22 = civ( ipivot( 4_${ik}$, icmax ) )
                 if( icmax==1_${ik}$ .or. icmax==4_${ik}$ ) then
                    ! code when off-diagonals of pivoted c are real
                    if( abs( ur11 )>abs( ui11 ) ) then
                       temp = ui11 / ur11
                       ur11r = one / ( ur11*( one+temp**2_${ik}$ ) )
                       ui11r = -temp*ur11r
                    else
                       temp = ur11 / ui11
                       ui11r = -one / ( ui11*( one+temp**2_${ik}$ ) )
                       ur11r = -temp*ui11r
                    end if
                    lr21 = cr21*ur11r
                    li21 = cr21*ui11r
                    ur12s = ur12*ur11r
                    ui12s = ur12*ui11r
                    ur22 = cr22 - ur12*lr21
                    ui22 = ci22 - ur12*li21
                 else
                    ! code when diagonals of pivoted c are real
                    ur11r = one / ur11
                    ui11r = zero
                    lr21 = cr21*ur11r
                    li21 = ci21*ur11r
                    ur12s = ur12*ur11r
                    ui12s = ui12*ur11r
                    ur22 = cr22 - ur12*lr21 + ui12*li21
                    ui22 = -ur12*li21 - ui12*lr21
                 end if
                 u22abs = abs( ur22 ) + abs( ui22 )
                 ! if smaller pivot < smini, use smini
                 if( u22abs<smini ) then
                    ur22 = smini
                    ui22 = zero
                    info = 1_${ik}$
                 end if
                 if( rswap( icmax ) ) then
                    br2 = b( 1_${ik}$, 1_${ik}$ )
                    br1 = b( 2_${ik}$, 1_${ik}$ )
                    bi2 = b( 1_${ik}$, 2_${ik}$ )
                    bi1 = b( 2_${ik}$, 2_${ik}$ )
                 else
                    br1 = b( 1_${ik}$, 1_${ik}$ )
                    br2 = b( 2_${ik}$, 1_${ik}$ )
                    bi1 = b( 1_${ik}$, 2_${ik}$ )
                    bi2 = b( 2_${ik}$, 2_${ik}$ )
                 end if
                 br2 = br2 - lr21*br1 + li21*bi1
                 bi2 = bi2 - li21*br1 - lr21*bi1
                 bbnd = max( ( abs( br1 )+abs( bi1 ) )*( u22abs*( abs( ur11r )+abs( ui11r ) ) ),&
                           abs( br2 )+abs( bi2 ) )
                 if( bbnd>one .and. u22abs<one ) then
                    if( bbnd>=bignum*u22abs ) then
                       scale = one / bbnd
                       br1 = scale*br1
                       bi1 = scale*bi1
                       br2 = scale*br2
                       bi2 = scale*bi2
                    end if
                 end if
                 call stdlib${ii}$_${ri}$ladiv( br2, bi2, ur22, ui22, xr2, xi2 )
                 xr1 = ur11r*br1 - ui11r*bi1 - ur12s*xr2 + ui12s*xi2
                 xi1 = ui11r*br1 + ur11r*bi1 - ui12s*xr2 - ur12s*xi2
                 if( zswap( icmax ) ) then
                    x( 1_${ik}$, 1_${ik}$ ) = xr2
                    x( 2_${ik}$, 1_${ik}$ ) = xr1
                    x( 1_${ik}$, 2_${ik}$ ) = xi2
                    x( 2_${ik}$, 2_${ik}$ ) = xi1
                 else
                    x( 1_${ik}$, 1_${ik}$ ) = xr1
                    x( 2_${ik}$, 1_${ik}$ ) = xr2
                    x( 1_${ik}$, 2_${ik}$ ) = xi1
                    x( 2_${ik}$, 2_${ik}$ ) = xi2
                 end if
                 xnorm = max( abs( xr1 )+abs( xi1 ), abs( xr2 )+abs( xi2 ) )
                 ! further scaling if  norm(a) norm(x) > overflow
                 if( xnorm>one .and. cmax>one ) then
                    if( xnorm>bignum / cmax ) then
                       temp = cmax / bignum
                       x( 1_${ik}$, 1_${ik}$ ) = temp*x( 1_${ik}$, 1_${ik}$ )
                       x( 2_${ik}$, 1_${ik}$ ) = temp*x( 2_${ik}$, 1_${ik}$ )
                       x( 1_${ik}$, 2_${ik}$ ) = temp*x( 1_${ik}$, 2_${ik}$ )
                       x( 2_${ik}$, 2_${ik}$ ) = temp*x( 2_${ik}$, 2_${ik}$ )
                       xnorm = temp*xnorm
                       scale = temp*scale
                    end if
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ri}$laln2

#:endif
#:endfor



     module subroutine stdlib${ii}$_strsyl( trana, tranb, isgn, m, n, a, lda, b, ldb, c,ldc, scale, info )
     !! STRSYL solves the real Sylvester matrix equation:
     !! op(A)*X + X*op(B) = scale*C or
     !! op(A)*X - X*op(B) = scale*C,
     !! where op(A) = A or A**T, and  A and B are both upper quasi-
     !! triangular. A is M-by-M and B is N-by-N; the right hand side C and
     !! the solution X are M-by-N; and scale is an output scale factor, set
     !! <= 1 to avoid overflow in X.
     !! A and B must be in Schur canonical form (as returned by SHSEQR), that
     !! is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
     !! each 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: trana, tranb
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, lda, ldb, ldc, m, n
           real(sp), intent(out) :: scale
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*), b(ldb,*)
           real(sp), intent(inout) :: c(ldc,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: notrna, notrnb
           integer(${ik}$) :: ierr, j, k, k1, k2, knext, l, l1, l2, lnext
           real(sp) :: a11, bignum, da11, db, eps, scaloc, sgn, smin, smlnum, suml, sumr, &
                     xnorm
           ! Local Arrays 
           real(sp) :: dum(1_${ik}$), vec(2_${ik}$,2_${ik}$), x(2_${ik}$,2_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test input parameters
           notrna = stdlib_lsame( trana, 'N' )
           notrnb = stdlib_lsame( tranb, 'N' )
           info = 0_${ik}$
           if( .not.notrna .and. .not.stdlib_lsame( trana, 'T' ) .and. .not.stdlib_lsame( trana, &
                     'C' ) ) then
              info = -1_${ik}$
           else if( .not.notrnb .and. .not.stdlib_lsame( tranb, 'T' ) .and. .not.stdlib_lsame( &
                     tranb, 'C' ) ) then
              info = -2_${ik}$
           else if( isgn/=1_${ik}$ .and. isgn/=-1_${ik}$ ) then
              info = -3_${ik}$
           else if( m<0_${ik}$ ) then
              info = -4_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'STRSYL', -info )
              return
           end if
           ! quick return if possible
           scale = one
           if( m==0 .or. n==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_slamch( 'P' )
           smlnum = stdlib${ii}$_slamch( 'S' )
           bignum = one / smlnum
           call stdlib${ii}$_slabad( smlnum, bignum )
           smlnum = smlnum*real( m*n,KIND=sp) / eps
           bignum = one / smlnum
           smin = max( smlnum, eps*stdlib${ii}$_slange( 'M', m, m, a, lda, dum ),eps*stdlib${ii}$_slange( 'M',&
                      n, n, b, ldb, dum ) )
           sgn = isgn
           if( notrna .and. notrnb ) then
              ! solve    a*x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
               ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                        ! m                         l-1
              ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b(j,l)].
                      ! i=k+1                       j=1
              ! start column loop (index = l)
              ! l1 (l2) : column index of the first (first) row of x(k,l).
              lnext = 1_${ik}$
              loop_70: do l = 1, n
                 if( l<lnext )cycle loop_70
                 if( l==n ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l+1, l )/=zero ) then
                       l1 = l
                       l2 = l + 1_${ik}$
                       lnext = l + 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l + 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l).
                 knext = m
                 loop_60: do k = m, 1, -1
                    if( k>knext )cycle loop_60
                    if( k==1_${ik}$ ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k, k-1 )/=zero ) then
                          k1 = k - 1_${ik}$
                          k2 = k
                          knext = k - 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k - 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_sdot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_slaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slasy2( .false., .false., isgn, 2_${ik}$, 2_${ik}$,a( k1, k1 ), lda, b( l1, &
                                 l1 ), ldb, vec,2_${ik}$, scaloc, x, 2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_60
              end do loop_70
           else if( .not.notrna .and. notrnb ) then
              ! solve    a**t *x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! upper-left corner column by column by
                ! a(k,k)**t*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                         ! k-1                          l-1
                ! r(k,l) = sum [a(i,k)**t*x(i,l)] +isgn*sum [x(k,j)*b(j,l)]
                         ! i=1                          j=1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = 1_${ik}$
              loop_130: do l = 1, n
                 if( l<lnext )cycle loop_130
                 if( l==n ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l+1, l )/=zero ) then
                       l1 = l
                       l2 = l + 1_${ik}$
                       lnext = l + 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l + 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = 1_${ik}$
                 loop_120: do k = 1, m
                    if( k<knext )cycle loop_120
                    if( k==m ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k+1, k )/=zero ) then
                          k1 = k
                          k2 = k + 1_${ik}$
                          knext = k + 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k + 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_slaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slasy2( .true., .false., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, &
                                 l1 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_120
              end do loop_130
           else if( .not.notrna .and. .not.notrnb ) then
              ! solve    a**t*x + isgn*x*b**t = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! top-right corner column by column by
                 ! a(k,k)**t*x(k,l) + isgn*x(k,l)*b(l,l)**t = c(k,l) - r(k,l)
              ! where
                           ! k-1                            n
                  ! r(k,l) = sum [a(i,k)**t*x(i,l)] + isgn*sum [x(k,j)*b(l,j)**t].
                           ! i=1                          j=l+1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = n
              loop_190: do l = n, 1, -1
                 if( l>lnext )cycle loop_190
                 if( l==1_${ik}$ ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l, l-1 )/=zero ) then
                       l1 = l - 1_${ik}$
                       l2 = l
                       lnext = l - 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l - 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = 1_${ik}$
                 loop_180: do k = 1, m
                    if( k<knext )cycle loop_180
                    if( k==m ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k+1, k )/=zero ) then
                          k1 = k
                          k2 = k + 1_${ik}$
                          knext = k + 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k + 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l1, c( k1, min( l1+1, n ) ), ldc,b( l1, min( l1+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_slaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l2, min(l2+1, n )&
                                  ), ldb )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slasy2( .true., .true., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, l1 &
                                 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_180
              end do loop_190
           else if( notrna .and. .not.notrnb ) then
              ! solve    a*x + isgn*x*b**t = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-right corner column by column by
                  ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l)**t = c(k,l) - r(k,l)
              ! where
                            ! m                          n
                  ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b(l,j)**t].
                          ! i=k+1                      j=l+1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = n
              loop_250: do l = n, 1, -1
                 if( l>lnext )cycle loop_250
                 if( l==1_${ik}$ ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l, l-1 )/=zero ) then
                       l1 = l - 1_${ik}$
                       l2 = l
                       lnext = l - 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l - 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = m
                 loop_240: do k = m, 1, -1
                    if( k>knext )cycle loop_240
                    if( k==1_${ik}$ ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k, k-1 )/=zero ) then
                          k1 = k - 1_${ik}$
                          k2 = k
                          knext = k - 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k - 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( m-k1, a( k1, min(k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l1, c( k1, min( l1+1, n ) ), ldc,b( l1, min( l1+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_sdot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_sdot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_slaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_sdot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_sdot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_sdot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_slasy2( .false., .true., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, &
                                 l1 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_sscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_240
              end do loop_250
           end if
           return
     end subroutine stdlib${ii}$_strsyl

     module subroutine stdlib${ii}$_dtrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb, c,ldc, scale, info )
     !! DTRSYL solves the real Sylvester matrix equation:
     !! op(A)*X + X*op(B) = scale*C or
     !! op(A)*X - X*op(B) = scale*C,
     !! where op(A) = A or A**T, and  A and B are both upper quasi-
     !! triangular. A is M-by-M and B is N-by-N; the right hand side C and
     !! the solution X are M-by-N; and scale is an output scale factor, set
     !! <= 1 to avoid overflow in X.
     !! A and B must be in Schur canonical form (as returned by DHSEQR), that
     !! is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
     !! each 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: trana, tranb
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, lda, ldb, ldc, m, n
           real(dp), intent(out) :: scale
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*), b(ldb,*)
           real(dp), intent(inout) :: c(ldc,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: notrna, notrnb
           integer(${ik}$) :: ierr, j, k, k1, k2, knext, l, l1, l2, lnext
           real(dp) :: a11, bignum, da11, db, eps, scaloc, sgn, smin, smlnum, suml, sumr, &
                     xnorm
           ! Local Arrays 
           real(dp) :: dum(1_${ik}$), vec(2_${ik}$,2_${ik}$), x(2_${ik}$,2_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test input parameters
           notrna = stdlib_lsame( trana, 'N' )
           notrnb = stdlib_lsame( tranb, 'N' )
           info = 0_${ik}$
           if( .not.notrna .and. .not.stdlib_lsame( trana, 'T' ) .and. .not.stdlib_lsame( trana, &
                     'C' ) ) then
              info = -1_${ik}$
           else if( .not.notrnb .and. .not.stdlib_lsame( tranb, 'T' ) .and. .not.stdlib_lsame( &
                     tranb, 'C' ) ) then
              info = -2_${ik}$
           else if( isgn/=1_${ik}$ .and. isgn/=-1_${ik}$ ) then
              info = -3_${ik}$
           else if( m<0_${ik}$ ) then
              info = -4_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTRSYL', -info )
              return
           end if
           ! quick return if possible
           scale = one
           if( m==0 .or. n==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_dlamch( 'P' )
           smlnum = stdlib${ii}$_dlamch( 'S' )
           bignum = one / smlnum
           call stdlib${ii}$_dlabad( smlnum, bignum )
           smlnum = smlnum*real( m*n,KIND=dp) / eps
           bignum = one / smlnum
           smin = max( smlnum, eps*stdlib${ii}$_dlange( 'M', m, m, a, lda, dum ),eps*stdlib${ii}$_dlange( 'M',&
                      n, n, b, ldb, dum ) )
           sgn = isgn
           if( notrna .and. notrnb ) then
              ! solve    a*x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
               ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                        ! m                         l-1
              ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b(j,l)].
                      ! i=k+1                       j=1
              ! start column loop (index = l)
              ! l1 (l2) : column index of the first (first) row of x(k,l).
              lnext = 1_${ik}$
              loop_60: do l = 1, n
                 if( l<lnext )cycle loop_60
                 if( l==n ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l+1, l )/=zero ) then
                       l1 = l
                       l2 = l + 1_${ik}$
                       lnext = l + 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l + 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l).
                 knext = m
                 loop_50: do k = m, 1, -1
                    if( k>knext )cycle loop_50
                    if( k==1_${ik}$ ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k, k-1 )/=zero ) then
                          k1 = k - 1_${ik}$
                          k2 = k
                          knext = k - 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k - 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_ddot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlasy2( .false., .false., isgn, 2_${ik}$, 2_${ik}$,a( k1, k1 ), lda, b( l1, &
                                 l1 ), ldb, vec,2_${ik}$, scaloc, x, 2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_50
              end do loop_60
           else if( .not.notrna .and. notrnb ) then
              ! solve    a**t *x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! upper-left corner column by column by
                ! a(k,k)**t*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                         ! k-1        t                    l-1
                ! r(k,l) = sum [a(i,k)**t*x(i,l)] +isgn*sum [x(k,j)*b(j,l)]
                         ! i=1                          j=1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = 1_${ik}$
              loop_120: do l = 1, n
                 if( l<lnext )cycle loop_120
                 if( l==n ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l+1, l )/=zero ) then
                       l1 = l
                       l2 = l + 1_${ik}$
                       lnext = l + 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l + 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = 1_${ik}$
                 loop_110: do k = 1, m
                    if( k<knext )cycle loop_110
                    if( k==m ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k+1, k )/=zero ) then
                          k1 = k
                          k2 = k + 1_${ik}$
                          knext = k + 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k + 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlasy2( .true., .false., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, &
                                 l1 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_110
              end do loop_120
           else if( .not.notrna .and. .not.notrnb ) then
              ! solve    a**t*x + isgn*x*b**t = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! top-right corner column by column by
                 ! a(k,k)**t*x(k,l) + isgn*x(k,l)*b(l,l)**t = c(k,l) - r(k,l)
              ! where
                           ! k-1                            n
                  ! r(k,l) = sum [a(i,k)**t*x(i,l)] + isgn*sum [x(k,j)*b(l,j)**t].
                           ! i=1                          j=l+1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = n
              loop_180: do l = n, 1, -1
                 if( l>lnext )cycle loop_180
                 if( l==1_${ik}$ ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l, l-1 )/=zero ) then
                       l1 = l - 1_${ik}$
                       l2 = l
                       lnext = l - 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l - 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = 1_${ik}$
                 loop_170: do k = 1, m
                    if( k<knext )cycle loop_170
                    if( k==m ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k+1, k )/=zero ) then
                          k1 = k
                          k2 = k + 1_${ik}$
                          knext = k + 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k + 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l1, c( k1, min( l1+1, n ) ), ldc,b( l1, min( l1+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlaln2( .true., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlasy2( .true., .true., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, l1 &
                                 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_170
              end do loop_180
           else if( notrna .and. .not.notrnb ) then
              ! solve    a*x + isgn*x*b**t = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-right corner column by column by
                  ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l)**t = c(k,l) - r(k,l)
              ! where
                            ! m                          n
                  ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b(l,j)**t].
                          ! i=k+1                      j=l+1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = n
              loop_240: do l = n, 1, -1
                 if( l>lnext )cycle loop_240
                 if( l==1_${ik}$ ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l, l-1 )/=zero ) then
                       l1 = l - 1_${ik}$
                       l2 = l
                       lnext = l - 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l - 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = m
                 loop_230: do k = m, 1, -1
                    if( k>knext )cycle loop_230
                    if( k==1_${ik}$ ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k, k-1 )/=zero ) then
                          k1 = k - 1_${ik}$
                          k2 = k
                          knext = k - 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k - 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l1, c( k1, min( l1+1, n ) ), ldc,b( l1, min( l1+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_ddot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_ddot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_dlaln2( .false., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_ddot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_ddot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_ddot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_dlasy2( .false., .true., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, &
                                 l1 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_230
              end do loop_240
           end if
           return
     end subroutine stdlib${ii}$_dtrsyl

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$trsyl( trana, tranb, isgn, m, n, a, lda, b, ldb, c,ldc, scale, info )
     !! DTRSYL: solves the real Sylvester matrix equation:
     !! op(A)*X + X*op(B) = scale*C or
     !! op(A)*X - X*op(B) = scale*C,
     !! where op(A) = A or A**T, and  A and B are both upper quasi-
     !! triangular. A is M-by-M and B is N-by-N; the right hand side C and
     !! the solution X are M-by-N; and scale is an output scale factor, set
     !! <= 1 to avoid overflow in X.
     !! A and B must be in Schur canonical form (as returned by DHSEQR), that
     !! is, block upper triangular with 1-by-1 and 2-by-2 diagonal blocks;
     !! each 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: trana, tranb
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, lda, ldb, ldc, m, n
           real(${rk}$), intent(out) :: scale
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*), b(ldb,*)
           real(${rk}$), intent(inout) :: c(ldc,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: notrna, notrnb
           integer(${ik}$) :: ierr, j, k, k1, k2, knext, l, l1, l2, lnext
           real(${rk}$) :: a11, bignum, da11, db, eps, scaloc, sgn, smin, smlnum, suml, sumr, &
                     xnorm
           ! Local Arrays 
           real(${rk}$) :: dum(1_${ik}$), vec(2_${ik}$,2_${ik}$), x(2_${ik}$,2_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test input parameters
           notrna = stdlib_lsame( trana, 'N' )
           notrnb = stdlib_lsame( tranb, 'N' )
           info = 0_${ik}$
           if( .not.notrna .and. .not.stdlib_lsame( trana, 'T' ) .and. .not.stdlib_lsame( trana, &
                     'C' ) ) then
              info = -1_${ik}$
           else if( .not.notrnb .and. .not.stdlib_lsame( tranb, 'T' ) .and. .not.stdlib_lsame( &
                     tranb, 'C' ) ) then
              info = -2_${ik}$
           else if( isgn/=1_${ik}$ .and. isgn/=-1_${ik}$ ) then
              info = -3_${ik}$
           else if( m<0_${ik}$ ) then
              info = -4_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTRSYL', -info )
              return
           end if
           ! quick return if possible
           scale = one
           if( m==0 .or. n==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_${ri}$lamch( 'P' )
           smlnum = stdlib${ii}$_${ri}$lamch( 'S' )
           bignum = one / smlnum
           call stdlib${ii}$_${ri}$labad( smlnum, bignum )
           smlnum = smlnum*real( m*n,KIND=${rk}$) / eps
           bignum = one / smlnum
           smin = max( smlnum, eps*stdlib${ii}$_${ri}$lange( 'M', m, m, a, lda, dum ),eps*stdlib${ii}$_${ri}$lange( 'M',&
                      n, n, b, ldb, dum ) )
           sgn = isgn
           if( notrna .and. notrnb ) then
              ! solve    a*x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
               ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                        ! m                         l-1
              ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b(j,l)].
                      ! i=k+1                       j=1
              ! start column loop (index = l)
              ! l1 (l2) : column index of the first (first) row of x(k,l).
              lnext = 1_${ik}$
              loop_60: do l = 1, n
                 if( l<lnext )cycle loop_60
                 if( l==n ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l+1, l )/=zero ) then
                       l1 = l
                       l2 = l + 1_${ik}$
                       lnext = l + 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l + 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l).
                 knext = m
                 loop_50: do k = m, 1, -1
                    if( k>knext )cycle loop_50
                    if( k==1_${ik}$ ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k, k-1 )/=zero ) then
                          k1 = k - 1_${ik}$
                          k2 = k
                          knext = k - 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k - 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_${ri}$dot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$lasy2( .false., .false., isgn, 2_${ik}$, 2_${ik}$,a( k1, k1 ), lda, b( l1, &
                                 l1 ), ldb, vec,2_${ik}$, scaloc, x, 2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_50
              end do loop_60
           else if( .not.notrna .and. notrnb ) then
              ! solve    a**t *x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! upper-left corner column by column by
                ! a(k,k)**t*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                         ! k-1        t                    l-1
                ! r(k,l) = sum [a(i,k)**t*x(i,l)] +isgn*sum [x(k,j)*b(j,l)]
                         ! i=1                          j=1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = 1_${ik}$
              loop_120: do l = 1, n
                 if( l<lnext )cycle loop_120
                 if( l==n ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l+1, l )/=zero ) then
                       l1 = l
                       l2 = l + 1_${ik}$
                       lnext = l + 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l + 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = 1_${ik}$
                 loop_110: do k = 1, m
                    if( k<knext )cycle loop_110
                    if( k==m ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k+1, k )/=zero ) then
                          k1 = k
                          k2 = k + 1_${ik}$
                          knext = k + 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k + 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k1, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l1 ), 1_${ik}$ )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( l1-1, c( k2, 1_${ik}$ ), ldc, b( 1_${ik}$, l2 ), 1_${ik}$ )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$lasy2( .true., .false., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, &
                                 l1 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_110
              end do loop_120
           else if( .not.notrna .and. .not.notrnb ) then
              ! solve    a**t*x + isgn*x*b**t = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! top-right corner column by column by
                 ! a(k,k)**t*x(k,l) + isgn*x(k,l)*b(l,l)**t = c(k,l) - r(k,l)
              ! where
                           ! k-1                            n
                  ! r(k,l) = sum [a(i,k)**t*x(i,l)] + isgn*sum [x(k,j)*b(l,j)**t].
                           ! i=1                          j=l+1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = n
              loop_180: do l = n, 1, -1
                 if( l>lnext )cycle loop_180
                 if( l==1_${ik}$ ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l, l-1 )/=zero ) then
                       l1 = l - 1_${ik}$
                       l2 = l
                       lnext = l - 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l - 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = 1_${ik}$
                 loop_170: do k = 1, m
                    if( k<knext )cycle loop_170
                    if( k==m ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k+1, k )/=zero ) then
                          k1 = k
                          k2 = k + 1_${ik}$
                          knext = k + 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k + 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l1, c( k1, min( l1+1, n ) ), ldc,b( l1, min( l1+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$laln2( .true., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k1 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( k1-1, a( 1_${ik}$, k2 ), 1_${ik}$, c( 1_${ik}$, l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$lasy2( .true., .true., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, l1 &
                                 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_170
              end do loop_180
           else if( notrna .and. .not.notrnb ) then
              ! solve    a*x + isgn*x*b**t = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-right corner column by column by
                  ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l)**t = c(k,l) - r(k,l)
              ! where
                            ! m                          n
                  ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b(l,j)**t].
                          ! i=k+1                      j=l+1
              ! start column loop (index = l)
              ! l1 (l2): column index of the first (last) row of x(k,l)
              lnext = n
              loop_240: do l = n, 1, -1
                 if( l>lnext )cycle loop_240
                 if( l==1_${ik}$ ) then
                    l1 = l
                    l2 = l
                 else
                    if( b( l, l-1 )/=zero ) then
                       l1 = l - 1_${ik}$
                       l2 = l
                       lnext = l - 2_${ik}$
                    else
                       l1 = l
                       l2 = l
                       lnext = l - 1_${ik}$
                    end if
                 end if
                 ! start row loop (index = k)
                 ! k1 (k2): row index of the first (last) row of x(k,l)
                 knext = m
                 loop_230: do k = m, 1, -1
                    if( k>knext )cycle loop_230
                    if( k==1_${ik}$ ) then
                       k1 = k
                       k2 = k
                    else
                       if( a( k, k-1 )/=zero ) then
                          k1 = k - 1_${ik}$
                          k2 = k
                          knext = k - 2_${ik}$
                       else
                          k1 = k
                          k2 = k
                          knext = k - 1_${ik}$
                       end if
                    end if
                    if( l1==l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l1, c( k1, min( l1+1, n ) ), ldc,b( l1, min( l1+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       scaloc = one
                       a11 = a( k1, k1 ) + sgn*b( l1, l1 )
                       da11 = abs( a11 )
                       if( da11<=smin ) then
                          a11 = smin
                          da11 = smin
                          info = 1_${ik}$
                       end if
                       db = abs( vec( 1_${ik}$, 1_${ik}$ ) )
                       if( da11<one .and. db>one ) then
                          if( db>bignum*da11 )scaloc = one / db
                       end if
                       x( 1_${ik}$, 1_${ik}$ ) = ( vec( 1_${ik}$, 1_${ik}$ )*scaloc ) / a11
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                    else if( l1==l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 1_${ik}$, smin, one, a( k1, k1 ),lda, one, one, &
                                 vec, 2_${ik}$, -sgn*b( l1, l1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1==k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l1 )-( suml+sgn*sumr ) )
                       suml = stdlib${ii}$_${ri}$dot( m-k1, a( k1, min( k1+1, m ) ), lda,c( min( k1+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = sgn*( c( k1, l2 )-( suml+sgn*sumr ) )
                       call stdlib${ii}$_${ri}$laln2( .false., 2_${ik}$, 1_${ik}$, smin, one, b( l1, l1 ),ldb, one, one, &
                                 vec, 2_${ik}$, -sgn*a( k1, k1 ),zero, x, 2_${ik}$, scaloc, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 2_${ik}$, 1_${ik}$ )
                    else if( l1/=l2 .and. k1/=k2 ) then
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 1_${ik}$ ) = c( k1, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k1, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k1, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 1_${ik}$, 2_${ik}$ ) = c( k1, l2 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l1 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l1, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 1_${ik}$ ) = c( k2, l1 ) - ( suml+sgn*sumr )
                       suml = stdlib${ii}$_${ri}$dot( m-k2, a( k2, min( k2+1, m ) ), lda,c( min( k2+1, m ), &
                                 l2 ), 1_${ik}$ )
                       sumr = stdlib${ii}$_${ri}$dot( n-l2, c( k2, min( l2+1, n ) ), ldc,b( l2, min( l2+1, n &
                                 ) ), ldb )
                       vec( 2_${ik}$, 2_${ik}$ ) = c( k2, l2 ) - ( suml+sgn*sumr )
                       call stdlib${ii}$_${ri}$lasy2( .false., .true., isgn, 2_${ik}$, 2_${ik}$, a( k1, k1 ),lda, b( l1, &
                                 l1 ), ldb, vec, 2_${ik}$, scaloc, x,2_${ik}$, xnorm, ierr )
                       if( ierr/=0_${ik}$ )info = 1_${ik}$
                       if( scaloc/=one ) then
                          do j = 1, n
                             call stdlib${ii}$_${ri}$scal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                          end do
                          scale = scale*scaloc
                       end if
                       c( k1, l1 ) = x( 1_${ik}$, 1_${ik}$ )
                       c( k1, l2 ) = x( 1_${ik}$, 2_${ik}$ )
                       c( k2, l1 ) = x( 2_${ik}$, 1_${ik}$ )
                       c( k2, l2 ) = x( 2_${ik}$, 2_${ik}$ )
                    end if
                 end do loop_230
              end do loop_240
           end if
           return
     end subroutine stdlib${ii}$_${ri}$trsyl

#:endif
#:endfor

     module subroutine stdlib${ii}$_ctrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb, c,ldc, scale, info )
     !! CTRSYL solves the complex Sylvester matrix equation:
     !! op(A)*X + X*op(B) = scale*C or
     !! op(A)*X - X*op(B) = scale*C,
     !! where op(A) = A or A**H, and A and B are both upper triangular. A is
     !! M-by-M and B is N-by-N; the right hand side C and the solution X are
     !! M-by-N; and scale is an output scale factor, set <= 1 to avoid
     !! overflow in X.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: trana, tranb
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, lda, ldb, ldc, m, n
           real(sp), intent(out) :: scale
           ! Array Arguments 
           complex(sp), intent(in) :: a(lda,*), b(ldb,*)
           complex(sp), intent(inout) :: c(ldc,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: notrna, notrnb
           integer(${ik}$) :: j, k, l
           real(sp) :: bignum, da11, db, eps, scaloc, sgn, smin, smlnum
           complex(sp) :: a11, suml, sumr, vec, x11
           ! Local Arrays 
           real(sp) :: dum(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test input parameters
           notrna = stdlib_lsame( trana, 'N' )
           notrnb = stdlib_lsame( tranb, 'N' )
           info = 0_${ik}$
           if( .not.notrna .and. .not.stdlib_lsame( trana, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.notrnb .and. .not.stdlib_lsame( tranb, 'C' ) ) then
              info = -2_${ik}$
           else if( isgn/=1_${ik}$ .and. isgn/=-1_${ik}$ ) then
              info = -3_${ik}$
           else if( m<0_${ik}$ ) then
              info = -4_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CTRSYL', -info )
              return
           end if
           ! quick return if possible
           scale = one
           if( m==0 .or. n==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_slamch( 'P' )
           smlnum = stdlib${ii}$_slamch( 'S' )
           bignum = one / smlnum
           call stdlib${ii}$_slabad( smlnum, bignum )
           smlnum = smlnum*real( m*n,KIND=sp) / eps
           bignum = one / smlnum
           smin = max( smlnum, eps*stdlib${ii}$_clange( 'M', m, m, a, lda, dum ),eps*stdlib${ii}$_clange( 'M',&
                      n, n, b, ldb, dum ) )
           sgn = isgn
           if( notrna .and. notrnb ) then
              ! solve    a*x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
                  ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                          ! m                        l-1
                ! r(k,l) = sum [a(k,i)*x(i,l)] +isgn*sum [x(k,j)*b(j,l)].
                        ! i=k+1                      j=1
              loop_30: do l = 1, n
                 do k = m, 1, -1
                    suml = stdlib${ii}$_cdotu( m-k, a( k, min( k+1, m ) ), lda,c( min( k+1, m ), l ), 1_${ik}$ &
                              )
                    sumr = stdlib${ii}$_cdotu( l-1, c( k, 1_${ik}$ ), ldc, b( 1_${ik}$, l ), 1_${ik}$ )
                    vec = c( k, l ) - ( suml+sgn*sumr )
                    scaloc = one
                    a11 = a( k, k ) + sgn*b( l, l )
                    da11 = abs( real( a11,KIND=sp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=sp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_cladiv( vec*cmplx( scaloc,KIND=sp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_csscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_30
           else if( .not.notrna .and. notrnb ) then
              ! solve    a**h *x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! upper-left corner column by column by
                  ! a**h(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                         ! k-1                           l-1
                ! r(k,l) = sum [a**h(i,k)*x(i,l)] + isgn*sum [x(k,j)*b(j,l)]
                         ! i=1                           j=1
              loop_60: do l = 1, n
                 do k = 1, m
                    suml = stdlib${ii}$_cdotc( k-1, a( 1_${ik}$, k ), 1_${ik}$, c( 1_${ik}$, l ), 1_${ik}$ )
                    sumr = stdlib${ii}$_cdotu( l-1, c( k, 1_${ik}$ ), ldc, b( 1_${ik}$, l ), 1_${ik}$ )
                    vec = c( k, l ) - ( suml+sgn*sumr )
                    scaloc = one
                    a11 = conjg( a( k, k ) ) + sgn*b( l, l )
                    da11 = abs( real( a11,KIND=sp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=sp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_cladiv( vec*cmplx( scaloc,KIND=sp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_csscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_60
           else if( .not.notrna .and. .not.notrnb ) then
              ! solve    a**h*x + isgn*x*b**h = c.
              ! the (k,l)th block of x is determined starting from
              ! upper-right corner column by column by
                  ! a**h(k,k)*x(k,l) + isgn*x(k,l)*b**h(l,l) = c(k,l) - r(k,l)
              ! where
                          ! k-1
                 ! r(k,l) = sum [a**h(i,k)*x(i,l)] +
                          ! i=1
                                 ! n
                           ! isgn*sum [x(k,j)*b**h(l,j)].
                                ! j=l+1
              loop_90: do l = n, 1, -1
                 do k = 1, m
                    suml = stdlib${ii}$_cdotc( k-1, a( 1_${ik}$, k ), 1_${ik}$, c( 1_${ik}$, l ), 1_${ik}$ )
                    sumr = stdlib${ii}$_cdotc( n-l, c( k, min( l+1, n ) ), ldc,b( l, min( l+1, n ) ), &
                              ldb )
                    vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
                    scaloc = one
                    a11 = conjg( a( k, k )+sgn*b( l, l ) )
                    da11 = abs( real( a11,KIND=sp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=sp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_cladiv( vec*cmplx( scaloc,KIND=sp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_csscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_90
           else if( notrna .and. .not.notrnb ) then
              ! solve    a*x + isgn*x*b**h = c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
                 ! a(k,k)*x(k,l) + isgn*x(k,l)*b**h(l,l) = c(k,l) - r(k,l)
              ! where
                          ! m                          n
                ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b**h(l,j)]
                        ! i=k+1                      j=l+1
              loop_120: do l = n, 1, -1
                 do k = m, 1, -1
                    suml = stdlib${ii}$_cdotu( m-k, a( k, min( k+1, m ) ), lda,c( min( k+1, m ), l ), 1_${ik}$ &
                              )
                    sumr = stdlib${ii}$_cdotc( n-l, c( k, min( l+1, n ) ), ldc,b( l, min( l+1, n ) ), &
                              ldb )
                    vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
                    scaloc = one
                    a11 = a( k, k ) + sgn*conjg( b( l, l ) )
                    da11 = abs( real( a11,KIND=sp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=sp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_cladiv( vec*cmplx( scaloc,KIND=sp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_csscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_120
           end if
           return
     end subroutine stdlib${ii}$_ctrsyl

     module subroutine stdlib${ii}$_ztrsyl( trana, tranb, isgn, m, n, a, lda, b, ldb, c,ldc, scale, info )
     !! ZTRSYL solves the complex Sylvester matrix equation:
     !! op(A)*X + X*op(B) = scale*C or
     !! op(A)*X - X*op(B) = scale*C,
     !! where op(A) = A or A**H, and A and B are both upper triangular. A is
     !! M-by-M and B is N-by-N; the right hand side C and the solution X are
     !! M-by-N; and scale is an output scale factor, set <= 1 to avoid
     !! overflow in X.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: trana, tranb
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, lda, ldb, ldc, m, n
           real(dp), intent(out) :: scale
           ! Array Arguments 
           complex(dp), intent(in) :: a(lda,*), b(ldb,*)
           complex(dp), intent(inout) :: c(ldc,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: notrna, notrnb
           integer(${ik}$) :: j, k, l
           real(dp) :: bignum, da11, db, eps, scaloc, sgn, smin, smlnum
           complex(dp) :: a11, suml, sumr, vec, x11
           ! Local Arrays 
           real(dp) :: dum(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test input parameters
           notrna = stdlib_lsame( trana, 'N' )
           notrnb = stdlib_lsame( tranb, 'N' )
           info = 0_${ik}$
           if( .not.notrna .and. .not.stdlib_lsame( trana, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.notrnb .and. .not.stdlib_lsame( tranb, 'C' ) ) then
              info = -2_${ik}$
           else if( isgn/=1_${ik}$ .and. isgn/=-1_${ik}$ ) then
              info = -3_${ik}$
           else if( m<0_${ik}$ ) then
              info = -4_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTRSYL', -info )
              return
           end if
           ! quick return if possible
           scale = one
           if( m==0 .or. n==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_dlamch( 'P' )
           smlnum = stdlib${ii}$_dlamch( 'S' )
           bignum = one / smlnum
           call stdlib${ii}$_dlabad( smlnum, bignum )
           smlnum = smlnum*real( m*n,KIND=dp) / eps
           bignum = one / smlnum
           smin = max( smlnum, eps*stdlib${ii}$_zlange( 'M', m, m, a, lda, dum ),eps*stdlib${ii}$_zlange( 'M',&
                      n, n, b, ldb, dum ) )
           sgn = isgn
           if( notrna .and. notrnb ) then
              ! solve    a*x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
                  ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                          ! m                        l-1
                ! r(k,l) = sum [a(k,i)*x(i,l)] +isgn*sum [x(k,j)*b(j,l)].
                        ! i=k+1                      j=1
              loop_30: do l = 1, n
                 do k = m, 1, -1
                    suml = stdlib${ii}$_zdotu( m-k, a( k, min( k+1, m ) ), lda,c( min( k+1, m ), l ), 1_${ik}$ &
                              )
                    sumr = stdlib${ii}$_zdotu( l-1, c( k, 1_${ik}$ ), ldc, b( 1_${ik}$, l ), 1_${ik}$ )
                    vec = c( k, l ) - ( suml+sgn*sumr )
                    scaloc = one
                    a11 = a( k, k ) + sgn*b( l, l )
                    da11 = abs( real( a11,KIND=dp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=dp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_zladiv( vec*cmplx( scaloc,KIND=dp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_zdscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_30
           else if( .not.notrna .and. notrnb ) then
              ! solve    a**h *x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! upper-left corner column by column by
                  ! a**h(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                         ! k-1                           l-1
                ! r(k,l) = sum [a**h(i,k)*x(i,l)] + isgn*sum [x(k,j)*b(j,l)]
                         ! i=1                           j=1
              loop_60: do l = 1, n
                 do k = 1, m
                    suml = stdlib${ii}$_zdotc( k-1, a( 1_${ik}$, k ), 1_${ik}$, c( 1_${ik}$, l ), 1_${ik}$ )
                    sumr = stdlib${ii}$_zdotu( l-1, c( k, 1_${ik}$ ), ldc, b( 1_${ik}$, l ), 1_${ik}$ )
                    vec = c( k, l ) - ( suml+sgn*sumr )
                    scaloc = one
                    a11 = conjg( a( k, k ) ) + sgn*b( l, l )
                    da11 = abs( real( a11,KIND=dp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=dp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_zladiv( vec*cmplx( scaloc,KIND=dp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_zdscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_60
           else if( .not.notrna .and. .not.notrnb ) then
              ! solve    a**h*x + isgn*x*b**h = c.
              ! the (k,l)th block of x is determined starting from
              ! upper-right corner column by column by
                  ! a**h(k,k)*x(k,l) + isgn*x(k,l)*b**h(l,l) = c(k,l) - r(k,l)
              ! where
                          ! k-1
                 ! r(k,l) = sum [a**h(i,k)*x(i,l)] +
                          ! i=1
                                 ! n
                           ! isgn*sum [x(k,j)*b**h(l,j)].
                                ! j=l+1
              loop_90: do l = n, 1, -1
                 do k = 1, m
                    suml = stdlib${ii}$_zdotc( k-1, a( 1_${ik}$, k ), 1_${ik}$, c( 1_${ik}$, l ), 1_${ik}$ )
                    sumr = stdlib${ii}$_zdotc( n-l, c( k, min( l+1, n ) ), ldc,b( l, min( l+1, n ) ), &
                              ldb )
                    vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
                    scaloc = one
                    a11 = conjg( a( k, k )+sgn*b( l, l ) )
                    da11 = abs( real( a11,KIND=dp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=dp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_zladiv( vec*cmplx( scaloc,KIND=dp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_zdscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_90
           else if( notrna .and. .not.notrnb ) then
              ! solve    a*x + isgn*x*b**h = c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
                 ! a(k,k)*x(k,l) + isgn*x(k,l)*b**h(l,l) = c(k,l) - r(k,l)
              ! where
                          ! m                          n
                ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b**h(l,j)]
                        ! i=k+1                      j=l+1
              loop_120: do l = n, 1, -1
                 do k = m, 1, -1
                    suml = stdlib${ii}$_zdotu( m-k, a( k, min( k+1, m ) ), lda,c( min( k+1, m ), l ), 1_${ik}$ &
                              )
                    sumr = stdlib${ii}$_zdotc( n-l, c( k, min( l+1, n ) ), ldc,b( l, min( l+1, n ) ), &
                              ldb )
                    vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
                    scaloc = one
                    a11 = a( k, k ) + sgn*conjg( b( l, l ) )
                    da11 = abs( real( a11,KIND=dp) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=dp) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_zladiv( vec*cmplx( scaloc,KIND=dp), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_zdscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_120
           end if
           return
     end subroutine stdlib${ii}$_ztrsyl

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     module subroutine stdlib${ii}$_${ci}$trsyl( trana, tranb, isgn, m, n, a, lda, b, ldb, c,ldc, scale, info )
     !! ZTRSYL: solves the complex Sylvester matrix equation:
     !! op(A)*X + X*op(B) = scale*C or
     !! op(A)*X - X*op(B) = scale*C,
     !! where op(A) = A or A**H, and A and B are both upper triangular. A is
     !! M-by-M and B is N-by-N; the right hand side C and the solution X are
     !! M-by-N; and scale is an output scale factor, set <= 1 to avoid
     !! overflow in X.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: trana, tranb
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, lda, ldb, ldc, m, n
           real(${ck}$), intent(out) :: scale
           ! Array Arguments 
           complex(${ck}$), intent(in) :: a(lda,*), b(ldb,*)
           complex(${ck}$), intent(inout) :: c(ldc,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: notrna, notrnb
           integer(${ik}$) :: j, k, l
           real(${ck}$) :: bignum, da11, db, eps, scaloc, sgn, smin, smlnum
           complex(${ck}$) :: a11, suml, sumr, vec, x11
           ! Local Arrays 
           real(${ck}$) :: dum(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test input parameters
           notrna = stdlib_lsame( trana, 'N' )
           notrnb = stdlib_lsame( tranb, 'N' )
           info = 0_${ik}$
           if( .not.notrna .and. .not.stdlib_lsame( trana, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.notrnb .and. .not.stdlib_lsame( tranb, 'C' ) ) then
              info = -2_${ik}$
           else if( isgn/=1_${ik}$ .and. isgn/=-1_${ik}$ ) then
              info = -3_${ik}$
           else if( m<0_${ik}$ ) then
              info = -4_${ik}$
           else if( n<0_${ik}$ ) then
              info = -5_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTRSYL', -info )
              return
           end if
           ! quick return if possible
           scale = one
           if( m==0 .or. n==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'P' )
           smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' )
           bignum = one / smlnum
           call stdlib${ii}$_${c2ri(ci)}$labad( smlnum, bignum )
           smlnum = smlnum*real( m*n,KIND=${ck}$) / eps
           bignum = one / smlnum
           smin = max( smlnum, eps*stdlib${ii}$_${ci}$lange( 'M', m, m, a, lda, dum ),eps*stdlib${ii}$_${ci}$lange( 'M',&
                      n, n, b, ldb, dum ) )
           sgn = isgn
           if( notrna .and. notrnb ) then
              ! solve    a*x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
                  ! a(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                          ! m                        l-1
                ! r(k,l) = sum [a(k,i)*x(i,l)] +isgn*sum [x(k,j)*b(j,l)].
                        ! i=k+1                      j=1
              loop_30: do l = 1, n
                 do k = m, 1, -1
                    suml = stdlib${ii}$_${ci}$dotu( m-k, a( k, min( k+1, m ) ), lda,c( min( k+1, m ), l ), 1_${ik}$ &
                              )
                    sumr = stdlib${ii}$_${ci}$dotu( l-1, c( k, 1_${ik}$ ), ldc, b( 1_${ik}$, l ), 1_${ik}$ )
                    vec = c( k, l ) - ( suml+sgn*sumr )
                    scaloc = one
                    a11 = a( k, k ) + sgn*b( l, l )
                    da11 = abs( real( a11,KIND=${ck}$) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=${ck}$) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_${ci}$ladiv( vec*cmplx( scaloc,KIND=${ck}$), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_${ci}$dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_30
           else if( .not.notrna .and. notrnb ) then
              ! solve    a**h *x + isgn*x*b = scale*c.
              ! the (k,l)th block of x is determined starting from
              ! upper-left corner column by column by
                  ! a**h(k,k)*x(k,l) + isgn*x(k,l)*b(l,l) = c(k,l) - r(k,l)
              ! where
                         ! k-1                           l-1
                ! r(k,l) = sum [a**h(i,k)*x(i,l)] + isgn*sum [x(k,j)*b(j,l)]
                         ! i=1                           j=1
              loop_60: do l = 1, n
                 do k = 1, m
                    suml = stdlib${ii}$_${ci}$dotc( k-1, a( 1_${ik}$, k ), 1_${ik}$, c( 1_${ik}$, l ), 1_${ik}$ )
                    sumr = stdlib${ii}$_${ci}$dotu( l-1, c( k, 1_${ik}$ ), ldc, b( 1_${ik}$, l ), 1_${ik}$ )
                    vec = c( k, l ) - ( suml+sgn*sumr )
                    scaloc = one
                    a11 = conjg( a( k, k ) ) + sgn*b( l, l )
                    da11 = abs( real( a11,KIND=${ck}$) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=${ck}$) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_${ci}$ladiv( vec*cmplx( scaloc,KIND=${ck}$), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_${ci}$dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_60
           else if( .not.notrna .and. .not.notrnb ) then
              ! solve    a**h*x + isgn*x*b**h = c.
              ! the (k,l)th block of x is determined starting from
              ! upper-right corner column by column by
                  ! a**h(k,k)*x(k,l) + isgn*x(k,l)*b**h(l,l) = c(k,l) - r(k,l)
              ! where
                          ! k-1
                 ! r(k,l) = sum [a**h(i,k)*x(i,l)] +
                          ! i=1
                                 ! n
                           ! isgn*sum [x(k,j)*b**h(l,j)].
                                ! j=l+1
              loop_90: do l = n, 1, -1
                 do k = 1, m
                    suml = stdlib${ii}$_${ci}$dotc( k-1, a( 1_${ik}$, k ), 1_${ik}$, c( 1_${ik}$, l ), 1_${ik}$ )
                    sumr = stdlib${ii}$_${ci}$dotc( n-l, c( k, min( l+1, n ) ), ldc,b( l, min( l+1, n ) ), &
                              ldb )
                    vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
                    scaloc = one
                    a11 = conjg( a( k, k )+sgn*b( l, l ) )
                    da11 = abs( real( a11,KIND=${ck}$) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=${ck}$) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_${ci}$ladiv( vec*cmplx( scaloc,KIND=${ck}$), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_${ci}$dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_90
           else if( notrna .and. .not.notrnb ) then
              ! solve    a*x + isgn*x*b**h = c.
              ! the (k,l)th block of x is determined starting from
              ! bottom-left corner column by column by
                 ! a(k,k)*x(k,l) + isgn*x(k,l)*b**h(l,l) = c(k,l) - r(k,l)
              ! where
                          ! m                          n
                ! r(k,l) = sum [a(k,i)*x(i,l)] + isgn*sum [x(k,j)*b**h(l,j)]
                        ! i=k+1                      j=l+1
              loop_120: do l = n, 1, -1
                 do k = m, 1, -1
                    suml = stdlib${ii}$_${ci}$dotu( m-k, a( k, min( k+1, m ) ), lda,c( min( k+1, m ), l ), 1_${ik}$ &
                              )
                    sumr = stdlib${ii}$_${ci}$dotc( n-l, c( k, min( l+1, n ) ), ldc,b( l, min( l+1, n ) ), &
                              ldb )
                    vec = c( k, l ) - ( suml+sgn*conjg( sumr ) )
                    scaloc = one
                    a11 = a( k, k ) + sgn*conjg( b( l, l ) )
                    da11 = abs( real( a11,KIND=${ck}$) ) + abs( aimag( a11 ) )
                    if( da11<=smin ) then
                       a11 = smin
                       da11 = smin
                       info = 1_${ik}$
                    end if
                    db = abs( real( vec,KIND=${ck}$) ) + abs( aimag( vec ) )
                    if( da11<one .and. db>one ) then
                       if( db>bignum*da11 )scaloc = one / db
                    end if
                    x11 = stdlib${ii}$_${ci}$ladiv( vec*cmplx( scaloc,KIND=${ck}$), a11 )
                    if( scaloc/=one ) then
                       do j = 1, n
                          call stdlib${ii}$_${ci}$dscal( m, scaloc, c( 1_${ik}$, j ), 1_${ik}$ )
                       end do
                       scale = scale*scaloc
                    end if
                    c( k, l ) = x11
                 end do
              end do loop_120
           end if
           return
     end subroutine stdlib${ii}$_${ci}$trsyl

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_slasy2( ltranl, ltranr, isgn, n1, n2, tl, ldtl, tr,ldtr, b, ldb, &
     !! SLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in
     !! op(TL)*X + ISGN*X*op(TR) = SCALE*B,
     !! where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or
     !! -1.  op(T) = T or T**T, where T**T denotes the transpose of T.
               scale, x, ldx, xnorm, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: ltranl, ltranr
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, ldb, ldtl, ldtr, ldx, n1, n2
           real(sp), intent(out) :: scale, xnorm
           ! Array Arguments 
           real(sp), intent(in) :: b(ldb,*), tl(ldtl,*), tr(ldtr,*)
           real(sp), intent(out) :: x(ldx,*)
       ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: bswap, xswap
           integer(${ik}$) :: i, ip, ipiv, ipsv, j, jp, jpsv, k
           real(sp) :: bet, eps, gam, l21, sgn, smin, smlnum, tau1, temp, u11, u12, u22, &
                     xmax
           ! Local Arrays 
           logical(lk) :: bswpiv(4_${ik}$), xswpiv(4_${ik}$)
           integer(${ik}$) :: jpiv(4_${ik}$), locl21(4_${ik}$), locu12(4_${ik}$), locu22(4_${ik}$)
           real(sp) :: btmp(4_${ik}$), t16(4_${ik}$,4_${ik}$), tmp(4_${ik}$), x2(2_${ik}$)
           ! Intrinsic Functions 
           ! Data Statements 
           locu12 = [3_${ik}$,4_${ik}$,1_${ik}$,2_${ik}$]
           locl21 = [2_${ik}$,1_${ik}$,4_${ik}$,3_${ik}$]
           locu22 = [4_${ik}$,3_${ik}$,2_${ik}$,1_${ik}$]
           xswpiv = [.false.,.false.,.true.,.true.]
           bswpiv = [.false.,.true.,.false.,.true.]
           ! Executable Statements 
           ! do not check the input parameters for errors
           info = 0_${ik}$
           ! quick return if possible
           if( n1==0 .or. n2==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_slamch( 'P' )
           smlnum = stdlib${ii}$_slamch( 'S' ) / eps
           sgn = isgn
           k = n1 + n1 + n2 - 2_${ik}$
           go to ( 10, 20, 30, 50 )k
           ! 1 by 1: tl11*x + sgn*x*tr11 = b11
           10 continue
           tau1 = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           bet = abs( tau1 )
           if( bet<=smlnum ) then
              tau1 = smlnum
              bet = smlnum
              info = 1_${ik}$
           end if
           scale = one
           gam = abs( b( 1_${ik}$, 1_${ik}$ ) )
           if( smlnum*gam>bet )scale = one / gam
           x( 1_${ik}$, 1_${ik}$ ) = ( b( 1_${ik}$, 1_${ik}$ )*scale ) / tau1
           xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) )
           return
           ! 1 by 2:
           ! tl11*[x11 x12] + isgn*[x11 x12]*op[tr11 tr12]  = [b11 b12]
                                             ! [tr21 tr22]
                                             20 continue
           smin = max( eps*max( abs( tl( 1_${ik}$, 1_${ik}$ ) ), abs( tr( 1_${ik}$, 1_${ik}$ ) ),abs( tr( 1_${ik}$, 2_${ik}$ ) ), abs( tr( &
                     2_${ik}$, 1_${ik}$ ) ), abs( tr( 2_${ik}$, 2_${ik}$ ) ) ),smlnum )
           tmp( 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           tmp( 4_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           if( ltranr ) then
              tmp( 2_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              tmp( 3_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
           else
              tmp( 2_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              tmp( 3_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 1_${ik}$, 2_${ik}$ )
           go to 40
           ! 2 by 1:
                ! op[tl11 tl12]*[x11] + isgn* [x11]*tr11  = [b11]
                  ! [tl21 tl22] [x21]         [x21]         [b21]
                  30 continue
           smin = max( eps*max( abs( tr( 1_${ik}$, 1_${ik}$ ) ), abs( tl( 1_${ik}$, 1_${ik}$ ) ),abs( tl( 1_${ik}$, 2_${ik}$ ) ), abs( tl( &
                     2_${ik}$, 1_${ik}$ ) ), abs( tl( 2_${ik}$, 2_${ik}$ ) ) ),smlnum )
           tmp( 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           tmp( 4_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           if( ltranl ) then
              tmp( 2_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              tmp( 3_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
           else
              tmp( 2_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              tmp( 3_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 2_${ik}$, 1_${ik}$ )
           40 continue
           ! solve 2 by 2 system using complete pivoting.
           ! set pivots less than smin to smin.
           ipiv = stdlib${ii}$_isamax( 4_${ik}$, tmp, 1_${ik}$ )
           u11 = tmp( ipiv )
           if( abs( u11 )<=smin ) then
              info = 1_${ik}$
              u11 = smin
           end if
           u12 = tmp( locu12( ipiv ) )
           l21 = tmp( locl21( ipiv ) ) / u11
           u22 = tmp( locu22( ipiv ) ) - u12*l21
           xswap = xswpiv( ipiv )
           bswap = bswpiv( ipiv )
           if( abs( u22 )<=smin ) then
              info = 1_${ik}$
              u22 = smin
           end if
           if( bswap ) then
              temp = btmp( 2_${ik}$ )
              btmp( 2_${ik}$ ) = btmp( 1_${ik}$ ) - l21*temp
              btmp( 1_${ik}$ ) = temp
           else
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ ) - l21*btmp( 1_${ik}$ )
           end if
           scale = one
           if( ( two*smlnum )*abs( btmp( 2_${ik}$ ) )>abs( u22 ) .or.( two*smlnum )*abs( btmp( 1_${ik}$ ) )>abs(&
                      u11 ) ) then
              scale = half / max( abs( btmp( 1_${ik}$ ) ), abs( btmp( 2_${ik}$ ) ) )
              btmp( 1_${ik}$ ) = btmp( 1_${ik}$ )*scale
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ )*scale
           end if
           x2( 2_${ik}$ ) = btmp( 2_${ik}$ ) / u22
           x2( 1_${ik}$ ) = btmp( 1_${ik}$ ) / u11 - ( u12 / u11 )*x2( 2_${ik}$ )
           if( xswap ) then
              temp = x2( 2_${ik}$ )
              x2( 2_${ik}$ ) = x2( 1_${ik}$ )
              x2( 1_${ik}$ ) = temp
           end if
           x( 1_${ik}$, 1_${ik}$ ) = x2( 1_${ik}$ )
           if( n1==1_${ik}$ ) then
              x( 1_${ik}$, 2_${ik}$ ) = x2( 2_${ik}$ )
              xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) ) + abs( x( 1_${ik}$, 2_${ik}$ ) )
           else
              x( 2_${ik}$, 1_${ik}$ ) = x2( 2_${ik}$ )
              xnorm = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 2_${ik}$, 1_${ik}$ ) ) )
           end if
           return
           ! 2 by 2:
           ! op[tl11 tl12]*[x11 x12] +isgn* [x11 x12]*op[tr11 tr12] = [b11 b12]
             ! [tl21 tl22] [x21 x22]        [x21 x22]   [tr21 tr22]   [b21 b22]
           ! solve equivalent 4 by 4 system using complete pivoting.
           ! set pivots less than smin to smin.
           50 continue
           smin = max( abs( tr( 1_${ik}$, 1_${ik}$ ) ), abs( tr( 1_${ik}$, 2_${ik}$ ) ),abs( tr( 2_${ik}$, 1_${ik}$ ) ), abs( tr( 2_${ik}$, 2_${ik}$ ) ) )
                     
           smin = max( smin, abs( tl( 1_${ik}$, 1_${ik}$ ) ), abs( tl( 1_${ik}$, 2_${ik}$ ) ),abs( tl( 2_${ik}$, 1_${ik}$ ) ), abs( tl( 2_${ik}$, &
                     2_${ik}$ ) ) )
           smin = max( eps*smin, smlnum )
           btmp( 1_${ik}$ ) = zero
           call stdlib${ii}$_scopy( 16_${ik}$, btmp, 0_${ik}$, t16, 1_${ik}$ )
           t16( 1_${ik}$, 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           t16( 2_${ik}$, 2_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           t16( 3_${ik}$, 3_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           t16( 4_${ik}$, 4_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           if( ltranl ) then
              t16( 1_${ik}$, 2_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 2_${ik}$, 1_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 3_${ik}$, 4_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 4_${ik}$, 3_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
           else
              t16( 1_${ik}$, 2_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 2_${ik}$, 1_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 3_${ik}$, 4_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 4_${ik}$, 3_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
           end if
           if( ltranr ) then
              t16( 1_${ik}$, 3_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 2_${ik}$, 4_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 3_${ik}$, 1_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 4_${ik}$, 2_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
           else
              t16( 1_${ik}$, 3_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 2_${ik}$, 4_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 3_${ik}$, 1_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 4_${ik}$, 2_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 2_${ik}$, 1_${ik}$ )
           btmp( 3_${ik}$ ) = b( 1_${ik}$, 2_${ik}$ )
           btmp( 4_${ik}$ ) = b( 2_${ik}$, 2_${ik}$ )
           ! perform elimination
           loop_100: do i = 1, 3
              xmax = zero
              do ip = i, 4
                 do jp = i, 4
                    if( abs( t16( ip, jp ) )>=xmax ) then
                       xmax = abs( t16( ip, jp ) )
                       ipsv = ip
                       jpsv = jp
                    end if
                 end do
              end do
              if( ipsv/=i ) then
                 call stdlib${ii}$_sswap( 4_${ik}$, t16( ipsv, 1_${ik}$ ), 4_${ik}$, t16( i, 1_${ik}$ ), 4_${ik}$ )
                 temp = btmp( i )
                 btmp( i ) = btmp( ipsv )
                 btmp( ipsv ) = temp
              end if
              if( jpsv/=i )call stdlib${ii}$_sswap( 4_${ik}$, t16( 1_${ik}$, jpsv ), 1_${ik}$, t16( 1_${ik}$, i ), 1_${ik}$ )
              jpiv( i ) = jpsv
              if( abs( t16( i, i ) )<smin ) then
                 info = 1_${ik}$
                 t16( i, i ) = smin
              end if
              do j = i + 1, 4
                 t16( j, i ) = t16( j, i ) / t16( i, i )
                 btmp( j ) = btmp( j ) - t16( j, i )*btmp( i )
                 do k = i + 1, 4
                    t16( j, k ) = t16( j, k ) - t16( j, i )*t16( i, k )
                 end do
              end do
           end do loop_100
           if( abs( t16( 4_${ik}$, 4_${ik}$ ) )<smin ) then
              info = 1_${ik}$
              t16( 4_${ik}$, 4_${ik}$ ) = smin
           end if
           scale = one
           if( ( eight*smlnum )*abs( btmp( 1_${ik}$ ) )>abs( t16( 1_${ik}$, 1_${ik}$ ) ) .or.( eight*smlnum )*abs( &
           btmp( 2_${ik}$ ) )>abs( t16( 2_${ik}$, 2_${ik}$ ) ) .or.( eight*smlnum )*abs( btmp( 3_${ik}$ ) )>abs( t16( 3_${ik}$, 3_${ik}$ ) )&
                      .or.( eight*smlnum )*abs( btmp( 4_${ik}$ ) )>abs( t16( 4_${ik}$, 4_${ik}$ ) ) ) then
              scale = ( one / eight ) / max( abs( btmp( 1_${ik}$ ) ),abs( btmp( 2_${ik}$ ) ), abs( btmp( 3_${ik}$ ) ), &
                        abs( btmp( 4_${ik}$ ) ) )
              btmp( 1_${ik}$ ) = btmp( 1_${ik}$ )*scale
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ )*scale
              btmp( 3_${ik}$ ) = btmp( 3_${ik}$ )*scale
              btmp( 4_${ik}$ ) = btmp( 4_${ik}$ )*scale
           end if
           do i = 1, 4
              k = 5_${ik}$ - i
              temp = one / t16( k, k )
              tmp( k ) = btmp( k )*temp
              do j = k + 1, 4
                 tmp( k ) = tmp( k ) - ( temp*t16( k, j ) )*tmp( j )
              end do
           end do
           do i = 1, 3
              if( jpiv( 4_${ik}$-i )/=4_${ik}$-i ) then
                 temp = tmp( 4_${ik}$-i )
                 tmp( 4_${ik}$-i ) = tmp( jpiv( 4_${ik}$-i ) )
                 tmp( jpiv( 4_${ik}$-i ) ) = temp
              end if
           end do
           x( 1_${ik}$, 1_${ik}$ ) = tmp( 1_${ik}$ )
           x( 2_${ik}$, 1_${ik}$ ) = tmp( 2_${ik}$ )
           x( 1_${ik}$, 2_${ik}$ ) = tmp( 3_${ik}$ )
           x( 2_${ik}$, 2_${ik}$ ) = tmp( 4_${ik}$ )
           xnorm = max( abs( tmp( 1_${ik}$ ) )+abs( tmp( 3_${ik}$ ) ),abs( tmp( 2_${ik}$ ) )+abs( tmp( 4_${ik}$ ) ) )
           return
     end subroutine stdlib${ii}$_slasy2

     pure module subroutine stdlib${ii}$_dlasy2( ltranl, ltranr, isgn, n1, n2, tl, ldtl, tr,ldtr, b, ldb, &
     !! DLASY2 solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in
     !! op(TL)*X + ISGN*X*op(TR) = SCALE*B,
     !! where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or
     !! -1.  op(T) = T or T**T, where T**T denotes the transpose of T.
               scale, x, ldx, xnorm, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: ltranl, ltranr
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, ldb, ldtl, ldtr, ldx, n1, n2
           real(dp), intent(out) :: scale, xnorm
           ! Array Arguments 
           real(dp), intent(in) :: b(ldb,*), tl(ldtl,*), tr(ldtr,*)
           real(dp), intent(out) :: x(ldx,*)
       ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: bswap, xswap
           integer(${ik}$) :: i, ip, ipiv, ipsv, j, jp, jpsv, k
           real(dp) :: bet, eps, gam, l21, sgn, smin, smlnum, tau1, temp, u11, u12, u22, &
                     xmax
           ! Local Arrays 
           logical(lk) :: bswpiv(4_${ik}$), xswpiv(4_${ik}$)
           integer(${ik}$) :: jpiv(4_${ik}$), locl21(4_${ik}$), locu12(4_${ik}$), locu22(4_${ik}$)
           real(dp) :: btmp(4_${ik}$), t16(4_${ik}$,4_${ik}$), tmp(4_${ik}$), x2(2_${ik}$)
           ! Intrinsic Functions 
           ! Data Statements 
           locu12 = [3_${ik}$,4_${ik}$,1_${ik}$,2_${ik}$]
           locl21 = [2_${ik}$,1_${ik}$,4_${ik}$,3_${ik}$]
           locu22 = [4_${ik}$,3_${ik}$,2_${ik}$,1_${ik}$]
           xswpiv = [.false.,.false.,.true.,.true.]
           bswpiv = [.false.,.true.,.false.,.true.]
           ! Executable Statements 
           ! do not check the input parameters for errors
           info = 0_${ik}$
           ! quick return if possible
           if( n1==0 .or. n2==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_dlamch( 'P' )
           smlnum = stdlib${ii}$_dlamch( 'S' ) / eps
           sgn = isgn
           k = n1 + n1 + n2 - 2_${ik}$
           go to ( 10, 20, 30, 50 )k
           ! 1 by 1: tl11*x + sgn*x*tr11 = b11
           10 continue
           tau1 = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           bet = abs( tau1 )
           if( bet<=smlnum ) then
              tau1 = smlnum
              bet = smlnum
              info = 1_${ik}$
           end if
           scale = one
           gam = abs( b( 1_${ik}$, 1_${ik}$ ) )
           if( smlnum*gam>bet )scale = one / gam
           x( 1_${ik}$, 1_${ik}$ ) = ( b( 1_${ik}$, 1_${ik}$ )*scale ) / tau1
           xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) )
           return
           ! 1 by 2:
           ! tl11*[x11 x12] + isgn*[x11 x12]*op[tr11 tr12]  = [b11 b12]
                                             ! [tr21 tr22]
                                             20 continue
           smin = max( eps*max( abs( tl( 1_${ik}$, 1_${ik}$ ) ), abs( tr( 1_${ik}$, 1_${ik}$ ) ),abs( tr( 1_${ik}$, 2_${ik}$ ) ), abs( tr( &
                     2_${ik}$, 1_${ik}$ ) ), abs( tr( 2_${ik}$, 2_${ik}$ ) ) ),smlnum )
           tmp( 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           tmp( 4_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           if( ltranr ) then
              tmp( 2_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              tmp( 3_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
           else
              tmp( 2_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              tmp( 3_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 1_${ik}$, 2_${ik}$ )
           go to 40
           ! 2 by 1:
                ! op[tl11 tl12]*[x11] + isgn* [x11]*tr11  = [b11]
                  ! [tl21 tl22] [x21]         [x21]         [b21]
                  30 continue
           smin = max( eps*max( abs( tr( 1_${ik}$, 1_${ik}$ ) ), abs( tl( 1_${ik}$, 1_${ik}$ ) ),abs( tl( 1_${ik}$, 2_${ik}$ ) ), abs( tl( &
                     2_${ik}$, 1_${ik}$ ) ), abs( tl( 2_${ik}$, 2_${ik}$ ) ) ),smlnum )
           tmp( 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           tmp( 4_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           if( ltranl ) then
              tmp( 2_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              tmp( 3_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
           else
              tmp( 2_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              tmp( 3_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 2_${ik}$, 1_${ik}$ )
           40 continue
           ! solve 2 by 2 system using complete pivoting.
           ! set pivots less than smin to smin.
           ipiv = stdlib${ii}$_idamax( 4_${ik}$, tmp, 1_${ik}$ )
           u11 = tmp( ipiv )
           if( abs( u11 )<=smin ) then
              info = 1_${ik}$
              u11 = smin
           end if
           u12 = tmp( locu12( ipiv ) )
           l21 = tmp( locl21( ipiv ) ) / u11
           u22 = tmp( locu22( ipiv ) ) - u12*l21
           xswap = xswpiv( ipiv )
           bswap = bswpiv( ipiv )
           if( abs( u22 )<=smin ) then
              info = 1_${ik}$
              u22 = smin
           end if
           if( bswap ) then
              temp = btmp( 2_${ik}$ )
              btmp( 2_${ik}$ ) = btmp( 1_${ik}$ ) - l21*temp
              btmp( 1_${ik}$ ) = temp
           else
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ ) - l21*btmp( 1_${ik}$ )
           end if
           scale = one
           if( ( two*smlnum )*abs( btmp( 2_${ik}$ ) )>abs( u22 ) .or.( two*smlnum )*abs( btmp( 1_${ik}$ ) )>abs(&
                      u11 ) ) then
              scale = half / max( abs( btmp( 1_${ik}$ ) ), abs( btmp( 2_${ik}$ ) ) )
              btmp( 1_${ik}$ ) = btmp( 1_${ik}$ )*scale
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ )*scale
           end if
           x2( 2_${ik}$ ) = btmp( 2_${ik}$ ) / u22
           x2( 1_${ik}$ ) = btmp( 1_${ik}$ ) / u11 - ( u12 / u11 )*x2( 2_${ik}$ )
           if( xswap ) then
              temp = x2( 2_${ik}$ )
              x2( 2_${ik}$ ) = x2( 1_${ik}$ )
              x2( 1_${ik}$ ) = temp
           end if
           x( 1_${ik}$, 1_${ik}$ ) = x2( 1_${ik}$ )
           if( n1==1_${ik}$ ) then
              x( 1_${ik}$, 2_${ik}$ ) = x2( 2_${ik}$ )
              xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) ) + abs( x( 1_${ik}$, 2_${ik}$ ) )
           else
              x( 2_${ik}$, 1_${ik}$ ) = x2( 2_${ik}$ )
              xnorm = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 2_${ik}$, 1_${ik}$ ) ) )
           end if
           return
           ! 2 by 2:
           ! op[tl11 tl12]*[x11 x12] +isgn* [x11 x12]*op[tr11 tr12] = [b11 b12]
             ! [tl21 tl22] [x21 x22]        [x21 x22]   [tr21 tr22]   [b21 b22]
           ! solve equivalent 4 by 4 system using complete pivoting.
           ! set pivots less than smin to smin.
           50 continue
           smin = max( abs( tr( 1_${ik}$, 1_${ik}$ ) ), abs( tr( 1_${ik}$, 2_${ik}$ ) ),abs( tr( 2_${ik}$, 1_${ik}$ ) ), abs( tr( 2_${ik}$, 2_${ik}$ ) ) )
                     
           smin = max( smin, abs( tl( 1_${ik}$, 1_${ik}$ ) ), abs( tl( 1_${ik}$, 2_${ik}$ ) ),abs( tl( 2_${ik}$, 1_${ik}$ ) ), abs( tl( 2_${ik}$, &
                     2_${ik}$ ) ) )
           smin = max( eps*smin, smlnum )
           btmp( 1_${ik}$ ) = zero
           call stdlib${ii}$_dcopy( 16_${ik}$, btmp, 0_${ik}$, t16, 1_${ik}$ )
           t16( 1_${ik}$, 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           t16( 2_${ik}$, 2_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           t16( 3_${ik}$, 3_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           t16( 4_${ik}$, 4_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           if( ltranl ) then
              t16( 1_${ik}$, 2_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 2_${ik}$, 1_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 3_${ik}$, 4_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 4_${ik}$, 3_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
           else
              t16( 1_${ik}$, 2_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 2_${ik}$, 1_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 3_${ik}$, 4_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 4_${ik}$, 3_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
           end if
           if( ltranr ) then
              t16( 1_${ik}$, 3_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 2_${ik}$, 4_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 3_${ik}$, 1_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 4_${ik}$, 2_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
           else
              t16( 1_${ik}$, 3_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 2_${ik}$, 4_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 3_${ik}$, 1_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 4_${ik}$, 2_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 2_${ik}$, 1_${ik}$ )
           btmp( 3_${ik}$ ) = b( 1_${ik}$, 2_${ik}$ )
           btmp( 4_${ik}$ ) = b( 2_${ik}$, 2_${ik}$ )
           ! perform elimination
           loop_100: do i = 1, 3
              xmax = zero
              do ip = i, 4
                 do jp = i, 4
                    if( abs( t16( ip, jp ) )>=xmax ) then
                       xmax = abs( t16( ip, jp ) )
                       ipsv = ip
                       jpsv = jp
                    end if
                 end do
              end do
              if( ipsv/=i ) then
                 call stdlib${ii}$_dswap( 4_${ik}$, t16( ipsv, 1_${ik}$ ), 4_${ik}$, t16( i, 1_${ik}$ ), 4_${ik}$ )
                 temp = btmp( i )
                 btmp( i ) = btmp( ipsv )
                 btmp( ipsv ) = temp
              end if
              if( jpsv/=i )call stdlib${ii}$_dswap( 4_${ik}$, t16( 1_${ik}$, jpsv ), 1_${ik}$, t16( 1_${ik}$, i ), 1_${ik}$ )
              jpiv( i ) = jpsv
              if( abs( t16( i, i ) )<smin ) then
                 info = 1_${ik}$
                 t16( i, i ) = smin
              end if
              do j = i + 1, 4
                 t16( j, i ) = t16( j, i ) / t16( i, i )
                 btmp( j ) = btmp( j ) - t16( j, i )*btmp( i )
                 do k = i + 1, 4
                    t16( j, k ) = t16( j, k ) - t16( j, i )*t16( i, k )
                 end do
              end do
           end do loop_100
           if( abs( t16( 4_${ik}$, 4_${ik}$ ) )<smin ) then
              info = 1_${ik}$
              t16( 4_${ik}$, 4_${ik}$ ) = smin
           end if
           scale = one
           if( ( eight*smlnum )*abs( btmp( 1_${ik}$ ) )>abs( t16( 1_${ik}$, 1_${ik}$ ) ) .or.( eight*smlnum )*abs( &
           btmp( 2_${ik}$ ) )>abs( t16( 2_${ik}$, 2_${ik}$ ) ) .or.( eight*smlnum )*abs( btmp( 3_${ik}$ ) )>abs( t16( 3_${ik}$, 3_${ik}$ ) )&
                      .or.( eight*smlnum )*abs( btmp( 4_${ik}$ ) )>abs( t16( 4_${ik}$, 4_${ik}$ ) ) ) then
              scale = ( one / eight ) / max( abs( btmp( 1_${ik}$ ) ),abs( btmp( 2_${ik}$ ) ), abs( btmp( 3_${ik}$ ) ), &
                        abs( btmp( 4_${ik}$ ) ) )
              btmp( 1_${ik}$ ) = btmp( 1_${ik}$ )*scale
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ )*scale
              btmp( 3_${ik}$ ) = btmp( 3_${ik}$ )*scale
              btmp( 4_${ik}$ ) = btmp( 4_${ik}$ )*scale
           end if
           do i = 1, 4
              k = 5_${ik}$ - i
              temp = one / t16( k, k )
              tmp( k ) = btmp( k )*temp
              do j = k + 1, 4
                 tmp( k ) = tmp( k ) - ( temp*t16( k, j ) )*tmp( j )
              end do
           end do
           do i = 1, 3
              if( jpiv( 4_${ik}$-i )/=4_${ik}$-i ) then
                 temp = tmp( 4_${ik}$-i )
                 tmp( 4_${ik}$-i ) = tmp( jpiv( 4_${ik}$-i ) )
                 tmp( jpiv( 4_${ik}$-i ) ) = temp
              end if
           end do
           x( 1_${ik}$, 1_${ik}$ ) = tmp( 1_${ik}$ )
           x( 2_${ik}$, 1_${ik}$ ) = tmp( 2_${ik}$ )
           x( 1_${ik}$, 2_${ik}$ ) = tmp( 3_${ik}$ )
           x( 2_${ik}$, 2_${ik}$ ) = tmp( 4_${ik}$ )
           xnorm = max( abs( tmp( 1_${ik}$ ) )+abs( tmp( 3_${ik}$ ) ),abs( tmp( 2_${ik}$ ) )+abs( tmp( 4_${ik}$ ) ) )
           return
     end subroutine stdlib${ii}$_dlasy2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$lasy2( ltranl, ltranr, isgn, n1, n2, tl, ldtl, tr,ldtr, b, ldb, &
     !! DLASY2: solves for the N1 by N2 matrix X, 1 <= N1,N2 <= 2, in
     !! op(TL)*X + ISGN*X*op(TR) = SCALE*B,
     !! where TL is N1 by N1, TR is N2 by N2, B is N1 by N2, and ISGN = 1 or
     !! -1.  op(T) = T or T**T, where T**T denotes the transpose of T.
               scale, x, ldx, xnorm, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: ltranl, ltranr
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: isgn, ldb, ldtl, ldtr, ldx, n1, n2
           real(${rk}$), intent(out) :: scale, xnorm
           ! Array Arguments 
           real(${rk}$), intent(in) :: b(ldb,*), tl(ldtl,*), tr(ldtr,*)
           real(${rk}$), intent(out) :: x(ldx,*)
       ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: bswap, xswap
           integer(${ik}$) :: i, ip, ipiv, ipsv, j, jp, jpsv, k
           real(${rk}$) :: bet, eps, gam, l21, sgn, smin, smlnum, tau1, temp, u11, u12, u22, &
                     xmax
           ! Local Arrays 
           logical(lk) :: bswpiv(4_${ik}$), xswpiv(4_${ik}$)
           integer(${ik}$) :: jpiv(4_${ik}$), locl21(4_${ik}$), locu12(4_${ik}$), locu22(4_${ik}$)
           real(${rk}$) :: btmp(4_${ik}$), t16(4_${ik}$,4_${ik}$), tmp(4_${ik}$), x2(2_${ik}$)
           ! Intrinsic Functions 
           ! Data Statements 
           locu12 = [3_${ik}$,4_${ik}$,1_${ik}$,2_${ik}$]
           locl21 = [2_${ik}$,1_${ik}$,4_${ik}$,3_${ik}$]
           locu22 = [4_${ik}$,3_${ik}$,2_${ik}$,1_${ik}$]
           xswpiv = [.false.,.false.,.true.,.true.]
           bswpiv = [.false.,.true.,.false.,.true.]
           ! Executable Statements 
           ! do not check the input parameters for errors
           info = 0_${ik}$
           ! quick return if possible
           if( n1==0 .or. n2==0 )return
           ! set constants to control overflow
           eps = stdlib${ii}$_${ri}$lamch( 'P' )
           smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) / eps
           sgn = isgn
           k = n1 + n1 + n2 - 2_${ik}$
           go to ( 10, 20, 30, 50 )k
           ! 1 by 1: tl11*x + sgn*x*tr11 = b11
           10 continue
           tau1 = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           bet = abs( tau1 )
           if( bet<=smlnum ) then
              tau1 = smlnum
              bet = smlnum
              info = 1_${ik}$
           end if
           scale = one
           gam = abs( b( 1_${ik}$, 1_${ik}$ ) )
           if( smlnum*gam>bet )scale = one / gam
           x( 1_${ik}$, 1_${ik}$ ) = ( b( 1_${ik}$, 1_${ik}$ )*scale ) / tau1
           xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) )
           return
           ! 1 by 2:
           ! tl11*[x11 x12] + isgn*[x11 x12]*op[tr11 tr12]  = [b11 b12]
                                             ! [tr21 tr22]
                                             20 continue
           smin = max( eps*max( abs( tl( 1_${ik}$, 1_${ik}$ ) ), abs( tr( 1_${ik}$, 1_${ik}$ ) ),abs( tr( 1_${ik}$, 2_${ik}$ ) ), abs( tr( &
                     2_${ik}$, 1_${ik}$ ) ), abs( tr( 2_${ik}$, 2_${ik}$ ) ) ),smlnum )
           tmp( 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           tmp( 4_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           if( ltranr ) then
              tmp( 2_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              tmp( 3_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
           else
              tmp( 2_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              tmp( 3_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 1_${ik}$, 2_${ik}$ )
           go to 40
           ! 2 by 1:
                ! op[tl11 tl12]*[x11] + isgn* [x11]*tr11  = [b11]
                  ! [tl21 tl22] [x21]         [x21]         [b21]
                  30 continue
           smin = max( eps*max( abs( tr( 1_${ik}$, 1_${ik}$ ) ), abs( tl( 1_${ik}$, 1_${ik}$ ) ),abs( tl( 1_${ik}$, 2_${ik}$ ) ), abs( tl( &
                     2_${ik}$, 1_${ik}$ ) ), abs( tl( 2_${ik}$, 2_${ik}$ ) ) ),smlnum )
           tmp( 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           tmp( 4_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           if( ltranl ) then
              tmp( 2_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              tmp( 3_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
           else
              tmp( 2_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              tmp( 3_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 2_${ik}$, 1_${ik}$ )
           40 continue
           ! solve 2 by 2 system using complete pivoting.
           ! set pivots less than smin to smin.
           ipiv = stdlib${ii}$_i${ri}$amax( 4_${ik}$, tmp, 1_${ik}$ )
           u11 = tmp( ipiv )
           if( abs( u11 )<=smin ) then
              info = 1_${ik}$
              u11 = smin
           end if
           u12 = tmp( locu12( ipiv ) )
           l21 = tmp( locl21( ipiv ) ) / u11
           u22 = tmp( locu22( ipiv ) ) - u12*l21
           xswap = xswpiv( ipiv )
           bswap = bswpiv( ipiv )
           if( abs( u22 )<=smin ) then
              info = 1_${ik}$
              u22 = smin
           end if
           if( bswap ) then
              temp = btmp( 2_${ik}$ )
              btmp( 2_${ik}$ ) = btmp( 1_${ik}$ ) - l21*temp
              btmp( 1_${ik}$ ) = temp
           else
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ ) - l21*btmp( 1_${ik}$ )
           end if
           scale = one
           if( ( two*smlnum )*abs( btmp( 2_${ik}$ ) )>abs( u22 ) .or.( two*smlnum )*abs( btmp( 1_${ik}$ ) )>abs(&
                      u11 ) ) then
              scale = half / max( abs( btmp( 1_${ik}$ ) ), abs( btmp( 2_${ik}$ ) ) )
              btmp( 1_${ik}$ ) = btmp( 1_${ik}$ )*scale
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ )*scale
           end if
           x2( 2_${ik}$ ) = btmp( 2_${ik}$ ) / u22
           x2( 1_${ik}$ ) = btmp( 1_${ik}$ ) / u11 - ( u12 / u11 )*x2( 2_${ik}$ )
           if( xswap ) then
              temp = x2( 2_${ik}$ )
              x2( 2_${ik}$ ) = x2( 1_${ik}$ )
              x2( 1_${ik}$ ) = temp
           end if
           x( 1_${ik}$, 1_${ik}$ ) = x2( 1_${ik}$ )
           if( n1==1_${ik}$ ) then
              x( 1_${ik}$, 2_${ik}$ ) = x2( 2_${ik}$ )
              xnorm = abs( x( 1_${ik}$, 1_${ik}$ ) ) + abs( x( 1_${ik}$, 2_${ik}$ ) )
           else
              x( 2_${ik}$, 1_${ik}$ ) = x2( 2_${ik}$ )
              xnorm = max( abs( x( 1_${ik}$, 1_${ik}$ ) ), abs( x( 2_${ik}$, 1_${ik}$ ) ) )
           end if
           return
           ! 2 by 2:
           ! op[tl11 tl12]*[x11 x12] +isgn* [x11 x12]*op[tr11 tr12] = [b11 b12]
             ! [tl21 tl22] [x21 x22]        [x21 x22]   [tr21 tr22]   [b21 b22]
           ! solve equivalent 4 by 4 system using complete pivoting.
           ! set pivots less than smin to smin.
           50 continue
           smin = max( abs( tr( 1_${ik}$, 1_${ik}$ ) ), abs( tr( 1_${ik}$, 2_${ik}$ ) ),abs( tr( 2_${ik}$, 1_${ik}$ ) ), abs( tr( 2_${ik}$, 2_${ik}$ ) ) )
                     
           smin = max( smin, abs( tl( 1_${ik}$, 1_${ik}$ ) ), abs( tl( 1_${ik}$, 2_${ik}$ ) ),abs( tl( 2_${ik}$, 1_${ik}$ ) ), abs( tl( 2_${ik}$, &
                     2_${ik}$ ) ) )
           smin = max( eps*smin, smlnum )
           btmp( 1_${ik}$ ) = zero
           call stdlib${ii}$_${ri}$copy( 16_${ik}$, btmp, 0_${ik}$, t16, 1_${ik}$ )
           t16( 1_${ik}$, 1_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           t16( 2_${ik}$, 2_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 1_${ik}$, 1_${ik}$ )
           t16( 3_${ik}$, 3_${ik}$ ) = tl( 1_${ik}$, 1_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           t16( 4_${ik}$, 4_${ik}$ ) = tl( 2_${ik}$, 2_${ik}$ ) + sgn*tr( 2_${ik}$, 2_${ik}$ )
           if( ltranl ) then
              t16( 1_${ik}$, 2_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 2_${ik}$, 1_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 3_${ik}$, 4_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 4_${ik}$, 3_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
           else
              t16( 1_${ik}$, 2_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 2_${ik}$, 1_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
              t16( 3_${ik}$, 4_${ik}$ ) = tl( 1_${ik}$, 2_${ik}$ )
              t16( 4_${ik}$, 3_${ik}$ ) = tl( 2_${ik}$, 1_${ik}$ )
           end if
           if( ltranr ) then
              t16( 1_${ik}$, 3_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 2_${ik}$, 4_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 3_${ik}$, 1_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 4_${ik}$, 2_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
           else
              t16( 1_${ik}$, 3_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 2_${ik}$, 4_${ik}$ ) = sgn*tr( 2_${ik}$, 1_${ik}$ )
              t16( 3_${ik}$, 1_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
              t16( 4_${ik}$, 2_${ik}$ ) = sgn*tr( 1_${ik}$, 2_${ik}$ )
           end if
           btmp( 1_${ik}$ ) = b( 1_${ik}$, 1_${ik}$ )
           btmp( 2_${ik}$ ) = b( 2_${ik}$, 1_${ik}$ )
           btmp( 3_${ik}$ ) = b( 1_${ik}$, 2_${ik}$ )
           btmp( 4_${ik}$ ) = b( 2_${ik}$, 2_${ik}$ )
           ! perform elimination
           loop_100: do i = 1, 3
              xmax = zero
              do ip = i, 4
                 do jp = i, 4
                    if( abs( t16( ip, jp ) )>=xmax ) then
                       xmax = abs( t16( ip, jp ) )
                       ipsv = ip
                       jpsv = jp
                    end if
                 end do
              end do
              if( ipsv/=i ) then
                 call stdlib${ii}$_${ri}$swap( 4_${ik}$, t16( ipsv, 1_${ik}$ ), 4_${ik}$, t16( i, 1_${ik}$ ), 4_${ik}$ )
                 temp = btmp( i )
                 btmp( i ) = btmp( ipsv )
                 btmp( ipsv ) = temp
              end if
              if( jpsv/=i )call stdlib${ii}$_${ri}$swap( 4_${ik}$, t16( 1_${ik}$, jpsv ), 1_${ik}$, t16( 1_${ik}$, i ), 1_${ik}$ )
              jpiv( i ) = jpsv
              if( abs( t16( i, i ) )<smin ) then
                 info = 1_${ik}$
                 t16( i, i ) = smin
              end if
              do j = i + 1, 4
                 t16( j, i ) = t16( j, i ) / t16( i, i )
                 btmp( j ) = btmp( j ) - t16( j, i )*btmp( i )
                 do k = i + 1, 4
                    t16( j, k ) = t16( j, k ) - t16( j, i )*t16( i, k )
                 end do
              end do
           end do loop_100
           if( abs( t16( 4_${ik}$, 4_${ik}$ ) )<smin ) then
              info = 1_${ik}$
              t16( 4_${ik}$, 4_${ik}$ ) = smin
           end if
           scale = one
           if( ( eight*smlnum )*abs( btmp( 1_${ik}$ ) )>abs( t16( 1_${ik}$, 1_${ik}$ ) ) .or.( eight*smlnum )*abs( &
           btmp( 2_${ik}$ ) )>abs( t16( 2_${ik}$, 2_${ik}$ ) ) .or.( eight*smlnum )*abs( btmp( 3_${ik}$ ) )>abs( t16( 3_${ik}$, 3_${ik}$ ) )&
                      .or.( eight*smlnum )*abs( btmp( 4_${ik}$ ) )>abs( t16( 4_${ik}$, 4_${ik}$ ) ) ) then
              scale = ( one / eight ) / max( abs( btmp( 1_${ik}$ ) ),abs( btmp( 2_${ik}$ ) ), abs( btmp( 3_${ik}$ ) ), &
                        abs( btmp( 4_${ik}$ ) ) )
              btmp( 1_${ik}$ ) = btmp( 1_${ik}$ )*scale
              btmp( 2_${ik}$ ) = btmp( 2_${ik}$ )*scale
              btmp( 3_${ik}$ ) = btmp( 3_${ik}$ )*scale
              btmp( 4_${ik}$ ) = btmp( 4_${ik}$ )*scale
           end if
           do i = 1, 4
              k = 5_${ik}$ - i
              temp = one / t16( k, k )
              tmp( k ) = btmp( k )*temp
              do j = k + 1, 4
                 tmp( k ) = tmp( k ) - ( temp*t16( k, j ) )*tmp( j )
              end do
           end do
           do i = 1, 3
              if( jpiv( 4_${ik}$-i )/=4_${ik}$-i ) then
                 temp = tmp( 4_${ik}$-i )
                 tmp( 4_${ik}$-i ) = tmp( jpiv( 4_${ik}$-i ) )
                 tmp( jpiv( 4_${ik}$-i ) ) = temp
              end if
           end do
           x( 1_${ik}$, 1_${ik}$ ) = tmp( 1_${ik}$ )
           x( 2_${ik}$, 1_${ik}$ ) = tmp( 2_${ik}$ )
           x( 1_${ik}$, 2_${ik}$ ) = tmp( 3_${ik}$ )
           x( 2_${ik}$, 2_${ik}$ ) = tmp( 4_${ik}$ )
           xnorm = max( abs( tmp( 1_${ik}$ ) )+abs( tmp( 3_${ik}$ ) ),abs( tmp( 2_${ik}$ ) )+abs( tmp( 4_${ik}$ ) ) )
           return
     end subroutine stdlib${ii}$_${ri}$lasy2

#:endif
#:endfor



     module subroutine stdlib${ii}$_strsna( job, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, s, sep, mm, m, &
     !! STRSNA estimates reciprocal condition numbers for specified
     !! eigenvalues and/or right eigenvectors of a real upper
     !! quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q
     !! orthogonal).
     !! T must be in Schur canonical form (as returned by SHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               work, ldwork, iwork,info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, ldwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(out) :: s(*), sep(*), work(ldwork,*)
           real(sp), intent(in) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: pair, somcon, wantbh, wants, wantsp
           integer(${ik}$) :: i, ierr, ifst, ilst, j, k, kase, ks, n2, nn
           real(sp) :: bignum, cond, cs, delta, dumm, eps, est, lnrm, mu, prod, prod1, prod2, &
                     rnrm, scale, smlnum, sn
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           real(sp) :: dummy(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           somcon = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           if( .not.wants .and. .not.wantsp ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( howmny, 'A' ) .and. .not.somcon ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( wants .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( wants .and. ldvr<n ) ) then
              info = -10_${ik}$
           else
              ! set m to the number of eigenpairs for which condition numbers
              ! are required, and test mm.
              if( somcon ) then
                 m = 0_${ik}$
                 pair = .false.
                 do k = 1, n
                    if( pair ) then
                       pair = .false.
                    else
                       if( k<n ) then
                          if( t( k+1, k )==zero ) then
                             if( select( k ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( k ) .or. select( k+1 ) )m = m + 2_${ik}$
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -13_${ik}$
              else if( ldwork<1_${ik}$ .or. ( wantsp .and. ldwork<n ) ) then
                 info = -16_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'STRSNA', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( n==1_${ik}$ ) then
              if( somcon ) then
                 if( .not.select( 1 ) )return
              end if
              if( wants )s( 1_${ik}$ ) = one
              if( wantsp )sep( 1_${ik}$ ) = abs( t( 1_${ik}$, 1_${ik}$ ) )
              return
           end if
           ! get machine constants
           eps = stdlib${ii}$_slamch( 'P' )
           smlnum = stdlib${ii}$_slamch( 'S' ) / eps
           bignum = one / smlnum
           call stdlib${ii}$_slabad( smlnum, bignum )
           ks = 0_${ik}$
           pair = .false.
           loop_60: do k = 1, n
              ! determine whether t(k,k) begins a 1-by-1 or 2-by-2 block.
              if( pair ) then
                 pair = .false.
                 cycle loop_60
              else
                 if( k<n )pair = t( k+1, k )/=zero
              end if
              ! determine whether condition numbers are required for the k-th
              ! eigenpair.
              if( somcon ) then
                 if( pair ) then
                    if( .not.select( k ) .and. .not.select( k+1 ) )cycle loop_60
                 else
                    if( .not.select( k ) )cycle loop_60
                 end if
              end if
              ks = ks + 1_${ik}$
              if( wants ) then
                 ! compute the reciprocal condition number of the k-th
                 ! eigenvalue.
                 if( .not.pair ) then
                    ! real eigenvalue.
                    prod = stdlib${ii}$_sdot( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    rnrm = stdlib${ii}$_snrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ )
                    lnrm = stdlib${ii}$_snrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    s( ks ) = abs( prod ) / ( rnrm*lnrm )
                 else
                    ! complex eigenvalue.
                    prod1 = stdlib${ii}$_sdot( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    prod1 = prod1 + stdlib${ii}$_sdot( n, vr( 1_${ik}$, ks+1 ), 1_${ik}$, vl( 1_${ik}$, ks+1 ),1_${ik}$ )
                    prod2 = stdlib${ii}$_sdot( n, vl( 1_${ik}$, ks ), 1_${ik}$, vr( 1_${ik}$, ks+1 ), 1_${ik}$ )
                    prod2 = prod2 - stdlib${ii}$_sdot( n, vl( 1_${ik}$, ks+1 ), 1_${ik}$, vr( 1_${ik}$, ks ),1_${ik}$ )
                    rnrm = stdlib${ii}$_slapy2( stdlib${ii}$_snrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ ),stdlib${ii}$_snrm2( n, vr( &
                              1_${ik}$, ks+1 ), 1_${ik}$ ) )
                    lnrm = stdlib${ii}$_slapy2( stdlib${ii}$_snrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ ),stdlib${ii}$_snrm2( n, vl( &
                              1_${ik}$, ks+1 ), 1_${ik}$ ) )
                    cond = stdlib${ii}$_slapy2( prod1, prod2 ) / ( rnrm*lnrm )
                    s( ks ) = cond
                    s( ks+1 ) = cond
                 end if
              end if
              if( wantsp ) then
                 ! estimate the reciprocal condition number of the k-th
                 ! eigenvector.
                 ! copy the matrix t to the array work and swap the diagonal
                 ! block beginning at t(k,k) to the (1,1) position.
                 call stdlib${ii}$_slacpy( 'FULL', n, n, t, ldt, work, ldwork )
                 ifst = k
                 ilst = 1_${ik}$
                 call stdlib${ii}$_strexc( 'NO Q', n, work, ldwork, dummy, 1_${ik}$, ifst, ilst,work( 1_${ik}$, n+1 ),&
                            ierr )
                 if( ierr==1_${ik}$ .or. ierr==2_${ik}$ ) then
                    ! could not swap because blocks not well separated
                    scale = one
                    est = bignum
                 else
                    ! reordering successful
                    if( work( 2_${ik}$, 1_${ik}$ )==zero ) then
                       ! form c = t22 - lambda*i in work(2:n,2:n).
                       do i = 2, n
                          work( i, i ) = work( i, i ) - work( 1_${ik}$, 1_${ik}$ )
                       end do
                       n2 = 1_${ik}$
                       nn = n - 1_${ik}$
                    else
                       ! triangularize the 2 by 2 block by unitary
                       ! transformation u = [  cs   i*ss ]
                                          ! [ i*ss   cs  ].
                       ! such that the (1,1) position of work is complex
                       ! eigenvalue lambda with positive imaginary part. (2,2)
                       ! position of work is the complex eigenvalue lambda
                       ! with negative imaginary  part.
                       mu = sqrt( abs( work( 1_${ik}$, 2_${ik}$ ) ) )*sqrt( abs( work( 2_${ik}$, 1_${ik}$ ) ) )
                       delta = stdlib${ii}$_slapy2( mu, work( 2_${ik}$, 1_${ik}$ ) )
                       cs = mu / delta
                       sn = -work( 2_${ik}$, 1_${ik}$ ) / delta
                       ! form
                       ! c**t = work(2:n,2:n) + i*[rwork(1) ..... rwork(n-1) ]
                                                ! [   mu                     ]
                                                ! [         ..               ]
                                                ! [             ..           ]
                                                ! [                  mu      ]
                       ! where c**t is transpose of matrix c,
                       ! and rwork is stored starting in the n+1-st column of
                       ! work.
                       do j = 3, n
                          work( 2_${ik}$, j ) = cs*work( 2_${ik}$, j )
                          work( j, j ) = work( j, j ) - work( 1_${ik}$, 1_${ik}$ )
                       end do
                       work( 2_${ik}$, 2_${ik}$ ) = zero
                       work( 1_${ik}$, n+1 ) = two*mu
                       do i = 2, n - 1
                          work( i, n+1 ) = sn*work( 1_${ik}$, i+1 )
                       end do
                       n2 = 2_${ik}$
                       nn = 2_${ik}$*( n-1 )
                    end if
                    ! estimate norm(inv(c**t))
                    est = zero
                    kase = 0_${ik}$
                    50 continue
                    call stdlib${ii}$_slacn2( nn, work( 1_${ik}$, n+2 ), work( 1_${ik}$, n+4 ), iwork,est, kase, &
                              isave )
                    if( kase/=0_${ik}$ ) then
                       if( kase==1_${ik}$ ) then
                          if( n2==1_${ik}$ ) then
                             ! real eigenvalue: solve c**t*x = scale*c.
                             call stdlib${ii}$_slaqtr( .true., .true., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, dummy, &
                                       dumm, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          else
                             ! complex eigenvalue: solve
                             ! c**t*(p+iq) = scale*(c+id) in real arithmetic.
                             call stdlib${ii}$_slaqtr( .true., .false., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, work( &
                                       1_${ik}$, n+1 ), mu, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          end if
                       else
                          if( n2==1_${ik}$ ) then
                             ! real eigenvalue: solve c*x = scale*c.
                             call stdlib${ii}$_slaqtr( .false., .true., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, dummy,&
                                        dumm, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          else
                             ! complex eigenvalue: solve
                             ! c*(p+iq) = scale*(c+id) in real arithmetic.
                             call stdlib${ii}$_slaqtr( .false., .false., n-1,work( 2_${ik}$, 2_${ik}$ ), ldwork,work( &
                                       1_${ik}$, n+1 ), mu, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          end if
                       end if
                       go to 50
                    end if
                 end if
                 sep( ks ) = scale / max( est, smlnum )
                 if( pair )sep( ks+1 ) = sep( ks )
              end if
              if( pair )ks = ks + 1_${ik}$
           end do loop_60
           return
     end subroutine stdlib${ii}$_strsna

     module subroutine stdlib${ii}$_dtrsna( job, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, s, sep, mm, m, &
     !! DTRSNA estimates reciprocal condition numbers for specified
     !! eigenvalues and/or right eigenvectors of a real upper
     !! quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q
     !! orthogonal).
     !! T must be in Schur canonical form (as returned by DHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               work, ldwork, iwork,info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, ldwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(out) :: s(*), sep(*), work(ldwork,*)
           real(dp), intent(in) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: pair, somcon, wantbh, wants, wantsp
           integer(${ik}$) :: i, ierr, ifst, ilst, j, k, kase, ks, n2, nn
           real(dp) :: bignum, cond, cs, delta, dumm, eps, est, lnrm, mu, prod, prod1, prod2, &
                     rnrm, scale, smlnum, sn
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           real(dp) :: dummy(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           somcon = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           if( .not.wants .and. .not.wantsp ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( howmny, 'A' ) .and. .not.somcon ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( wants .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( wants .and. ldvr<n ) ) then
              info = -10_${ik}$
           else
              ! set m to the number of eigenpairs for which condition numbers
              ! are required, and test mm.
              if( somcon ) then
                 m = 0_${ik}$
                 pair = .false.
                 do k = 1, n
                    if( pair ) then
                       pair = .false.
                    else
                       if( k<n ) then
                          if( t( k+1, k )==zero ) then
                             if( select( k ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( k ) .or. select( k+1 ) )m = m + 2_${ik}$
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -13_${ik}$
              else if( ldwork<1_${ik}$ .or. ( wantsp .and. ldwork<n ) ) then
                 info = -16_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTRSNA', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( n==1_${ik}$ ) then
              if( somcon ) then
                 if( .not.select( 1 ) )return
              end if
              if( wants )s( 1_${ik}$ ) = one
              if( wantsp )sep( 1_${ik}$ ) = abs( t( 1_${ik}$, 1_${ik}$ ) )
              return
           end if
           ! get machine constants
           eps = stdlib${ii}$_dlamch( 'P' )
           smlnum = stdlib${ii}$_dlamch( 'S' ) / eps
           bignum = one / smlnum
           call stdlib${ii}$_dlabad( smlnum, bignum )
           ks = 0_${ik}$
           pair = .false.
           loop_60: do k = 1, n
              ! determine whether t(k,k) begins a 1-by-1 or 2-by-2 block.
              if( pair ) then
                 pair = .false.
                 cycle loop_60
              else
                 if( k<n )pair = t( k+1, k )/=zero
              end if
              ! determine whether condition numbers are required for the k-th
              ! eigenpair.
              if( somcon ) then
                 if( pair ) then
                    if( .not.select( k ) .and. .not.select( k+1 ) )cycle loop_60
                 else
                    if( .not.select( k ) )cycle loop_60
                 end if
              end if
              ks = ks + 1_${ik}$
              if( wants ) then
                 ! compute the reciprocal condition number of the k-th
                 ! eigenvalue.
                 if( .not.pair ) then
                    ! real eigenvalue.
                    prod = stdlib${ii}$_ddot( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    rnrm = stdlib${ii}$_dnrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ )
                    lnrm = stdlib${ii}$_dnrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    s( ks ) = abs( prod ) / ( rnrm*lnrm )
                 else
                    ! complex eigenvalue.
                    prod1 = stdlib${ii}$_ddot( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    prod1 = prod1 + stdlib${ii}$_ddot( n, vr( 1_${ik}$, ks+1 ), 1_${ik}$, vl( 1_${ik}$, ks+1 ),1_${ik}$ )
                    prod2 = stdlib${ii}$_ddot( n, vl( 1_${ik}$, ks ), 1_${ik}$, vr( 1_${ik}$, ks+1 ), 1_${ik}$ )
                    prod2 = prod2 - stdlib${ii}$_ddot( n, vl( 1_${ik}$, ks+1 ), 1_${ik}$, vr( 1_${ik}$, ks ),1_${ik}$ )
                    rnrm = stdlib${ii}$_dlapy2( stdlib${ii}$_dnrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ ),stdlib${ii}$_dnrm2( n, vr( &
                              1_${ik}$, ks+1 ), 1_${ik}$ ) )
                    lnrm = stdlib${ii}$_dlapy2( stdlib${ii}$_dnrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ ),stdlib${ii}$_dnrm2( n, vl( &
                              1_${ik}$, ks+1 ), 1_${ik}$ ) )
                    cond = stdlib${ii}$_dlapy2( prod1, prod2 ) / ( rnrm*lnrm )
                    s( ks ) = cond
                    s( ks+1 ) = cond
                 end if
              end if
              if( wantsp ) then
                 ! estimate the reciprocal condition number of the k-th
                 ! eigenvector.
                 ! copy the matrix t to the array work and swap the diagonal
                 ! block beginning at t(k,k) to the (1,1) position.
                 call stdlib${ii}$_dlacpy( 'FULL', n, n, t, ldt, work, ldwork )
                 ifst = k
                 ilst = 1_${ik}$
                 call stdlib${ii}$_dtrexc( 'NO Q', n, work, ldwork, dummy, 1_${ik}$, ifst, ilst,work( 1_${ik}$, n+1 ),&
                            ierr )
                 if( ierr==1_${ik}$ .or. ierr==2_${ik}$ ) then
                    ! could not swap because blocks not well separated
                    scale = one
                    est = bignum
                 else
                    ! reordering successful
                    if( work( 2_${ik}$, 1_${ik}$ )==zero ) then
                       ! form c = t22 - lambda*i in work(2:n,2:n).
                       do i = 2, n
                          work( i, i ) = work( i, i ) - work( 1_${ik}$, 1_${ik}$ )
                       end do
                       n2 = 1_${ik}$
                       nn = n - 1_${ik}$
                    else
                       ! triangularize the 2 by 2 block by unitary
                       ! transformation u = [  cs   i*ss ]
                                          ! [ i*ss   cs  ].
                       ! such that the (1,1) position of work is complex
                       ! eigenvalue lambda with positive imaginary part. (2,2)
                       ! position of work is the complex eigenvalue lambda
                       ! with negative imaginary  part.
                       mu = sqrt( abs( work( 1_${ik}$, 2_${ik}$ ) ) )*sqrt( abs( work( 2_${ik}$, 1_${ik}$ ) ) )
                       delta = stdlib${ii}$_dlapy2( mu, work( 2_${ik}$, 1_${ik}$ ) )
                       cs = mu / delta
                       sn = -work( 2_${ik}$, 1_${ik}$ ) / delta
                       ! form
                       ! c**t = work(2:n,2:n) + i*[rwork(1) ..... rwork(n-1) ]
                                                ! [   mu                     ]
                                                ! [         ..               ]
                                                ! [             ..           ]
                                                ! [                  mu      ]
                       ! where c**t is transpose of matrix c,
                       ! and rwork is stored starting in the n+1-st column of
                       ! work.
                       do j = 3, n
                          work( 2_${ik}$, j ) = cs*work( 2_${ik}$, j )
                          work( j, j ) = work( j, j ) - work( 1_${ik}$, 1_${ik}$ )
                       end do
                       work( 2_${ik}$, 2_${ik}$ ) = zero
                       work( 1_${ik}$, n+1 ) = two*mu
                       do i = 2, n - 1
                          work( i, n+1 ) = sn*work( 1_${ik}$, i+1 )
                       end do
                       n2 = 2_${ik}$
                       nn = 2_${ik}$*( n-1 )
                    end if
                    ! estimate norm(inv(c**t))
                    est = zero
                    kase = 0_${ik}$
                    50 continue
                    call stdlib${ii}$_dlacn2( nn, work( 1_${ik}$, n+2 ), work( 1_${ik}$, n+4 ), iwork,est, kase, &
                              isave )
                    if( kase/=0_${ik}$ ) then
                       if( kase==1_${ik}$ ) then
                          if( n2==1_${ik}$ ) then
                             ! real eigenvalue: solve c**t*x = scale*c.
                             call stdlib${ii}$_dlaqtr( .true., .true., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, dummy, &
                                       dumm, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          else
                             ! complex eigenvalue: solve
                             ! c**t*(p+iq) = scale*(c+id) in real arithmetic.
                             call stdlib${ii}$_dlaqtr( .true., .false., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, work( &
                                       1_${ik}$, n+1 ), mu, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          end if
                       else
                          if( n2==1_${ik}$ ) then
                             ! real eigenvalue: solve c*x = scale*c.
                             call stdlib${ii}$_dlaqtr( .false., .true., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, dummy,&
                                        dumm, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          else
                             ! complex eigenvalue: solve
                             ! c*(p+iq) = scale*(c+id) in real arithmetic.
                             call stdlib${ii}$_dlaqtr( .false., .false., n-1,work( 2_${ik}$, 2_${ik}$ ), ldwork,work( &
                                       1_${ik}$, n+1 ), mu, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          end if
                       end if
                       go to 50
                    end if
                 end if
                 sep( ks ) = scale / max( est, smlnum )
                 if( pair )sep( ks+1 ) = sep( ks )
              end if
              if( pair )ks = ks + 1_${ik}$
           end do loop_60
           return
     end subroutine stdlib${ii}$_dtrsna

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$trsna( job, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, s, sep, mm, m, &
     !! DTRSNA: estimates reciprocal condition numbers for specified
     !! eigenvalues and/or right eigenvectors of a real upper
     !! quasi-triangular matrix T (or of any matrix Q*T*Q**T with Q
     !! orthogonal).
     !! T must be in Schur canonical form (as returned by DHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               work, ldwork, iwork,info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, ldwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(out) :: s(*), sep(*), work(ldwork,*)
           real(${rk}$), intent(in) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: pair, somcon, wantbh, wants, wantsp
           integer(${ik}$) :: i, ierr, ifst, ilst, j, k, kase, ks, n2, nn
           real(${rk}$) :: bignum, cond, cs, delta, dumm, eps, est, lnrm, mu, prod, prod1, prod2, &
                     rnrm, scale, smlnum, sn
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           real(${rk}$) :: dummy(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           somcon = stdlib_lsame( howmny, 'S' )
           info = 0_${ik}$
           if( .not.wants .and. .not.wantsp ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( howmny, 'A' ) .and. .not.somcon ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( wants .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( wants .and. ldvr<n ) ) then
              info = -10_${ik}$
           else
              ! set m to the number of eigenpairs for which condition numbers
              ! are required, and test mm.
              if( somcon ) then
                 m = 0_${ik}$
                 pair = .false.
                 do k = 1, n
                    if( pair ) then
                       pair = .false.
                    else
                       if( k<n ) then
                          if( t( k+1, k )==zero ) then
                             if( select( k ) )m = m + 1_${ik}$
                          else
                             pair = .true.
                             if( select( k ) .or. select( k+1 ) )m = m + 2_${ik}$
                          end if
                       else
                          if( select( n ) )m = m + 1_${ik}$
                       end if
                    end if
                 end do
              else
                 m = n
              end if
              if( mm<m ) then
                 info = -13_${ik}$
              else if( ldwork<1_${ik}$ .or. ( wantsp .and. ldwork<n ) ) then
                 info = -16_${ik}$
              end if
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTRSNA', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( n==1_${ik}$ ) then
              if( somcon ) then
                 if( .not.select( 1 ) )return
              end if
              if( wants )s( 1_${ik}$ ) = one
              if( wantsp )sep( 1_${ik}$ ) = abs( t( 1_${ik}$, 1_${ik}$ ) )
              return
           end if
           ! get machine constants
           eps = stdlib${ii}$_${ri}$lamch( 'P' )
           smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) / eps
           bignum = one / smlnum
           call stdlib${ii}$_${ri}$labad( smlnum, bignum )
           ks = 0_${ik}$
           pair = .false.
           loop_60: do k = 1, n
              ! determine whether t(k,k) begins a 1-by-1 or 2-by-2 block.
              if( pair ) then
                 pair = .false.
                 cycle loop_60
              else
                 if( k<n )pair = t( k+1, k )/=zero
              end if
              ! determine whether condition numbers are required for the k-th
              ! eigenpair.
              if( somcon ) then
                 if( pair ) then
                    if( .not.select( k ) .and. .not.select( k+1 ) )cycle loop_60
                 else
                    if( .not.select( k ) )cycle loop_60
                 end if
              end if
              ks = ks + 1_${ik}$
              if( wants ) then
                 ! compute the reciprocal condition number of the k-th
                 ! eigenvalue.
                 if( .not.pair ) then
                    ! real eigenvalue.
                    prod = stdlib${ii}$_${ri}$dot( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    rnrm = stdlib${ii}$_${ri}$nrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ )
                    lnrm = stdlib${ii}$_${ri}$nrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    s( ks ) = abs( prod ) / ( rnrm*lnrm )
                 else
                    ! complex eigenvalue.
                    prod1 = stdlib${ii}$_${ri}$dot( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                    prod1 = prod1 + stdlib${ii}$_${ri}$dot( n, vr( 1_${ik}$, ks+1 ), 1_${ik}$, vl( 1_${ik}$, ks+1 ),1_${ik}$ )
                    prod2 = stdlib${ii}$_${ri}$dot( n, vl( 1_${ik}$, ks ), 1_${ik}$, vr( 1_${ik}$, ks+1 ), 1_${ik}$ )
                    prod2 = prod2 - stdlib${ii}$_${ri}$dot( n, vl( 1_${ik}$, ks+1 ), 1_${ik}$, vr( 1_${ik}$, ks ),1_${ik}$ )
                    rnrm = stdlib${ii}$_${ri}$lapy2( stdlib${ii}$_${ri}$nrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ ),stdlib${ii}$_${ri}$nrm2( n, vr( &
                              1_${ik}$, ks+1 ), 1_${ik}$ ) )
                    lnrm = stdlib${ii}$_${ri}$lapy2( stdlib${ii}$_${ri}$nrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ ),stdlib${ii}$_${ri}$nrm2( n, vl( &
                              1_${ik}$, ks+1 ), 1_${ik}$ ) )
                    cond = stdlib${ii}$_${ri}$lapy2( prod1, prod2 ) / ( rnrm*lnrm )
                    s( ks ) = cond
                    s( ks+1 ) = cond
                 end if
              end if
              if( wantsp ) then
                 ! estimate the reciprocal condition number of the k-th
                 ! eigenvector.
                 ! copy the matrix t to the array work and swap the diagonal
                 ! block beginning at t(k,k) to the (1,1) position.
                 call stdlib${ii}$_${ri}$lacpy( 'FULL', n, n, t, ldt, work, ldwork )
                 ifst = k
                 ilst = 1_${ik}$
                 call stdlib${ii}$_${ri}$trexc( 'NO Q', n, work, ldwork, dummy, 1_${ik}$, ifst, ilst,work( 1_${ik}$, n+1 ),&
                            ierr )
                 if( ierr==1_${ik}$ .or. ierr==2_${ik}$ ) then
                    ! could not swap because blocks not well separated
                    scale = one
                    est = bignum
                 else
                    ! reordering successful
                    if( work( 2_${ik}$, 1_${ik}$ )==zero ) then
                       ! form c = t22 - lambda*i in work(2:n,2:n).
                       do i = 2, n
                          work( i, i ) = work( i, i ) - work( 1_${ik}$, 1_${ik}$ )
                       end do
                       n2 = 1_${ik}$
                       nn = n - 1_${ik}$
                    else
                       ! triangularize the 2 by 2 block by unitary
                       ! transformation u = [  cs   i*ss ]
                                          ! [ i*ss   cs  ].
                       ! such that the (1,1) position of work is complex
                       ! eigenvalue lambda with positive imaginary part. (2,2)
                       ! position of work is the complex eigenvalue lambda
                       ! with negative imaginary  part.
                       mu = sqrt( abs( work( 1_${ik}$, 2_${ik}$ ) ) )*sqrt( abs( work( 2_${ik}$, 1_${ik}$ ) ) )
                       delta = stdlib${ii}$_${ri}$lapy2( mu, work( 2_${ik}$, 1_${ik}$ ) )
                       cs = mu / delta
                       sn = -work( 2_${ik}$, 1_${ik}$ ) / delta
                       ! form
                       ! c**t = work(2:n,2:n) + i*[rwork(1) ..... rwork(n-1) ]
                                                ! [   mu                     ]
                                                ! [         ..               ]
                                                ! [             ..           ]
                                                ! [                  mu      ]
                       ! where c**t is transpose of matrix c,
                       ! and rwork is stored starting in the n+1-st column of
                       ! work.
                       do j = 3, n
                          work( 2_${ik}$, j ) = cs*work( 2_${ik}$, j )
                          work( j, j ) = work( j, j ) - work( 1_${ik}$, 1_${ik}$ )
                       end do
                       work( 2_${ik}$, 2_${ik}$ ) = zero
                       work( 1_${ik}$, n+1 ) = two*mu
                       do i = 2, n - 1
                          work( i, n+1 ) = sn*work( 1_${ik}$, i+1 )
                       end do
                       n2 = 2_${ik}$
                       nn = 2_${ik}$*( n-1 )
                    end if
                    ! estimate norm(inv(c**t))
                    est = zero
                    kase = 0_${ik}$
                    50 continue
                    call stdlib${ii}$_${ri}$lacn2( nn, work( 1_${ik}$, n+2 ), work( 1_${ik}$, n+4 ), iwork,est, kase, &
                              isave )
                    if( kase/=0_${ik}$ ) then
                       if( kase==1_${ik}$ ) then
                          if( n2==1_${ik}$ ) then
                             ! real eigenvalue: solve c**t*x = scale*c.
                             call stdlib${ii}$_${ri}$laqtr( .true., .true., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, dummy, &
                                       dumm, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          else
                             ! complex eigenvalue: solve
                             ! c**t*(p+iq) = scale*(c+id) in real arithmetic.
                             call stdlib${ii}$_${ri}$laqtr( .true., .false., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, work( &
                                       1_${ik}$, n+1 ), mu, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          end if
                       else
                          if( n2==1_${ik}$ ) then
                             ! real eigenvalue: solve c*x = scale*c.
                             call stdlib${ii}$_${ri}$laqtr( .false., .true., n-1, work( 2_${ik}$, 2_${ik}$ ),ldwork, dummy,&
                                        dumm, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          else
                             ! complex eigenvalue: solve
                             ! c*(p+iq) = scale*(c+id) in real arithmetic.
                             call stdlib${ii}$_${ri}$laqtr( .false., .false., n-1,work( 2_${ik}$, 2_${ik}$ ), ldwork,work( &
                                       1_${ik}$, n+1 ), mu, scale,work( 1_${ik}$, n+4 ), work( 1_${ik}$, n+6 ),ierr )
                          end if
                       end if
                       go to 50
                    end if
                 end if
                 sep( ks ) = scale / max( est, smlnum )
                 if( pair )sep( ks+1 ) = sep( ks )
              end if
              if( pair )ks = ks + 1_${ik}$
           end do loop_60
           return
     end subroutine stdlib${ii}$_${ri}$trsna

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_ctrsna( job, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, s, sep, mm,&
     !! CTRSNA estimates reciprocal condition numbers for specified
     !! eigenvalues and/or right eigenvectors of a complex upper triangular
     !! matrix T (or of any matrix Q*T*Q**H with Q unitary).
                m, work, ldwork, rwork,info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, ldwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(sp), intent(out) :: rwork(*), s(*), sep(*)
           complex(sp), intent(in) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(sp), intent(out) :: work(ldwork,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: somcon, wantbh, wants, wantsp
           character :: normin
           integer(${ik}$) :: i, ierr, ix, j, k, kase, ks
           real(sp) :: bignum, eps, est, lnrm, rnrm, scale, smlnum, xnorm
           complex(sp) :: cdum, prod
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           complex(sp) :: dummy(1_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=sp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           somcon = stdlib_lsame( howmny, 'S' )
           ! set m to the number of eigenpairs for which condition numbers are
           ! to be computed.
           if( somcon ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           if( .not.wants .and. .not.wantsp ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( howmny, 'A' ) .and. .not.somcon ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( wants .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( wants .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -13_${ik}$
           else if( ldwork<1_${ik}$ .or. ( wantsp .and. ldwork<n ) ) then
              info = -16_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CTRSNA', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( n==1_${ik}$ ) then
              if( somcon ) then
                 if( .not.select( 1 ) )return
              end if
              if( wants )s( 1_${ik}$ ) = one
              if( wantsp )sep( 1_${ik}$ ) = abs( t( 1_${ik}$, 1_${ik}$ ) )
              return
           end if
           ! get machine constants
           eps = stdlib${ii}$_slamch( 'P' )
           smlnum = stdlib${ii}$_slamch( 'S' ) / eps
           bignum = one / smlnum
           call stdlib${ii}$_slabad( smlnum, bignum )
           ks = 1_${ik}$
           loop_50: do k = 1, n
              if( somcon ) then
                 if( .not.select( k ) )cycle loop_50
              end if
              if( wants ) then
                 ! compute the reciprocal condition number of the k-th
                 ! eigenvalue.
                 prod = stdlib${ii}$_cdotc( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                 rnrm = stdlib${ii}$_scnrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ )
                 lnrm = stdlib${ii}$_scnrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ )
                 s( ks ) = abs( prod ) / ( rnrm*lnrm )
              end if
              if( wantsp ) then
                 ! estimate the reciprocal condition number of the k-th
                 ! eigenvector.
                 ! copy the matrix t to the array work and swap the k-th
                 ! diagonal element to the (1,1) position.
                 call stdlib${ii}$_clacpy( 'FULL', n, n, t, ldt, work, ldwork )
                 call stdlib${ii}$_ctrexc( 'NO Q', n, work, ldwork, dummy, 1_${ik}$, k, 1_${ik}$, ierr )
                 ! form  c = t22 - lambda*i in work(2:n,2:n).
                 do i = 2, n
                    work( i, i ) = work( i, i ) - work( 1_${ik}$, 1_${ik}$ )
                 end do
                 ! estimate a lower bound for the 1-norm of inv(c**h). the 1st
                 ! and (n+1)th columns of work are used to store work vectors.
                 sep( ks ) = zero
                 est = zero
                 kase = 0_${ik}$
                 normin = 'N'
                 30 continue
                 call stdlib${ii}$_clacn2( n-1, work( 1_${ik}$, n+1 ), work, est, kase, isave )
                 if( kase/=0_${ik}$ ) then
                    if( kase==1_${ik}$ ) then
                       ! solve c**h*x = scale*b
                       call stdlib${ii}$_clatrs( 'UPPER', 'CONJUGATE TRANSPOSE','NONUNIT', normin, n-1, &
                                 work( 2_${ik}$, 2_${ik}$ ),ldwork, work, scale, rwork, ierr )
                    else
                       ! solve c*x = scale*b
                       call stdlib${ii}$_clatrs( 'UPPER', 'NO TRANSPOSE', 'NONUNIT',normin, n-1, work( &
                                 2_${ik}$, 2_${ik}$ ), ldwork, work,scale, rwork, ierr )
                    end if
                    normin = 'Y'
                    if( scale/=one ) then
                       ! multiply by 1/scale if doing so will not cause
                       ! overflow.
                       ix = stdlib${ii}$_icamax( n-1, work, 1_${ik}$ )
                       xnorm = cabs1( work( ix, 1_${ik}$ ) )
                       if( scale<xnorm*smlnum .or. scale==zero )go to 40
                       call stdlib${ii}$_csrscl( n, scale, work, 1_${ik}$ )
                    end if
                    go to 30
                 end if
                 sep( ks ) = one / max( est, smlnum )
              end if
              40 continue
              ks = ks + 1_${ik}$
           end do loop_50
           return
     end subroutine stdlib${ii}$_ctrsna

     pure module subroutine stdlib${ii}$_ztrsna( job, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, s, sep, mm,&
     !! ZTRSNA estimates reciprocal condition numbers for specified
     !! eigenvalues and/or right eigenvectors of a complex upper triangular
     !! matrix T (or of any matrix Q*T*Q**H with Q unitary).
                m, work, ldwork, rwork,info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, ldwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(dp), intent(out) :: rwork(*), s(*), sep(*)
           complex(dp), intent(in) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(dp), intent(out) :: work(ldwork,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: somcon, wantbh, wants, wantsp
           character :: normin
           integer(${ik}$) :: i, ierr, ix, j, k, kase, ks
           real(dp) :: bignum, eps, est, lnrm, rnrm, scale, smlnum, xnorm
           complex(dp) :: cdum, prod
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           complex(dp) :: dummy(1_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=dp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           somcon = stdlib_lsame( howmny, 'S' )
           ! set m to the number of eigenpairs for which condition numbers are
           ! to be computed.
           if( somcon ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           if( .not.wants .and. .not.wantsp ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( howmny, 'A' ) .and. .not.somcon ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( wants .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( wants .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -13_${ik}$
           else if( ldwork<1_${ik}$ .or. ( wantsp .and. ldwork<n ) ) then
              info = -16_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTRSNA', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( n==1_${ik}$ ) then
              if( somcon ) then
                 if( .not.select( 1 ) )return
              end if
              if( wants )s( 1_${ik}$ ) = one
              if( wantsp )sep( 1_${ik}$ ) = abs( t( 1_${ik}$, 1_${ik}$ ) )
              return
           end if
           ! get machine constants
           eps = stdlib${ii}$_dlamch( 'P' )
           smlnum = stdlib${ii}$_dlamch( 'S' ) / eps
           bignum = one / smlnum
           call stdlib${ii}$_dlabad( smlnum, bignum )
           ks = 1_${ik}$
           loop_50: do k = 1, n
              if( somcon ) then
                 if( .not.select( k ) )cycle loop_50
              end if
              if( wants ) then
                 ! compute the reciprocal condition number of the k-th
                 ! eigenvalue.
                 prod = stdlib${ii}$_zdotc( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                 rnrm = stdlib${ii}$_dznrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ )
                 lnrm = stdlib${ii}$_dznrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ )
                 s( ks ) = abs( prod ) / ( rnrm*lnrm )
              end if
              if( wantsp ) then
                 ! estimate the reciprocal condition number of the k-th
                 ! eigenvector.
                 ! copy the matrix t to the array work and swap the k-th
                 ! diagonal element to the (1,1) position.
                 call stdlib${ii}$_zlacpy( 'FULL', n, n, t, ldt, work, ldwork )
                 call stdlib${ii}$_ztrexc( 'NO Q', n, work, ldwork, dummy, 1_${ik}$, k, 1_${ik}$, ierr )
                 ! form  c = t22 - lambda*i in work(2:n,2:n).
                 do i = 2, n
                    work( i, i ) = work( i, i ) - work( 1_${ik}$, 1_${ik}$ )
                 end do
                 ! estimate a lower bound for the 1-norm of inv(c**h). the 1st
                 ! and (n+1)th columns of work are used to store work vectors.
                 sep( ks ) = zero
                 est = zero
                 kase = 0_${ik}$
                 normin = 'N'
                 30 continue
                 call stdlib${ii}$_zlacn2( n-1, work( 1_${ik}$, n+1 ), work, est, kase, isave )
                 if( kase/=0_${ik}$ ) then
                    if( kase==1_${ik}$ ) then
                       ! solve c**h*x = scale*b
                       call stdlib${ii}$_zlatrs( 'UPPER', 'CONJUGATE TRANSPOSE','NONUNIT', normin, n-1, &
                                 work( 2_${ik}$, 2_${ik}$ ),ldwork, work, scale, rwork, ierr )
                    else
                       ! solve c*x = scale*b
                       call stdlib${ii}$_zlatrs( 'UPPER', 'NO TRANSPOSE', 'NONUNIT',normin, n-1, work( &
                                 2_${ik}$, 2_${ik}$ ), ldwork, work,scale, rwork, ierr )
                    end if
                    normin = 'Y'
                    if( scale/=one ) then
                       ! multiply by 1/scale if doing so will not cause
                       ! overflow.
                       ix = stdlib${ii}$_izamax( n-1, work, 1_${ik}$ )
                       xnorm = cabs1( work( ix, 1_${ik}$ ) )
                       if( scale<xnorm*smlnum .or. scale==zero )go to 40
                       call stdlib${ii}$_zdrscl( n, scale, work, 1_${ik}$ )
                    end if
                    go to 30
                 end if
                 sep( ks ) = one / max( est, smlnum )
              end if
              40 continue
              ks = ks + 1_${ik}$
           end do loop_50
           return
     end subroutine stdlib${ii}$_ztrsna

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$trsna( job, howmny, select, n, t, ldt, vl, ldvl, vr,ldvr, s, sep, mm,&
     !! ZTRSNA: estimates reciprocal condition numbers for specified
     !! eigenvalues and/or right eigenvectors of a complex upper triangular
     !! matrix T (or of any matrix Q*T*Q**H with Q unitary).
                m, work, ldwork, rwork,info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: howmny, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldt, ldvl, ldvr, ldwork, mm, n
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           real(${ck}$), intent(out) :: rwork(*), s(*), sep(*)
           complex(${ck}$), intent(in) :: t(ldt,*), vl(ldvl,*), vr(ldvr,*)
           complex(${ck}$), intent(out) :: work(ldwork,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: somcon, wantbh, wants, wantsp
           character :: normin
           integer(${ik}$) :: i, ierr, ix, j, k, kase, ks
           real(${ck}$) :: bignum, eps, est, lnrm, rnrm, scale, smlnum, xnorm
           complex(${ck}$) :: cdum, prod
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           complex(${ck}$) :: dummy(1_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=${ck}$) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           somcon = stdlib_lsame( howmny, 'S' )
           ! set m to the number of eigenpairs for which condition numbers are
           ! to be computed.
           if( somcon ) then
              m = 0_${ik}$
              do j = 1, n
                 if( select( j ) )m = m + 1_${ik}$
              end do
           else
              m = n
           end if
           info = 0_${ik}$
           if( .not.wants .and. .not.wantsp ) then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( howmny, 'A' ) .and. .not.somcon ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldvl<1_${ik}$ .or. ( wants .and. ldvl<n ) ) then
              info = -8_${ik}$
           else if( ldvr<1_${ik}$ .or. ( wants .and. ldvr<n ) ) then
              info = -10_${ik}$
           else if( mm<m ) then
              info = -13_${ik}$
           else if( ldwork<1_${ik}$ .or. ( wantsp .and. ldwork<n ) ) then
              info = -16_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTRSNA', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( n==1_${ik}$ ) then
              if( somcon ) then
                 if( .not.select( 1 ) )return
              end if
              if( wants )s( 1_${ik}$ ) = one
              if( wantsp )sep( 1_${ik}$ ) = abs( t( 1_${ik}$, 1_${ik}$ ) )
              return
           end if
           ! get machine constants
           eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'P' )
           smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) / eps
           bignum = one / smlnum
           call stdlib${ii}$_${c2ri(ci)}$labad( smlnum, bignum )
           ks = 1_${ik}$
           loop_50: do k = 1, n
              if( somcon ) then
                 if( .not.select( k ) )cycle loop_50
              end if
              if( wants ) then
                 ! compute the reciprocal condition number of the k-th
                 ! eigenvalue.
                 prod = stdlib${ii}$_${ci}$dotc( n, vr( 1_${ik}$, ks ), 1_${ik}$, vl( 1_${ik}$, ks ), 1_${ik}$ )
                 rnrm = stdlib${ii}$_${c2ri(ci)}$znrm2( n, vr( 1_${ik}$, ks ), 1_${ik}$ )
                 lnrm = stdlib${ii}$_${c2ri(ci)}$znrm2( n, vl( 1_${ik}$, ks ), 1_${ik}$ )
                 s( ks ) = abs( prod ) / ( rnrm*lnrm )
              end if
              if( wantsp ) then
                 ! estimate the reciprocal condition number of the k-th
                 ! eigenvector.
                 ! copy the matrix t to the array work and swap the k-th
                 ! diagonal element to the (1,1) position.
                 call stdlib${ii}$_${ci}$lacpy( 'FULL', n, n, t, ldt, work, ldwork )
                 call stdlib${ii}$_${ci}$trexc( 'NO Q', n, work, ldwork, dummy, 1_${ik}$, k, 1_${ik}$, ierr )
                 ! form  c = t22 - lambda*i in work(2:n,2:n).
                 do i = 2, n
                    work( i, i ) = work( i, i ) - work( 1_${ik}$, 1_${ik}$ )
                 end do
                 ! estimate a lower bound for the 1-norm of inv(c**h). the 1st
                 ! and (n+1)th columns of work are used to store work vectors.
                 sep( ks ) = zero
                 est = zero
                 kase = 0_${ik}$
                 normin = 'N'
                 30 continue
                 call stdlib${ii}$_${ci}$lacn2( n-1, work( 1_${ik}$, n+1 ), work, est, kase, isave )
                 if( kase/=0_${ik}$ ) then
                    if( kase==1_${ik}$ ) then
                       ! solve c**h*x = scale*b
                       call stdlib${ii}$_${ci}$latrs( 'UPPER', 'CONJUGATE TRANSPOSE','NONUNIT', normin, n-1, &
                                 work( 2_${ik}$, 2_${ik}$ ),ldwork, work, scale, rwork, ierr )
                    else
                       ! solve c*x = scale*b
                       call stdlib${ii}$_${ci}$latrs( 'UPPER', 'NO TRANSPOSE', 'NONUNIT',normin, n-1, work( &
                                 2_${ik}$, 2_${ik}$ ), ldwork, work,scale, rwork, ierr )
                    end if
                    normin = 'Y'
                    if( scale/=one ) then
                       ! multiply by 1/scale if doing so will not cause
                       ! overflow.
                       ix = stdlib${ii}$_i${ci}$amax( n-1, work, 1_${ik}$ )
                       xnorm = cabs1( work( ix, 1_${ik}$ ) )
                       if( scale<xnorm*smlnum .or. scale==zero )go to 40
                       call stdlib${ii}$_${ci}$drscl( n, scale, work, 1_${ik}$ )
                    end if
                    go to 30
                 end if
                 sep( ks ) = one / max( est, smlnum )
              end if
              40 continue
              ks = ks + 1_${ik}$
           end do loop_50
           return
     end subroutine stdlib${ii}$_${ci}$trsna

#:endif
#:endfor



     module subroutine stdlib${ii}$_strexc( compq, n, t, ldt, q, ldq, ifst, ilst, work,info )
     !! STREXC reorders the real Schur factorization of a real matrix
     !! A = Q*T*Q**T, so that the diagonal block of T with row index IFST is
     !! moved to row ILST.
     !! The real Schur form T is reordered by an orthogonal similarity
     !! transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors
     !! is updated by postmultiplying it with Z.
     !! T must be in Schur canonical form (as returned by SHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq
           integer(${ik}$), intent(inout) :: ifst, ilst
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldq, ldt, n
           ! Array Arguments 
           real(sp), intent(inout) :: q(ldq,*), t(ldt,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: wantq
           integer(${ik}$) :: here, nbf, nbl, nbnext
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input arguments.
           info = 0_${ik}$
           wantq = stdlib_lsame( compq, 'V' )
           if( .not.wantq .and. .not.stdlib_lsame( compq, 'N' ) ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<max( 1_${ik}$, n ) ) ) then
              info = -6_${ik}$
           else if(( ifst<1_${ik}$ .or. ifst>n ).and.( n>0_${ik}$ )) then
              info = -7_${ik}$
           else if(( ilst<1_${ik}$ .or. ilst>n ).and.( n>0_${ik}$ )) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'STREXC', -info )
              return
           end if
           ! quick return if possible
           if( n<=1 )return
           ! determine the first row of specified block
           ! and find out it is 1 by 1 or 2 by 2.
           if( ifst>1_${ik}$ ) then
              if( t( ifst, ifst-1 )/=zero )ifst = ifst - 1_${ik}$
           end if
           nbf = 1_${ik}$
           if( ifst<n ) then
              if( t( ifst+1, ifst )/=zero )nbf = 2_${ik}$
           end if
           ! determine the first row of the final block
           ! and find out it is 1 by 1 or 2 by 2.
           if( ilst>1_${ik}$ ) then
              if( t( ilst, ilst-1 )/=zero )ilst = ilst - 1_${ik}$
           end if
           nbl = 1_${ik}$
           if( ilst<n ) then
              if( t( ilst+1, ilst )/=zero )nbl = 2_${ik}$
           end if
           if( ifst==ilst )return
           if( ifst<ilst ) then
              ! update ilst
              if( nbf==2_${ik}$ .and. nbl==1_${ik}$ )ilst = ilst - 1_${ik}$
              if( nbf==1_${ik}$ .and. nbl==2_${ik}$ )ilst = ilst + 1_${ik}$
              here = ifst
              10 continue
              ! swap block with next one below
              if( nbf==1_${ik}$ .or. nbf==2_${ik}$ ) then
                 ! current block either 1 by 1 or 2 by 2
                 nbnext = 1_${ik}$
                 if( here+nbf+1<=n ) then
                    if( t( here+nbf+1, here+nbf )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here, nbf, nbnext,work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 here = here + nbnext
                 ! test if 2 by 2 block breaks into two 1 by 1 blocks
                 if( nbf==2_${ik}$ ) then
                    if( t( here+1, here )==zero )nbf = 3_${ik}$
                 end if
              else
                 ! current block consists of two 1 by 1 blocks each of which
                 ! must be swapped individually
                 nbnext = 1_${ik}$
                 if( here+3<=n ) then
                    if( t( here+3, here+2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here+1, 1_${ik}$, nbnext,work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 if( nbnext==1_${ik}$ ) then
                    ! swap two 1 by 1 blocks, no problems possible
                    call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, nbnext,work, info )
                              
                    here = here + 1_${ik}$
                 else
                    ! recompute nbnext in case 2 by 2 split
                    if( t( here+2, here+1 )==zero )nbnext = 1_${ik}$
                    if( nbnext==2_${ik}$ ) then
                       ! 2 by 2 block did not split
                       call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$,nbnext, work, info )
                                 
                       if( info/=0_${ik}$ ) then
                          ilst = here
                          return
                       end if
                       here = here + 2_${ik}$
                    else
                       ! 2 by 2 block did split
                       call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here+1, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       here = here + 2_${ik}$
                    end if
                 end if
              end if
              if( here<ilst )go to 10
           else
              here = ifst
              20 continue
              ! swap block with next one above
              if( nbf==1_${ik}$ .or. nbf==2_${ik}$ ) then
                 ! current block either 1 by 1 or 2 by 2
                 nbnext = 1_${ik}$
                 if( here>=3_${ik}$ ) then
                    if( t( here-1, here-2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here-nbnext, nbnext,nbf, work, &
                           info )
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 here = here - nbnext
                 ! test if 2 by 2 block breaks into two 1 by 1 blocks
                 if( nbf==2_${ik}$ ) then
                    if( t( here+1, here )==zero )nbf = 3_${ik}$
                 end if
              else
                 ! current block consists of two 1 by 1 blocks each of which
                 ! must be swapped individually
                 nbnext = 1_${ik}$
                 if( here>=3_${ik}$ ) then
                    if( t( here-1, here-2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here-nbnext, nbnext,1_${ik}$, work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 if( nbnext==1_${ik}$ ) then
                    ! swap two 1 by 1 blocks, no problems possible
                    call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here, nbnext, 1_${ik}$,work, info )
                              
                    here = here - 1_${ik}$
                 else
                    ! recompute nbnext in case 2 by 2 split
                    if( t( here, here-1 )==zero )nbnext = 1_${ik}$
                    if( nbnext==2_${ik}$ ) then
                       ! 2 by 2 block did not split
                       call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here-1, 2_${ik}$, 1_${ik}$,work, info )
                                 
                       if( info/=0_${ik}$ ) then
                          ilst = here
                          return
                       end if
                       here = here - 2_${ik}$
                    else
                       ! 2 by 2 block did split
                       call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       call stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, here-1, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       here = here - 2_${ik}$
                    end if
                 end if
              end if
              if( here>ilst )go to 20
           end if
           ilst = here
           return
     end subroutine stdlib${ii}$_strexc

     module subroutine stdlib${ii}$_dtrexc( compq, n, t, ldt, q, ldq, ifst, ilst, work,info )
     !! DTREXC reorders the real Schur factorization of a real matrix
     !! A = Q*T*Q**T, so that the diagonal block of T with row index IFST is
     !! moved to row ILST.
     !! The real Schur form T is reordered by an orthogonal similarity
     !! transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors
     !! is updated by postmultiplying it with Z.
     !! T must be in Schur canonical form (as returned by DHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq
           integer(${ik}$), intent(inout) :: ifst, ilst
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldq, ldt, n
           ! Array Arguments 
           real(dp), intent(inout) :: q(ldq,*), t(ldt,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: wantq
           integer(${ik}$) :: here, nbf, nbl, nbnext
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input arguments.
           info = 0_${ik}$
           wantq = stdlib_lsame( compq, 'V' )
           if( .not.wantq .and. .not.stdlib_lsame( compq, 'N' ) ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<max( 1_${ik}$, n ) ) ) then
              info = -6_${ik}$
           else if(( ifst<1_${ik}$ .or. ifst>n ).and.( n>0_${ik}$ )) then
              info = -7_${ik}$
           else if(( ilst<1_${ik}$ .or. ilst>n ).and.( n>0_${ik}$ )) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTREXC', -info )
              return
           end if
           ! quick return if possible
           if( n<=1 )return
           ! determine the first row of specified block
           ! and find out it is 1 by 1 or 2 by 2.
           if( ifst>1_${ik}$ ) then
              if( t( ifst, ifst-1 )/=zero )ifst = ifst - 1_${ik}$
           end if
           nbf = 1_${ik}$
           if( ifst<n ) then
              if( t( ifst+1, ifst )/=zero )nbf = 2_${ik}$
           end if
           ! determine the first row of the final block
           ! and find out it is 1 by 1 or 2 by 2.
           if( ilst>1_${ik}$ ) then
              if( t( ilst, ilst-1 )/=zero )ilst = ilst - 1_${ik}$
           end if
           nbl = 1_${ik}$
           if( ilst<n ) then
              if( t( ilst+1, ilst )/=zero )nbl = 2_${ik}$
           end if
           if( ifst==ilst )return
           if( ifst<ilst ) then
              ! update ilst
              if( nbf==2_${ik}$ .and. nbl==1_${ik}$ )ilst = ilst - 1_${ik}$
              if( nbf==1_${ik}$ .and. nbl==2_${ik}$ )ilst = ilst + 1_${ik}$
              here = ifst
              10 continue
              ! swap block with next one below
              if( nbf==1_${ik}$ .or. nbf==2_${ik}$ ) then
                 ! current block either 1 by 1 or 2 by 2
                 nbnext = 1_${ik}$
                 if( here+nbf+1<=n ) then
                    if( t( here+nbf+1, here+nbf )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here, nbf, nbnext,work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 here = here + nbnext
                 ! test if 2 by 2 block breaks into two 1 by 1 blocks
                 if( nbf==2_${ik}$ ) then
                    if( t( here+1, here )==zero )nbf = 3_${ik}$
                 end if
              else
                 ! current block consists of two 1 by 1 blocks each of which
                 ! must be swapped individually
                 nbnext = 1_${ik}$
                 if( here+3<=n ) then
                    if( t( here+3, here+2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here+1, 1_${ik}$, nbnext,work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 if( nbnext==1_${ik}$ ) then
                    ! swap two 1 by 1 blocks, no problems possible
                    call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, nbnext,work, info )
                              
                    here = here + 1_${ik}$
                 else
                    ! recompute nbnext in case 2 by 2 split
                    if( t( here+2, here+1 )==zero )nbnext = 1_${ik}$
                    if( nbnext==2_${ik}$ ) then
                       ! 2 by 2 block did not split
                       call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$,nbnext, work, info )
                                 
                       if( info/=0_${ik}$ ) then
                          ilst = here
                          return
                       end if
                       here = here + 2_${ik}$
                    else
                       ! 2 by 2 block did split
                       call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here+1, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       here = here + 2_${ik}$
                    end if
                 end if
              end if
              if( here<ilst )go to 10
           else
              here = ifst
              20 continue
              ! swap block with next one above
              if( nbf==1_${ik}$ .or. nbf==2_${ik}$ ) then
                 ! current block either 1 by 1 or 2 by 2
                 nbnext = 1_${ik}$
                 if( here>=3_${ik}$ ) then
                    if( t( here-1, here-2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here-nbnext, nbnext,nbf, work, &
                           info )
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 here = here - nbnext
                 ! test if 2 by 2 block breaks into two 1 by 1 blocks
                 if( nbf==2_${ik}$ ) then
                    if( t( here+1, here )==zero )nbf = 3_${ik}$
                 end if
              else
                 ! current block consists of two 1 by 1 blocks each of which
                 ! must be swapped individually
                 nbnext = 1_${ik}$
                 if( here>=3_${ik}$ ) then
                    if( t( here-1, here-2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here-nbnext, nbnext,1_${ik}$, work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 if( nbnext==1_${ik}$ ) then
                    ! swap two 1 by 1 blocks, no problems possible
                    call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here, nbnext, 1_${ik}$,work, info )
                              
                    here = here - 1_${ik}$
                 else
                    ! recompute nbnext in case 2 by 2 split
                    if( t( here, here-1 )==zero )nbnext = 1_${ik}$
                    if( nbnext==2_${ik}$ ) then
                       ! 2 by 2 block did not split
                       call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here-1, 2_${ik}$, 1_${ik}$,work, info )
                                 
                       if( info/=0_${ik}$ ) then
                          ilst = here
                          return
                       end if
                       here = here - 2_${ik}$
                    else
                       ! 2 by 2 block did split
                       call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       call stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, here-1, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       here = here - 2_${ik}$
                    end if
                 end if
              end if
              if( here>ilst )go to 20
           end if
           ilst = here
           return
     end subroutine stdlib${ii}$_dtrexc

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$trexc( compq, n, t, ldt, q, ldq, ifst, ilst, work,info )
     !! DTREXC: reorders the real Schur factorization of a real matrix
     !! A = Q*T*Q**T, so that the diagonal block of T with row index IFST is
     !! moved to row ILST.
     !! The real Schur form T is reordered by an orthogonal similarity
     !! transformation Z**T*T*Z, and optionally the matrix Q of Schur vectors
     !! is updated by postmultiplying it with Z.
     !! T must be in Schur canonical form (as returned by DHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq
           integer(${ik}$), intent(inout) :: ifst, ilst
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldq, ldt, n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: q(ldq,*), t(ldt,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: wantq
           integer(${ik}$) :: here, nbf, nbl, nbnext
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input arguments.
           info = 0_${ik}$
           wantq = stdlib_lsame( compq, 'V' )
           if( .not.wantq .and. .not.stdlib_lsame( compq, 'N' ) ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<max( 1_${ik}$, n ) ) ) then
              info = -6_${ik}$
           else if(( ifst<1_${ik}$ .or. ifst>n ).and.( n>0_${ik}$ )) then
              info = -7_${ik}$
           else if(( ilst<1_${ik}$ .or. ilst>n ).and.( n>0_${ik}$ )) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTREXC', -info )
              return
           end if
           ! quick return if possible
           if( n<=1 )return
           ! determine the first row of specified block
           ! and find out it is 1 by 1 or 2 by 2.
           if( ifst>1_${ik}$ ) then
              if( t( ifst, ifst-1 )/=zero )ifst = ifst - 1_${ik}$
           end if
           nbf = 1_${ik}$
           if( ifst<n ) then
              if( t( ifst+1, ifst )/=zero )nbf = 2_${ik}$
           end if
           ! determine the first row of the final block
           ! and find out it is 1 by 1 or 2 by 2.
           if( ilst>1_${ik}$ ) then
              if( t( ilst, ilst-1 )/=zero )ilst = ilst - 1_${ik}$
           end if
           nbl = 1_${ik}$
           if( ilst<n ) then
              if( t( ilst+1, ilst )/=zero )nbl = 2_${ik}$
           end if
           if( ifst==ilst )return
           if( ifst<ilst ) then
              ! update ilst
              if( nbf==2_${ik}$ .and. nbl==1_${ik}$ )ilst = ilst - 1_${ik}$
              if( nbf==1_${ik}$ .and. nbl==2_${ik}$ )ilst = ilst + 1_${ik}$
              here = ifst
              10 continue
              ! swap block with next one below
              if( nbf==1_${ik}$ .or. nbf==2_${ik}$ ) then
                 ! current block either 1 by 1 or 2 by 2
                 nbnext = 1_${ik}$
                 if( here+nbf+1<=n ) then
                    if( t( here+nbf+1, here+nbf )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here, nbf, nbnext,work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 here = here + nbnext
                 ! test if 2 by 2 block breaks into two 1 by 1 blocks
                 if( nbf==2_${ik}$ ) then
                    if( t( here+1, here )==zero )nbf = 3_${ik}$
                 end if
              else
                 ! current block consists of two 1 by 1 blocks each of which
                 ! must be swapped individually
                 nbnext = 1_${ik}$
                 if( here+3<=n ) then
                    if( t( here+3, here+2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here+1, 1_${ik}$, nbnext,work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 if( nbnext==1_${ik}$ ) then
                    ! swap two 1 by 1 blocks, no problems possible
                    call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, nbnext,work, info )
                              
                    here = here + 1_${ik}$
                 else
                    ! recompute nbnext in case 2 by 2 split
                    if( t( here+2, here+1 )==zero )nbnext = 1_${ik}$
                    if( nbnext==2_${ik}$ ) then
                       ! 2 by 2 block did not split
                       call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$,nbnext, work, info )
                                 
                       if( info/=0_${ik}$ ) then
                          ilst = here
                          return
                       end if
                       here = here + 2_${ik}$
                    else
                       ! 2 by 2 block did split
                       call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here+1, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       here = here + 2_${ik}$
                    end if
                 end if
              end if
              if( here<ilst )go to 10
           else
              here = ifst
              20 continue
              ! swap block with next one above
              if( nbf==1_${ik}$ .or. nbf==2_${ik}$ ) then
                 ! current block either 1 by 1 or 2 by 2
                 nbnext = 1_${ik}$
                 if( here>=3_${ik}$ ) then
                    if( t( here-1, here-2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here-nbnext, nbnext,nbf, work, &
                           info )
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 here = here - nbnext
                 ! test if 2 by 2 block breaks into two 1 by 1 blocks
                 if( nbf==2_${ik}$ ) then
                    if( t( here+1, here )==zero )nbf = 3_${ik}$
                 end if
              else
                 ! current block consists of two 1 by 1 blocks each of which
                 ! must be swapped individually
                 nbnext = 1_${ik}$
                 if( here>=3_${ik}$ ) then
                    if( t( here-1, here-2 )/=zero )nbnext = 2_${ik}$
                 end if
                 call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here-nbnext, nbnext,1_${ik}$, work, info )
                           
                 if( info/=0_${ik}$ ) then
                    ilst = here
                    return
                 end if
                 if( nbnext==1_${ik}$ ) then
                    ! swap two 1 by 1 blocks, no problems possible
                    call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here, nbnext, 1_${ik}$,work, info )
                              
                    here = here - 1_${ik}$
                 else
                    ! recompute nbnext in case 2 by 2 split
                    if( t( here, here-1 )==zero )nbnext = 1_${ik}$
                    if( nbnext==2_${ik}$ ) then
                       ! 2 by 2 block did not split
                       call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here-1, 2_${ik}$, 1_${ik}$,work, info )
                                 
                       if( info/=0_${ik}$ ) then
                          ilst = here
                          return
                       end if
                       here = here - 2_${ik}$
                    else
                       ! 2 by 2 block did split
                       call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       call stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, here-1, 1_${ik}$, 1_${ik}$,work, info )
                                 
                       here = here - 2_${ik}$
                    end if
                 end if
              end if
              if( here>ilst )go to 20
           end if
           ilst = here
           return
     end subroutine stdlib${ii}$_${ri}$trexc

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_ctrexc( compq, n, t, ldt, q, ldq, ifst, ilst, info )
     !! CTREXC reorders the Schur factorization of a complex matrix
     !! A = Q*T*Q**H, so that the diagonal element of T with row index IFST
     !! is moved to row ILST.
     !! The Schur form T is reordered by a unitary similarity transformation
     !! Z**H*T*Z, and optionally the matrix Q of Schur vectors is updated by
     !! postmultplying it with Z.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq
           integer(${ik}$), intent(in) :: ifst, ilst, ldq, ldt, n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           complex(sp), intent(inout) :: q(ldq,*), t(ldt,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: wantq
           integer(${ik}$) :: k, m1, m2, m3
           real(sp) :: cs
           complex(sp) :: sn, t11, t22, temp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           info = 0_${ik}$
           wantq = stdlib_lsame( compq, 'V' )
           if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<max( 1_${ik}$, n ) ) ) then
              info = -6_${ik}$
           else if(( ifst<1_${ik}$ .or. ifst>n ).and.( n>0_${ik}$ )) then
              info = -7_${ik}$
           else if(( ilst<1_${ik}$ .or. ilst>n ).and.( n>0_${ik}$ )) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CTREXC', -info )
              return
           end if
           ! quick return if possible
           if( n<=1 .or. ifst==ilst )return
           if( ifst<ilst ) then
              ! move the ifst-th diagonal element forward down the diagonal.
              m1 = 0_${ik}$
              m2 = -1_${ik}$
              m3 = 1_${ik}$
           else
              ! move the ifst-th diagonal element backward up the diagonal.
              m1 = -1_${ik}$
              m2 = 0_${ik}$
              m3 = -1_${ik}$
           end if
           do k = ifst + m1, ilst + m2, m3
              ! interchange the k-th and (k+1)-th diagonal elements.
              t11 = t( k, k )
              t22 = t( k+1, k+1 )
              ! determine the transformation to perform the interchange.
              call stdlib${ii}$_clartg( t( k, k+1 ), t22-t11, cs, sn, temp )
              ! apply transformation to the matrix t.
              if( k+2<=n )call stdlib${ii}$_crot( n-k-1, t( k, k+2 ), ldt, t( k+1, k+2 ), ldt, cs,sn )
                        
              call stdlib${ii}$_crot( k-1, t( 1_${ik}$, k ), 1_${ik}$, t( 1_${ik}$, k+1 ), 1_${ik}$, cs, conjg( sn ) )
              t( k, k ) = t22
              t( k+1, k+1 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_crot( n, q( 1_${ik}$, k ), 1_${ik}$, q( 1_${ik}$, k+1 ), 1_${ik}$, cs,conjg( sn ) )
              end if
           end do
           return
     end subroutine stdlib${ii}$_ctrexc

     pure module subroutine stdlib${ii}$_ztrexc( compq, n, t, ldt, q, ldq, ifst, ilst, info )
     !! ZTREXC reorders the Schur factorization of a complex matrix
     !! A = Q*T*Q**H, so that the diagonal element of T with row index IFST
     !! is moved to row ILST.
     !! The Schur form T is reordered by a unitary similarity transformation
     !! Z**H*T*Z, and optionally the matrix Q of Schur vectors is updated by
     !! postmultplying it with Z.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq
           integer(${ik}$), intent(in) :: ifst, ilst, ldq, ldt, n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           complex(dp), intent(inout) :: q(ldq,*), t(ldt,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: wantq
           integer(${ik}$) :: k, m1, m2, m3
           real(dp) :: cs
           complex(dp) :: sn, t11, t22, temp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           info = 0_${ik}$
           wantq = stdlib_lsame( compq, 'V' )
           if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<max( 1_${ik}$, n ) ) ) then
              info = -6_${ik}$
           else if(( ifst<1_${ik}$ .or. ifst>n ).and.( n>0_${ik}$ )) then
              info = -7_${ik}$
           else if(( ilst<1_${ik}$ .or. ilst>n ).and.( n>0_${ik}$ )) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTREXC', -info )
              return
           end if
           ! quick return if possible
           if( n<=1 .or. ifst==ilst )return
           if( ifst<ilst ) then
              ! move the ifst-th diagonal element forward down the diagonal.
              m1 = 0_${ik}$
              m2 = -1_${ik}$
              m3 = 1_${ik}$
           else
              ! move the ifst-th diagonal element backward up the diagonal.
              m1 = -1_${ik}$
              m2 = 0_${ik}$
              m3 = -1_${ik}$
           end if
           do k = ifst + m1, ilst + m2, m3
              ! interchange the k-th and (k+1)-th diagonal elements.
              t11 = t( k, k )
              t22 = t( k+1, k+1 )
              ! determine the transformation to perform the interchange.
              call stdlib${ii}$_zlartg( t( k, k+1 ), t22-t11, cs, sn, temp )
              ! apply transformation to the matrix t.
              if( k+2<=n )call stdlib${ii}$_zrot( n-k-1, t( k, k+2 ), ldt, t( k+1, k+2 ), ldt, cs,sn )
                        
              call stdlib${ii}$_zrot( k-1, t( 1_${ik}$, k ), 1_${ik}$, t( 1_${ik}$, k+1 ), 1_${ik}$, cs,conjg( sn ) )
              t( k, k ) = t22
              t( k+1, k+1 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_zrot( n, q( 1_${ik}$, k ), 1_${ik}$, q( 1_${ik}$, k+1 ), 1_${ik}$, cs,conjg( sn ) )
              end if
           end do
           return
     end subroutine stdlib${ii}$_ztrexc

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$trexc( compq, n, t, ldt, q, ldq, ifst, ilst, info )
     !! ZTREXC: reorders the Schur factorization of a complex matrix
     !! A = Q*T*Q**H, so that the diagonal element of T with row index IFST
     !! is moved to row ILST.
     !! The Schur form T is reordered by a unitary similarity transformation
     !! Z**H*T*Z, and optionally the matrix Q of Schur vectors is updated by
     !! postmultplying it with Z.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq
           integer(${ik}$), intent(in) :: ifst, ilst, ldq, ldt, n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: q(ldq,*), t(ldt,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: wantq
           integer(${ik}$) :: k, m1, m2, m3
           real(${ck}$) :: cs
           complex(${ck}$) :: sn, t11, t22, temp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           info = 0_${ik}$
           wantq = stdlib_lsame( compq, 'V' )
           if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -4_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<max( 1_${ik}$, n ) ) ) then
              info = -6_${ik}$
           else if(( ifst<1_${ik}$ .or. ifst>n ).and.( n>0_${ik}$ )) then
              info = -7_${ik}$
           else if(( ilst<1_${ik}$ .or. ilst>n ).and.( n>0_${ik}$ )) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTREXC', -info )
              return
           end if
           ! quick return if possible
           if( n<=1 .or. ifst==ilst )return
           if( ifst<ilst ) then
              ! move the ifst-th diagonal element forward down the diagonal.
              m1 = 0_${ik}$
              m2 = -1_${ik}$
              m3 = 1_${ik}$
           else
              ! move the ifst-th diagonal element backward up the diagonal.
              m1 = -1_${ik}$
              m2 = 0_${ik}$
              m3 = -1_${ik}$
           end if
           do k = ifst + m1, ilst + m2, m3
              ! interchange the k-th and (k+1)-th diagonal elements.
              t11 = t( k, k )
              t22 = t( k+1, k+1 )
              ! determine the transformation to perform the interchange.
              call stdlib${ii}$_${ci}$lartg( t( k, k+1 ), t22-t11, cs, sn, temp )
              ! apply transformation to the matrix t.
              if( k+2<=n )call stdlib${ii}$_${ci}$rot( n-k-1, t( k, k+2 ), ldt, t( k+1, k+2 ), ldt, cs,sn )
                        
              call stdlib${ii}$_${ci}$rot( k-1, t( 1_${ik}$, k ), 1_${ik}$, t( 1_${ik}$, k+1 ), 1_${ik}$, cs,conjg( sn ) )
              t( k, k ) = t22
              t( k+1, k+1 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_${ci}$rot( n, q( 1_${ik}$, k ), 1_${ik}$, q( 1_${ik}$, k+1 ), 1_${ik}$, cs,conjg( sn ) )
              end if
           end do
           return
     end subroutine stdlib${ii}$_${ci}$trexc

#:endif
#:endfor



     module subroutine stdlib${ii}$_strsen( job, compq, select, n, t, ldt, q, ldq, wr, wi,m, s, sep, work, &
     !! STRSEN reorders the real Schur factorization of a real matrix
     !! A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in
     !! the leading diagonal blocks of the upper quasi-triangular matrix T,
     !! and the leading columns of Q form an orthonormal basis of the
     !! corresponding right invariant subspace.
     !! Optionally the routine computes the reciprocal condition numbers of
     !! the cluster of eigenvalues and/or the invariant subspace.
     !! T must be in Schur canonical form (as returned by SHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               lwork, iwork, liwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldq, ldt, liwork, lwork, n
           real(sp), intent(out) :: s, sep
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(inout) :: q(ldq,*), t(ldt,*)
           real(sp), intent(out) :: wi(*), work(*), wr(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery, pair, swap, wantbh, wantq, wants, wantsp
           integer(${ik}$) :: ierr, k, kase, kk, ks, liwmin, lwmin, n1, n2, nn
           real(sp) :: est, rnorm, scale
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           wantq = stdlib_lsame( compq, 'V' )
           info = 0_${ik}$
           lquery = ( lwork==-1_${ik}$ )
           if( .not.stdlib_lsame( job, 'N' ) .and. .not.wants .and. .not.wantsp )then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<n ) ) then
              info = -8_${ik}$
           else
              ! set m to the dimension of the specified invariant subspace,
              ! and test lwork and liwork.
              m = 0_${ik}$
              pair = .false.
              do k = 1, n
                 if( pair ) then
                    pair = .false.
                 else
                    if( k<n ) then
                       if( t( k+1, k )==zero ) then
                          if( select( k ) )m = m + 1_${ik}$
                       else
                          pair = .true.
                          if( select( k ) .or. select( k+1 ) )m = m + 2_${ik}$
                       end if
                    else
                       if( select( n ) )m = m + 1_${ik}$
                    end if
                 end if
              end do
              n1 = m
              n2 = n - m
              nn = n1*n2
              if(  wantsp ) then
                 lwmin = max( 1_${ik}$, 2_${ik}$*nn )
                 liwmin = max( 1_${ik}$, nn )
              else if( stdlib_lsame( job, 'N' ) ) then
                 lwmin = max( 1_${ik}$, n )
                 liwmin = 1_${ik}$
              else if( stdlib_lsame( job, 'E' ) ) then
                 lwmin = max( 1_${ik}$, nn )
                 liwmin = 1_${ik}$
              end if
              if( lwork<lwmin .and. .not.lquery ) then
                 info = -15_${ik}$
              else if( liwork<liwmin .and. .not.lquery ) then
                 info = -17_${ik}$
              end if
           end if
           if( info==0_${ik}$ ) then
              work( 1_${ik}$ ) = lwmin
              iwork( 1_${ik}$ ) = liwmin
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'STRSEN', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( m==n .or. m==0_${ik}$ ) then
              if( wants )s = one
              if( wantsp )sep = stdlib${ii}$_slange( '1', n, n, t, ldt, work )
              go to 40
           end if
           ! collect the selected blocks at the top-left corner of t.
           ks = 0_${ik}$
           pair = .false.
           loop_20: do k = 1, n
              if( pair ) then
                 pair = .false.
              else
                 swap = select( k )
                 if( k<n ) then
                    if( t( k+1, k )/=zero ) then
                       pair = .true.
                       swap = swap .or. select( k+1 )
                    end if
                 end if
                 if( swap ) then
                    ks = ks + 1_${ik}$
                    ! swap the k-th block to position ks.
                    ierr = 0_${ik}$
                    kk = k
                    if( k/=ks )call stdlib${ii}$_strexc( compq, n, t, ldt, q, ldq, kk, ks, work,ierr )
                              
                    if( ierr==1_${ik}$ .or. ierr==2_${ik}$ ) then
                       ! blocks too close to swap: exit.
                       info = 1_${ik}$
                       if( wants )s = zero
                       if( wantsp )sep = zero
                       go to 40
                    end if
                    if( pair )ks = ks + 1_${ik}$
                 end if
              end if
           end do loop_20
           if( wants ) then
              ! solve sylvester equation for r:
                 ! t11*r - r*t22 = scale*t12
              call stdlib${ii}$_slacpy( 'F', n1, n2, t( 1_${ik}$, n1+1 ), ldt, work, n1 )
              call stdlib${ii}$_strsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt, t( n1+1, n1+1 ),ldt, work, n1, &
                        scale, ierr )
              ! estimate the reciprocal of the condition number of the cluster
              ! of eigenvalues.
              rnorm = stdlib${ii}$_slange( 'F', n1, n2, work, n1, work )
              if( rnorm==zero ) then
                 s = one
              else
                 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*sqrt( rnorm ) )
              end if
           end if
           if( wantsp ) then
              ! estimate sep(t11,t22).
              est = zero
              kase = 0_${ik}$
              30 continue
              call stdlib${ii}$_slacn2( nn, work( nn+1 ), work, iwork, est, kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! solve  t11*r - r*t22 = scale*x.
                    call stdlib${ii}$_strsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 else
                    ! solve t11**t*r - r*t22**t = scale*x.
                    call stdlib${ii}$_strsyl( 'T', 'T', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 end if
                 go to 30
              end if
              sep = scale / est
           end if
           40 continue
           ! store the output eigenvalues in wr and wi.
           do k = 1, n
              wr( k ) = t( k, k )
              wi( k ) = zero
           end do
           do k = 1, n - 1
              if( t( k+1, k )/=zero ) then
                 wi( k ) = sqrt( abs( t( k, k+1 ) ) )*sqrt( abs( t( k+1, k ) ) )
                 wi( k+1 ) = -wi( k )
              end if
           end do
           work( 1_${ik}$ ) = lwmin
           iwork( 1_${ik}$ ) = liwmin
           return
     end subroutine stdlib${ii}$_strsen

     module subroutine stdlib${ii}$_dtrsen( job, compq, select, n, t, ldt, q, ldq, wr, wi,m, s, sep, work, &
     !! DTRSEN reorders the real Schur factorization of a real matrix
     !! A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in
     !! the leading diagonal blocks of the upper quasi-triangular matrix T,
     !! and the leading columns of Q form an orthonormal basis of the
     !! corresponding right invariant subspace.
     !! Optionally the routine computes the reciprocal condition numbers of
     !! the cluster of eigenvalues and/or the invariant subspace.
     !! T must be in Schur canonical form (as returned by DHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               lwork, iwork, liwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldq, ldt, liwork, lwork, n
           real(dp), intent(out) :: s, sep
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(inout) :: q(ldq,*), t(ldt,*)
           real(dp), intent(out) :: wi(*), work(*), wr(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery, pair, swap, wantbh, wantq, wants, wantsp
           integer(${ik}$) :: ierr, k, kase, kk, ks, liwmin, lwmin, n1, n2, nn
           real(dp) :: est, rnorm, scale
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           wantq = stdlib_lsame( compq, 'V' )
           info = 0_${ik}$
           lquery = ( lwork==-1_${ik}$ )
           if( .not.stdlib_lsame( job, 'N' ) .and. .not.wants .and. .not.wantsp )then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<n ) ) then
              info = -8_${ik}$
           else
              ! set m to the dimension of the specified invariant subspace,
              ! and test lwork and liwork.
              m = 0_${ik}$
              pair = .false.
              do k = 1, n
                 if( pair ) then
                    pair = .false.
                 else
                    if( k<n ) then
                       if( t( k+1, k )==zero ) then
                          if( select( k ) )m = m + 1_${ik}$
                       else
                          pair = .true.
                          if( select( k ) .or. select( k+1 ) )m = m + 2_${ik}$
                       end if
                    else
                       if( select( n ) )m = m + 1_${ik}$
                    end if
                 end if
              end do
              n1 = m
              n2 = n - m
              nn = n1*n2
              if( wantsp ) then
                 lwmin = max( 1_${ik}$, 2_${ik}$*nn )
                 liwmin = max( 1_${ik}$, nn )
              else if( stdlib_lsame( job, 'N' ) ) then
                 lwmin = max( 1_${ik}$, n )
                 liwmin = 1_${ik}$
              else if( stdlib_lsame( job, 'E' ) ) then
                 lwmin = max( 1_${ik}$, nn )
                 liwmin = 1_${ik}$
              end if
              if( lwork<lwmin .and. .not.lquery ) then
                 info = -15_${ik}$
              else if( liwork<liwmin .and. .not.lquery ) then
                 info = -17_${ik}$
              end if
           end if
           if( info==0_${ik}$ ) then
              work( 1_${ik}$ ) = lwmin
              iwork( 1_${ik}$ ) = liwmin
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTRSEN', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( m==n .or. m==0_${ik}$ ) then
              if( wants )s = one
              if( wantsp )sep = stdlib${ii}$_dlange( '1', n, n, t, ldt, work )
              go to 40
           end if
           ! collect the selected blocks at the top-left corner of t.
           ks = 0_${ik}$
           pair = .false.
           loop_20: do k = 1, n
              if( pair ) then
                 pair = .false.
              else
                 swap = select( k )
                 if( k<n ) then
                    if( t( k+1, k )/=zero ) then
                       pair = .true.
                       swap = swap .or. select( k+1 )
                    end if
                 end if
                 if( swap ) then
                    ks = ks + 1_${ik}$
                    ! swap the k-th block to position ks.
                    ierr = 0_${ik}$
                    kk = k
                    if( k/=ks )call stdlib${ii}$_dtrexc( compq, n, t, ldt, q, ldq, kk, ks, work,ierr )
                              
                    if( ierr==1_${ik}$ .or. ierr==2_${ik}$ ) then
                       ! blocks too close to swap: exit.
                       info = 1_${ik}$
                       if( wants )s = zero
                       if( wantsp )sep = zero
                       go to 40
                    end if
                    if( pair )ks = ks + 1_${ik}$
                 end if
              end if
           end do loop_20
           if( wants ) then
              ! solve sylvester equation for r:
                 ! t11*r - r*t22 = scale*t12
              call stdlib${ii}$_dlacpy( 'F', n1, n2, t( 1_${ik}$, n1+1 ), ldt, work, n1 )
              call stdlib${ii}$_dtrsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt, t( n1+1, n1+1 ),ldt, work, n1, &
                        scale, ierr )
              ! estimate the reciprocal of the condition number of the cluster
              ! of eigenvalues.
              rnorm = stdlib${ii}$_dlange( 'F', n1, n2, work, n1, work )
              if( rnorm==zero ) then
                 s = one
              else
                 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*sqrt( rnorm ) )
              end if
           end if
           if( wantsp ) then
              ! estimate sep(t11,t22).
              est = zero
              kase = 0_${ik}$
              30 continue
              call stdlib${ii}$_dlacn2( nn, work( nn+1 ), work, iwork, est, kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! solve  t11*r - r*t22 = scale*x.
                    call stdlib${ii}$_dtrsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 else
                    ! solve t11**t*r - r*t22**t = scale*x.
                    call stdlib${ii}$_dtrsyl( 'T', 'T', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 end if
                 go to 30
              end if
              sep = scale / est
           end if
           40 continue
           ! store the output eigenvalues in wr and wi.
           do k = 1, n
              wr( k ) = t( k, k )
              wi( k ) = zero
           end do
           do k = 1, n - 1
              if( t( k+1, k )/=zero ) then
                 wi( k ) = sqrt( abs( t( k, k+1 ) ) )*sqrt( abs( t( k+1, k ) ) )
                 wi( k+1 ) = -wi( k )
              end if
           end do
           work( 1_${ik}$ ) = lwmin
           iwork( 1_${ik}$ ) = liwmin
           return
     end subroutine stdlib${ii}$_dtrsen

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$trsen( job, compq, select, n, t, ldt, q, ldq, wr, wi,m, s, sep, work, &
     !! DTRSEN: reorders the real Schur factorization of a real matrix
     !! A = Q*T*Q**T, so that a selected cluster of eigenvalues appears in
     !! the leading diagonal blocks of the upper quasi-triangular matrix T,
     !! and the leading columns of Q form an orthonormal basis of the
     !! corresponding right invariant subspace.
     !! Optionally the routine computes the reciprocal condition numbers of
     !! the cluster of eigenvalues and/or the invariant subspace.
     !! T must be in Schur canonical form (as returned by DHSEQR), that is,
     !! block upper triangular with 1-by-1 and 2-by-2 diagonal blocks; each
     !! 2-by-2 diagonal block has its diagonal elements equal and its
     !! off-diagonal elements of opposite sign.
               lwork, iwork, liwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldq, ldt, liwork, lwork, n
           real(${rk}$), intent(out) :: s, sep
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(inout) :: q(ldq,*), t(ldt,*)
           real(${rk}$), intent(out) :: wi(*), work(*), wr(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery, pair, swap, wantbh, wantq, wants, wantsp
           integer(${ik}$) :: ierr, k, kase, kk, ks, liwmin, lwmin, n1, n2, nn
           real(${rk}$) :: est, rnorm, scale
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           wantq = stdlib_lsame( compq, 'V' )
           info = 0_${ik}$
           lquery = ( lwork==-1_${ik}$ )
           if( .not.stdlib_lsame( job, 'N' ) .and. .not.wants .and. .not.wantsp )then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<n ) ) then
              info = -8_${ik}$
           else
              ! set m to the dimension of the specified invariant subspace,
              ! and test lwork and liwork.
              m = 0_${ik}$
              pair = .false.
              do k = 1, n
                 if( pair ) then
                    pair = .false.
                 else
                    if( k<n ) then
                       if( t( k+1, k )==zero ) then
                          if( select( k ) )m = m + 1_${ik}$
                       else
                          pair = .true.
                          if( select( k ) .or. select( k+1 ) )m = m + 2_${ik}$
                       end if
                    else
                       if( select( n ) )m = m + 1_${ik}$
                    end if
                 end if
              end do
              n1 = m
              n2 = n - m
              nn = n1*n2
              if( wantsp ) then
                 lwmin = max( 1_${ik}$, 2_${ik}$*nn )
                 liwmin = max( 1_${ik}$, nn )
              else if( stdlib_lsame( job, 'N' ) ) then
                 lwmin = max( 1_${ik}$, n )
                 liwmin = 1_${ik}$
              else if( stdlib_lsame( job, 'E' ) ) then
                 lwmin = max( 1_${ik}$, nn )
                 liwmin = 1_${ik}$
              end if
              if( lwork<lwmin .and. .not.lquery ) then
                 info = -15_${ik}$
              else if( liwork<liwmin .and. .not.lquery ) then
                 info = -17_${ik}$
              end if
           end if
           if( info==0_${ik}$ ) then
              work( 1_${ik}$ ) = lwmin
              iwork( 1_${ik}$ ) = liwmin
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DTRSEN', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible.
           if( m==n .or. m==0_${ik}$ ) then
              if( wants )s = one
              if( wantsp )sep = stdlib${ii}$_${ri}$lange( '1', n, n, t, ldt, work )
              go to 40
           end if
           ! collect the selected blocks at the top-left corner of t.
           ks = 0_${ik}$
           pair = .false.
           loop_20: do k = 1, n
              if( pair ) then
                 pair = .false.
              else
                 swap = select( k )
                 if( k<n ) then
                    if( t( k+1, k )/=zero ) then
                       pair = .true.
                       swap = swap .or. select( k+1 )
                    end if
                 end if
                 if( swap ) then
                    ks = ks + 1_${ik}$
                    ! swap the k-th block to position ks.
                    ierr = 0_${ik}$
                    kk = k
                    if( k/=ks )call stdlib${ii}$_${ri}$trexc( compq, n, t, ldt, q, ldq, kk, ks, work,ierr )
                              
                    if( ierr==1_${ik}$ .or. ierr==2_${ik}$ ) then
                       ! blocks too close to swap: exit.
                       info = 1_${ik}$
                       if( wants )s = zero
                       if( wantsp )sep = zero
                       go to 40
                    end if
                    if( pair )ks = ks + 1_${ik}$
                 end if
              end if
           end do loop_20
           if( wants ) then
              ! solve sylvester equation for r:
                 ! t11*r - r*t22 = scale*t12
              call stdlib${ii}$_${ri}$lacpy( 'F', n1, n2, t( 1_${ik}$, n1+1 ), ldt, work, n1 )
              call stdlib${ii}$_${ri}$trsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt, t( n1+1, n1+1 ),ldt, work, n1, &
                        scale, ierr )
              ! estimate the reciprocal of the condition number of the cluster
              ! of eigenvalues.
              rnorm = stdlib${ii}$_${ri}$lange( 'F', n1, n2, work, n1, work )
              if( rnorm==zero ) then
                 s = one
              else
                 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*sqrt( rnorm ) )
              end if
           end if
           if( wantsp ) then
              ! estimate sep(t11,t22).
              est = zero
              kase = 0_${ik}$
              30 continue
              call stdlib${ii}$_${ri}$lacn2( nn, work( nn+1 ), work, iwork, est, kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! solve  t11*r - r*t22 = scale*x.
                    call stdlib${ii}$_${ri}$trsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 else
                    ! solve t11**t*r - r*t22**t = scale*x.
                    call stdlib${ii}$_${ri}$trsyl( 'T', 'T', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 end if
                 go to 30
              end if
              sep = scale / est
           end if
           40 continue
           ! store the output eigenvalues in wr and wi.
           do k = 1, n
              wr( k ) = t( k, k )
              wi( k ) = zero
           end do
           do k = 1, n - 1
              if( t( k+1, k )/=zero ) then
                 wi( k ) = sqrt( abs( t( k, k+1 ) ) )*sqrt( abs( t( k+1, k ) ) )
                 wi( k+1 ) = -wi( k )
              end if
           end do
           work( 1_${ik}$ ) = lwmin
           iwork( 1_${ik}$ ) = liwmin
           return
     end subroutine stdlib${ii}$_${ri}$trsen

#:endif
#:endfor

     module subroutine stdlib${ii}$_ctrsen( job, compq, select, n, t, ldt, q, ldq, w, m, s,sep, work, lwork, &
     !! CTRSEN reorders the Schur factorization of a complex matrix
     !! A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in
     !! the leading positions on the diagonal of the upper triangular matrix
     !! T, and the leading columns of Q form an orthonormal basis of the
     !! corresponding right invariant subspace.
     !! Optionally the routine computes the reciprocal condition numbers of
     !! the cluster of eigenvalues and/or the invariant subspace.
               info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldq, ldt, lwork, n
           real(sp), intent(out) :: s, sep
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           complex(sp), intent(inout) :: q(ldq,*), t(ldt,*)
           complex(sp), intent(out) :: w(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery, wantbh, wantq, wants, wantsp
           integer(${ik}$) :: ierr, k, kase, ks, lwmin, n1, n2, nn
           real(sp) :: est, rnorm, scale
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           real(sp) :: rwork(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           wantq = stdlib_lsame( compq, 'V' )
           ! set m to the number of selected eigenvalues.
           m = 0_${ik}$
           do k = 1, n
              if( select( k ) )m = m + 1_${ik}$
           end do
           n1 = m
           n2 = n - m
           nn = n1*n2
           info = 0_${ik}$
           lquery = ( lwork==-1_${ik}$ )
           if( wantsp ) then
              lwmin = max( 1_${ik}$, 2_${ik}$*nn )
           else if( stdlib_lsame( job, 'N' ) ) then
              lwmin = 1_${ik}$
           else if( stdlib_lsame( job, 'E' ) ) then
              lwmin = max( 1_${ik}$, nn )
           end if
           if( .not.stdlib_lsame( job, 'N' ) .and. .not.wants .and. .not.wantsp )then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<n ) ) then
              info = -8_${ik}$
           else if( lwork<lwmin .and. .not.lquery ) then
              info = -14_${ik}$
           end if
           if( info==0_${ik}$ ) then
              work( 1_${ik}$ ) = lwmin
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CTRSEN', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible
           if( m==n .or. m==0_${ik}$ ) then
              if( wants )s = one
              if( wantsp )sep = stdlib${ii}$_clange( '1', n, n, t, ldt, rwork )
              go to 40
           end if
           ! collect the selected eigenvalues at the top left corner of t.
           ks = 0_${ik}$
           do k = 1, n
              if( select( k ) ) then
                 ks = ks + 1_${ik}$
                 ! swap the k-th eigenvalue to position ks.
                 if( k/=ks )call stdlib${ii}$_ctrexc( compq, n, t, ldt, q, ldq, k, ks, ierr )
              end if
           end do
           if( wants ) then
              ! solve the sylvester equation for r:
                 ! t11*r - r*t22 = scale*t12
              call stdlib${ii}$_clacpy( 'F', n1, n2, t( 1_${ik}$, n1+1 ), ldt, work, n1 )
              call stdlib${ii}$_ctrsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt, t( n1+1, n1+1 ),ldt, work, n1, &
                        scale, ierr )
              ! estimate the reciprocal of the condition number of the cluster
              ! of eigenvalues.
              rnorm = stdlib${ii}$_clange( 'F', n1, n2, work, n1, rwork )
              if( rnorm==zero ) then
                 s = one
              else
                 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*sqrt( rnorm ) )
              end if
           end if
           if( wantsp ) then
              ! estimate sep(t11,t22).
              est = zero
              kase = 0_${ik}$
              30 continue
              call stdlib${ii}$_clacn2( nn, work( nn+1 ), work, est, kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! solve t11*r - r*t22 = scale*x.
                    call stdlib${ii}$_ctrsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 else
                    ! solve t11**h*r - r*t22**h = scale*x.
                    call stdlib${ii}$_ctrsyl( 'C', 'C', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 end if
                 go to 30
              end if
              sep = scale / est
           end if
           40 continue
           ! copy reordered eigenvalues to w.
           do k = 1, n
              w( k ) = t( k, k )
           end do
           work( 1_${ik}$ ) = lwmin
           return
     end subroutine stdlib${ii}$_ctrsen

     module subroutine stdlib${ii}$_ztrsen( job, compq, select, n, t, ldt, q, ldq, w, m, s,sep, work, lwork, &
     !! ZTRSEN reorders the Schur factorization of a complex matrix
     !! A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in
     !! the leading positions on the diagonal of the upper triangular matrix
     !! T, and the leading columns of Q form an orthonormal basis of the
     !! corresponding right invariant subspace.
     !! Optionally the routine computes the reciprocal condition numbers of
     !! the cluster of eigenvalues and/or the invariant subspace.
               info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldq, ldt, lwork, n
           real(dp), intent(out) :: s, sep
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           complex(dp), intent(inout) :: q(ldq,*), t(ldt,*)
           complex(dp), intent(out) :: w(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery, wantbh, wantq, wants, wantsp
           integer(${ik}$) :: ierr, k, kase, ks, lwmin, n1, n2, nn
           real(dp) :: est, rnorm, scale
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           real(dp) :: rwork(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           wantq = stdlib_lsame( compq, 'V' )
           ! set m to the number of selected eigenvalues.
           m = 0_${ik}$
           do k = 1, n
              if( select( k ) )m = m + 1_${ik}$
           end do
           n1 = m
           n2 = n - m
           nn = n1*n2
           info = 0_${ik}$
           lquery = ( lwork==-1_${ik}$ )
           if( wantsp ) then
              lwmin = max( 1_${ik}$, 2_${ik}$*nn )
           else if( stdlib_lsame( job, 'N' ) ) then
              lwmin = 1_${ik}$
           else if( stdlib_lsame( job, 'E' ) ) then
              lwmin = max( 1_${ik}$, nn )
           end if
           if( .not.stdlib_lsame( job, 'N' ) .and. .not.wants .and. .not.wantsp )then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<n ) ) then
              info = -8_${ik}$
           else if( lwork<lwmin .and. .not.lquery ) then
              info = -14_${ik}$
           end if
           if( info==0_${ik}$ ) then
              work( 1_${ik}$ ) = lwmin
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTRSEN', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible
           if( m==n .or. m==0_${ik}$ ) then
              if( wants )s = one
              if( wantsp )sep = stdlib${ii}$_zlange( '1', n, n, t, ldt, rwork )
              go to 40
           end if
           ! collect the selected eigenvalues at the top left corner of t.
           ks = 0_${ik}$
           do k = 1, n
              if( select( k ) ) then
                 ks = ks + 1_${ik}$
                 ! swap the k-th eigenvalue to position ks.
                 if( k/=ks )call stdlib${ii}$_ztrexc( compq, n, t, ldt, q, ldq, k, ks, ierr )
              end if
           end do
           if( wants ) then
              ! solve the sylvester equation for r:
                 ! t11*r - r*t22 = scale*t12
              call stdlib${ii}$_zlacpy( 'F', n1, n2, t( 1_${ik}$, n1+1 ), ldt, work, n1 )
              call stdlib${ii}$_ztrsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt, t( n1+1, n1+1 ),ldt, work, n1, &
                        scale, ierr )
              ! estimate the reciprocal of the condition number of the cluster
              ! of eigenvalues.
              rnorm = stdlib${ii}$_zlange( 'F', n1, n2, work, n1, rwork )
              if( rnorm==zero ) then
                 s = one
              else
                 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*sqrt( rnorm ) )
              end if
           end if
           if( wantsp ) then
              ! estimate sep(t11,t22).
              est = zero
              kase = 0_${ik}$
              30 continue
              call stdlib${ii}$_zlacn2( nn, work( nn+1 ), work, est, kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! solve t11*r - r*t22 = scale*x.
                    call stdlib${ii}$_ztrsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 else
                    ! solve t11**h*r - r*t22**h = scale*x.
                    call stdlib${ii}$_ztrsyl( 'C', 'C', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 end if
                 go to 30
              end if
              sep = scale / est
           end if
           40 continue
           ! copy reordered eigenvalues to w.
           do k = 1, n
              w( k ) = t( k, k )
           end do
           work( 1_${ik}$ ) = lwmin
           return
     end subroutine stdlib${ii}$_ztrsen

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     module subroutine stdlib${ii}$_${ci}$trsen( job, compq, select, n, t, ldt, q, ldq, w, m, s,sep, work, lwork, &
     !! ZTRSEN: reorders the Schur factorization of a complex matrix
     !! A = Q*T*Q**H, so that a selected cluster of eigenvalues appears in
     !! the leading positions on the diagonal of the upper triangular matrix
     !! T, and the leading columns of Q form an orthonormal basis of the
     !! corresponding right invariant subspace.
     !! Optionally the routine computes the reciprocal condition numbers of
     !! the cluster of eigenvalues and/or the invariant subspace.
               info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: compq, job
           integer(${ik}$), intent(out) :: info, m
           integer(${ik}$), intent(in) :: ldq, ldt, lwork, n
           real(${ck}$), intent(out) :: s, sep
           ! Array Arguments 
           logical(lk), intent(in) :: select(*)
           complex(${ck}$), intent(inout) :: q(ldq,*), t(ldt,*)
           complex(${ck}$), intent(out) :: w(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery, wantbh, wantq, wants, wantsp
           integer(${ik}$) :: ierr, k, kase, ks, lwmin, n1, n2, nn
           real(${ck}$) :: est, rnorm, scale
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           real(${ck}$) :: rwork(1_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! decode and test the input parameters.
           wantbh = stdlib_lsame( job, 'B' )
           wants = stdlib_lsame( job, 'E' ) .or. wantbh
           wantsp = stdlib_lsame( job, 'V' ) .or. wantbh
           wantq = stdlib_lsame( compq, 'V' )
           ! set m to the number of selected eigenvalues.
           m = 0_${ik}$
           do k = 1, n
              if( select( k ) )m = m + 1_${ik}$
           end do
           n1 = m
           n2 = n - m
           nn = n1*n2
           info = 0_${ik}$
           lquery = ( lwork==-1_${ik}$ )
           if( wantsp ) then
              lwmin = max( 1_${ik}$, 2_${ik}$*nn )
           else if( stdlib_lsame( job, 'N' ) ) then
              lwmin = 1_${ik}$
           else if( stdlib_lsame( job, 'E' ) ) then
              lwmin = max( 1_${ik}$, nn )
           end if
           if( .not.stdlib_lsame( job, 'N' ) .and. .not.wants .and. .not.wantsp )then
              info = -1_${ik}$
           else if( .not.stdlib_lsame( compq, 'N' ) .and. .not.wantq ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldt<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           else if( ldq<1_${ik}$ .or. ( wantq .and. ldq<n ) ) then
              info = -8_${ik}$
           else if( lwork<lwmin .and. .not.lquery ) then
              info = -14_${ik}$
           end if
           if( info==0_${ik}$ ) then
              work( 1_${ik}$ ) = lwmin
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZTRSEN', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible
           if( m==n .or. m==0_${ik}$ ) then
              if( wants )s = one
              if( wantsp )sep = stdlib${ii}$_${ci}$lange( '1', n, n, t, ldt, rwork )
              go to 40
           end if
           ! collect the selected eigenvalues at the top left corner of t.
           ks = 0_${ik}$
           do k = 1, n
              if( select( k ) ) then
                 ks = ks + 1_${ik}$
                 ! swap the k-th eigenvalue to position ks.
                 if( k/=ks )call stdlib${ii}$_${ci}$trexc( compq, n, t, ldt, q, ldq, k, ks, ierr )
              end if
           end do
           if( wants ) then
              ! solve the sylvester equation for r:
                 ! t11*r - r*t22 = scale*t12
              call stdlib${ii}$_${ci}$lacpy( 'F', n1, n2, t( 1_${ik}$, n1+1 ), ldt, work, n1 )
              call stdlib${ii}$_${ci}$trsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt, t( n1+1, n1+1 ),ldt, work, n1, &
                        scale, ierr )
              ! estimate the reciprocal of the condition number of the cluster
              ! of eigenvalues.
              rnorm = stdlib${ii}$_${ci}$lange( 'F', n1, n2, work, n1, rwork )
              if( rnorm==zero ) then
                 s = one
              else
                 s = scale / ( sqrt( scale*scale / rnorm+rnorm )*sqrt( rnorm ) )
              end if
           end if
           if( wantsp ) then
              ! estimate sep(t11,t22).
              est = zero
              kase = 0_${ik}$
              30 continue
              call stdlib${ii}$_${ci}$lacn2( nn, work( nn+1 ), work, est, kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! solve t11*r - r*t22 = scale*x.
                    call stdlib${ii}$_${ci}$trsyl( 'N', 'N', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 else
                    ! solve t11**h*r - r*t22**h = scale*x.
                    call stdlib${ii}$_${ci}$trsyl( 'C', 'C', -1_${ik}$, n1, n2, t, ldt,t( n1+1, n1+1 ), ldt, work, &
                              n1, scale,ierr )
                 end if
                 go to 30
              end if
              sep = scale / est
           end if
           40 continue
           ! copy reordered eigenvalues to w.
           do k = 1, n
              w( k ) = t( k, k )
           end do
           work( 1_${ik}$ ) = lwmin
           return
     end subroutine stdlib${ii}$_${ci}$trsen

#:endif
#:endfor



     module subroutine stdlib${ii}$_slaexc( wantq, n, t, ldt, q, ldq, j1, n1, n2, work,info )
     !! SLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in
     !! an upper quasi-triangular matrix T by an orthogonal similarity
     !! transformation.
     !! T must be in Schur canonical form, that is, block upper triangular
     !! with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block
     !! has its diagonal elements equal and its off-diagonal elements of
     !! opposite sign.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: wantq
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: j1, ldq, ldt, n, n1, n2
           ! Array Arguments 
           real(sp), intent(inout) :: q(ldq,*), t(ldt,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ldd = 4_${ik}$
           integer(${ik}$), parameter :: ldx = 2_${ik}$
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: ierr, j2, j3, j4, k, nd
           real(sp) :: cs, dnorm, eps, scale, smlnum, sn, t11, t22, t33, tau, tau1, tau2, temp, &
                     thresh, wi1, wi2, wr1, wr2, xnorm
           ! Local Arrays 
           real(sp) :: d(ldd,4_${ik}$), u(3_${ik}$), u1(3_${ik}$), u2(3_${ik}$), x(ldx,2_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           info = 0_${ik}$
           ! quick return if possible
           if( n==0 .or. n1==0 .or. n2==0 )return
           if( j1+n1>n )return
           j2 = j1 + 1_${ik}$
           j3 = j1 + 2_${ik}$
           j4 = j1 + 3_${ik}$
           if( n1==1_${ik}$ .and. n2==1_${ik}$ ) then
              ! swap two 1-by-1 blocks.
              t11 = t( j1, j1 )
              t22 = t( j2, j2 )
              ! determine the transformation to perform the interchange.
              call stdlib${ii}$_slartg( t( j1, j2 ), t22-t11, cs, sn, temp )
              ! apply transformation to the matrix t.
              if( j3<=n )call stdlib${ii}$_srot( n-j1-1, t( j1, j3 ), ldt, t( j2, j3 ), ldt, cs,sn )
                        
              call stdlib${ii}$_srot( j1-1, t( 1_${ik}$, j1 ), 1_${ik}$, t( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              t( j1, j1 ) = t22
              t( j2, j2 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_srot( n, q( 1_${ik}$, j1 ), 1_${ik}$, q( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              end if
           else
              ! swapping involves at least one 2-by-2 block.
              ! copy the diagonal block of order n1+n2 to the local array d
              ! and compute its norm.
              nd = n1 + n2
              call stdlib${ii}$_slacpy( 'FULL', nd, nd, t( j1, j1 ), ldt, d, ldd )
              dnorm = stdlib${ii}$_slange( 'MAX', nd, nd, d, ldd, work )
              ! compute machine-dependent threshold for test for accepting
              ! swap.
              eps = stdlib${ii}$_slamch( 'P' )
              smlnum = stdlib${ii}$_slamch( 'S' ) / eps
              thresh = max( ten*eps*dnorm, smlnum )
              ! solve t11*x - x*t22 = scale*t12 for x.
              call stdlib${ii}$_slasy2( .false., .false., -1_${ik}$, n1, n2, d, ldd,d( n1+1, n1+1 ), ldd, d( 1_${ik}$,&
                         n1+1 ), ldd, scale, x,ldx, xnorm, ierr )
              ! swap the adjacent diagonal blocks.
              k = n1 + n1 + n2 - 3_${ik}$
              go to ( 10, 20, 30 )k
              10 continue
              ! n1 = 1, n2 = 2: generate elementary reflector h so that:
              ! ( scale, x11, x12 ) h = ( 0, 0, * )
              u( 1_${ik}$ ) = scale
              u( 2_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )
              u( 3_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )
              call stdlib${ii}$_slarfg( 3_${ik}$, u( 3_${ik}$ ), u, 1_${ik}$, tau )
              u( 3_${ik}$ ) = one
              t11 = t( j1, j1 )
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              call stdlib${ii}$_slarfx( 'R', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 3, 1 ) ), abs( d( 3, 2 ) ), abs( d( 3,3 )-t11 ) )>thresh )go to 50

              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, n-j1+1, u, tau, t( j1, j1 ), ldt, work )
              call stdlib${ii}$_slarfx( 'R', j2, 3_${ik}$, u, tau, t( 1_${ik}$, j1 ), ldt, work )
              t( j3, j1 ) = zero
              t( j3, j2 ) = zero
              t( j3, j3 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_slarfx( 'R', n, 3_${ik}$, u, tau, q( 1_${ik}$, j1 ), ldq, work )
              end if
              go to 40
              20 continue
              ! n1 = 2, n2 = 1: generate elementary reflector h so that:
              ! h (  -x11 ) = ( * )
                ! (  -x21 ) = ( 0 )
                ! ( scale ) = ( 0 )
              u( 1_${ik}$ ) = -x( 1_${ik}$, 1_${ik}$ )
              u( 2_${ik}$ ) = -x( 2_${ik}$, 1_${ik}$ )
              u( 3_${ik}$ ) = scale
              call stdlib${ii}$_slarfg( 3_${ik}$, u( 1_${ik}$ ), u( 2_${ik}$ ), 1_${ik}$, tau )
              u( 1_${ik}$ ) = one
              t33 = t( j3, j3 )
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              call stdlib${ii}$_slarfx( 'R', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 2, 1 ) ), abs( d( 3, 1 ) ), abs( d( 1,1 )-t33 ) )>thresh )go to 50

              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_slarfx( 'R', j3, 3_${ik}$, u, tau, t( 1_${ik}$, j1 ), ldt, work )
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, n-j1, u, tau, t( j1, j2 ), ldt, work )
              t( j1, j1 ) = t33
              t( j2, j1 ) = zero
              t( j3, j1 ) = zero
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_slarfx( 'R', n, 3_${ik}$, u, tau, q( 1_${ik}$, j1 ), ldq, work )
              end if
              go to 40
              30 continue
              ! n1 = 2, n2 = 2: generate elementary reflectors h(1) and h(2) so
              ! that:
              ! h(2) h(1) (  -x11  -x12 ) = (  *  * )
                        ! (  -x21  -x22 )   (  0  * )
                        ! ( scale    0  )   (  0  0 )
                        ! (    0  scale )   (  0  0 )
              u1( 1_${ik}$ ) = -x( 1_${ik}$, 1_${ik}$ )
              u1( 2_${ik}$ ) = -x( 2_${ik}$, 1_${ik}$ )
              u1( 3_${ik}$ ) = scale
              call stdlib${ii}$_slarfg( 3_${ik}$, u1( 1_${ik}$ ), u1( 2_${ik}$ ), 1_${ik}$, tau1 )
              u1( 1_${ik}$ ) = one
              temp = -tau1*( x( 1_${ik}$, 2_${ik}$ )+u1( 2_${ik}$ )*x( 2_${ik}$, 2_${ik}$ ) )
              u2( 1_${ik}$ ) = -temp*u1( 2_${ik}$ ) - x( 2_${ik}$, 2_${ik}$ )
              u2( 2_${ik}$ ) = -temp*u1( 3_${ik}$ )
              u2( 3_${ik}$ ) = scale
              call stdlib${ii}$_slarfg( 3_${ik}$, u2( 1_${ik}$ ), u2( 2_${ik}$ ), 1_${ik}$, tau2 )
              u2( 1_${ik}$ ) = one
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, 4_${ik}$, u1, tau1, d, ldd, work )
              call stdlib${ii}$_slarfx( 'R', 4_${ik}$, 3_${ik}$, u1, tau1, d, ldd, work )
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, 4_${ik}$, u2, tau2, d( 2_${ik}$, 1_${ik}$ ), ldd, work )
              call stdlib${ii}$_slarfx( 'R', 4_${ik}$, 3_${ik}$, u2, tau2, d( 1_${ik}$, 2_${ik}$ ), ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 3_${ik}$, 1_${ik}$ ) ), abs( d( 3_${ik}$, 2_${ik}$ ) ), abs( d( 4_${ik}$, 1_${ik}$ ) ),abs( d( 4_${ik}$, 2_${ik}$ ) ) )&
                        >thresh )go to 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, n-j1+1, u1, tau1, t( j1, j1 ), ldt, work )
              call stdlib${ii}$_slarfx( 'R', j4, 3_${ik}$, u1, tau1, t( 1_${ik}$, j1 ), ldt, work )
              call stdlib${ii}$_slarfx( 'L', 3_${ik}$, n-j1+1, u2, tau2, t( j2, j1 ), ldt, work )
              call stdlib${ii}$_slarfx( 'R', j4, 3_${ik}$, u2, tau2, t( 1_${ik}$, j2 ), ldt, work )
              t( j3, j1 ) = zero
              t( j3, j2 ) = zero
              t( j4, j1 ) = zero
              t( j4, j2 ) = zero
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_slarfx( 'R', n, 3_${ik}$, u1, tau1, q( 1_${ik}$, j1 ), ldq, work )
                 call stdlib${ii}$_slarfx( 'R', n, 3_${ik}$, u2, tau2, q( 1_${ik}$, j2 ), ldq, work )
              end if
              40 continue
              if( n2==2_${ik}$ ) then
                 ! standardize new 2-by-2 block t11
                 call stdlib${ii}$_slanv2( t( j1, j1 ), t( j1, j2 ), t( j2, j1 ),t( j2, j2 ), wr1, wi1, &
                           wr2, wi2, cs, sn )
                 call stdlib${ii}$_srot( n-j1-1, t( j1, j1+2 ), ldt, t( j2, j1+2 ), ldt,cs, sn )
                 call stdlib${ii}$_srot( j1-1, t( 1_${ik}$, j1 ), 1_${ik}$, t( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
                 if( wantq )call stdlib${ii}$_srot( n, q( 1_${ik}$, j1 ), 1_${ik}$, q( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              end if
              if( n1==2_${ik}$ ) then
                 ! standardize new 2-by-2 block t22
                 j3 = j1 + n2
                 j4 = j3 + 1_${ik}$
                 call stdlib${ii}$_slanv2( t( j3, j3 ), t( j3, j4 ), t( j4, j3 ),t( j4, j4 ), wr1, wi1, &
                           wr2, wi2, cs, sn )
                 if( j3+2<=n )call stdlib${ii}$_srot( n-j3-1, t( j3, j3+2 ), ldt, t( j4, j3+2 ),ldt, cs,&
                            sn )
                 call stdlib${ii}$_srot( j3-1, t( 1_${ik}$, j3 ), 1_${ik}$, t( 1_${ik}$, j4 ), 1_${ik}$, cs, sn )
                 if( wantq )call stdlib${ii}$_srot( n, q( 1_${ik}$, j3 ), 1_${ik}$, q( 1_${ik}$, j4 ), 1_${ik}$, cs, sn )
              end if
           end if
           return
           ! exit with info = 1 if swap was rejected.
        50 continue
           info = 1_${ik}$
           return
     end subroutine stdlib${ii}$_slaexc

     module subroutine stdlib${ii}$_dlaexc( wantq, n, t, ldt, q, ldq, j1, n1, n2, work,info )
     !! DLAEXC swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in
     !! an upper quasi-triangular matrix T by an orthogonal similarity
     !! transformation.
     !! T must be in Schur canonical form, that is, block upper triangular
     !! with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block
     !! has its diagonal elements equal and its off-diagonal elements of
     !! opposite sign.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: wantq
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: j1, ldq, ldt, n, n1, n2
           ! Array Arguments 
           real(dp), intent(inout) :: q(ldq,*), t(ldt,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ldd = 4_${ik}$
           integer(${ik}$), parameter :: ldx = 2_${ik}$
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: ierr, j2, j3, j4, k, nd
           real(dp) :: cs, dnorm, eps, scale, smlnum, sn, t11, t22, t33, tau, tau1, tau2, temp, &
                     thresh, wi1, wi2, wr1, wr2, xnorm
           ! Local Arrays 
           real(dp) :: d(ldd,4_${ik}$), u(3_${ik}$), u1(3_${ik}$), u2(3_${ik}$), x(ldx,2_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           info = 0_${ik}$
           ! quick return if possible
           if( n==0 .or. n1==0 .or. n2==0 )return
           if( j1+n1>n )return
           j2 = j1 + 1_${ik}$
           j3 = j1 + 2_${ik}$
           j4 = j1 + 3_${ik}$
           if( n1==1_${ik}$ .and. n2==1_${ik}$ ) then
              ! swap two 1-by-1 blocks.
              t11 = t( j1, j1 )
              t22 = t( j2, j2 )
              ! determine the transformation to perform the interchange.
              call stdlib${ii}$_dlartg( t( j1, j2 ), t22-t11, cs, sn, temp )
              ! apply transformation to the matrix t.
              if( j3<=n )call stdlib${ii}$_drot( n-j1-1, t( j1, j3 ), ldt, t( j2, j3 ), ldt, cs,sn )
                        
              call stdlib${ii}$_drot( j1-1, t( 1_${ik}$, j1 ), 1_${ik}$, t( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              t( j1, j1 ) = t22
              t( j2, j2 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_drot( n, q( 1_${ik}$, j1 ), 1_${ik}$, q( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              end if
           else
              ! swapping involves at least one 2-by-2 block.
              ! copy the diagonal block of order n1+n2 to the local array d
              ! and compute its norm.
              nd = n1 + n2
              call stdlib${ii}$_dlacpy( 'FULL', nd, nd, t( j1, j1 ), ldt, d, ldd )
              dnorm = stdlib${ii}$_dlange( 'MAX', nd, nd, d, ldd, work )
              ! compute machine-dependent threshold for test for accepting
              ! swap.
              eps = stdlib${ii}$_dlamch( 'P' )
              smlnum = stdlib${ii}$_dlamch( 'S' ) / eps
              thresh = max( ten*eps*dnorm, smlnum )
              ! solve t11*x - x*t22 = scale*t12 for x.
              call stdlib${ii}$_dlasy2( .false., .false., -1_${ik}$, n1, n2, d, ldd,d( n1+1, n1+1 ), ldd, d( 1_${ik}$,&
                         n1+1 ), ldd, scale, x,ldx, xnorm, ierr )
              ! swap the adjacent diagonal blocks.
              k = n1 + n1 + n2 - 3_${ik}$
              go to ( 10, 20, 30 )k
              10 continue
              ! n1 = 1, n2 = 2: generate elementary reflector h so that:
              ! ( scale, x11, x12 ) h = ( 0, 0, * )
              u( 1_${ik}$ ) = scale
              u( 2_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )
              u( 3_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )
              call stdlib${ii}$_dlarfg( 3_${ik}$, u( 3_${ik}$ ), u, 1_${ik}$, tau )
              u( 3_${ik}$ ) = one
              t11 = t( j1, j1 )
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              call stdlib${ii}$_dlarfx( 'R', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 3, 1 ) ), abs( d( 3, 2 ) ), abs( d( 3,3 )-t11 ) )>thresh ) go to 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, n-j1+1, u, tau, t( j1, j1 ), ldt, work )
              call stdlib${ii}$_dlarfx( 'R', j2, 3_${ik}$, u, tau, t( 1_${ik}$, j1 ), ldt, work )
              t( j3, j1 ) = zero
              t( j3, j2 ) = zero
              t( j3, j3 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_dlarfx( 'R', n, 3_${ik}$, u, tau, q( 1_${ik}$, j1 ), ldq, work )
              end if
              go to 40
              20 continue
              ! n1 = 2, n2 = 1: generate elementary reflector h so that:
              ! h (  -x11 ) = ( * )
                ! (  -x21 ) = ( 0 )
                ! ( scale ) = ( 0 )
              u( 1_${ik}$ ) = -x( 1_${ik}$, 1_${ik}$ )
              u( 2_${ik}$ ) = -x( 2_${ik}$, 1_${ik}$ )
              u( 3_${ik}$ ) = scale
              call stdlib${ii}$_dlarfg( 3_${ik}$, u( 1_${ik}$ ), u( 2_${ik}$ ), 1_${ik}$, tau )
              u( 1_${ik}$ ) = one
              t33 = t( j3, j3 )
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              call stdlib${ii}$_dlarfx( 'R', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 2, 1 ) ), abs( d( 3, 1 ) ), abs( d( 1,1 )-t33 ) )>thresh ) go to 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_dlarfx( 'R', j3, 3_${ik}$, u, tau, t( 1_${ik}$, j1 ), ldt, work )
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, n-j1, u, tau, t( j1, j2 ), ldt, work )
              t( j1, j1 ) = t33
              t( j2, j1 ) = zero
              t( j3, j1 ) = zero
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_dlarfx( 'R', n, 3_${ik}$, u, tau, q( 1_${ik}$, j1 ), ldq, work )
              end if
              go to 40
              30 continue
              ! n1 = 2, n2 = 2: generate elementary reflectors h(1) and h(2) so
              ! that:
              ! h(2) h(1) (  -x11  -x12 ) = (  *  * )
                        ! (  -x21  -x22 )   (  0  * )
                        ! ( scale    0  )   (  0  0 )
                        ! (    0  scale )   (  0  0 )
              u1( 1_${ik}$ ) = -x( 1_${ik}$, 1_${ik}$ )
              u1( 2_${ik}$ ) = -x( 2_${ik}$, 1_${ik}$ )
              u1( 3_${ik}$ ) = scale
              call stdlib${ii}$_dlarfg( 3_${ik}$, u1( 1_${ik}$ ), u1( 2_${ik}$ ), 1_${ik}$, tau1 )
              u1( 1_${ik}$ ) = one
              temp = -tau1*( x( 1_${ik}$, 2_${ik}$ )+u1( 2_${ik}$ )*x( 2_${ik}$, 2_${ik}$ ) )
              u2( 1_${ik}$ ) = -temp*u1( 2_${ik}$ ) - x( 2_${ik}$, 2_${ik}$ )
              u2( 2_${ik}$ ) = -temp*u1( 3_${ik}$ )
              u2( 3_${ik}$ ) = scale
              call stdlib${ii}$_dlarfg( 3_${ik}$, u2( 1_${ik}$ ), u2( 2_${ik}$ ), 1_${ik}$, tau2 )
              u2( 1_${ik}$ ) = one
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, 4_${ik}$, u1, tau1, d, ldd, work )
              call stdlib${ii}$_dlarfx( 'R', 4_${ik}$, 3_${ik}$, u1, tau1, d, ldd, work )
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, 4_${ik}$, u2, tau2, d( 2_${ik}$, 1_${ik}$ ), ldd, work )
              call stdlib${ii}$_dlarfx( 'R', 4_${ik}$, 3_${ik}$, u2, tau2, d( 1_${ik}$, 2_${ik}$ ), ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 3_${ik}$, 1_${ik}$ ) ), abs( d( 3_${ik}$, 2_${ik}$ ) ), abs( d( 4_${ik}$, 1_${ik}$ ) ),abs( d( 4_${ik}$, 2_${ik}$ ) ) )&
                        >thresh )go to 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, n-j1+1, u1, tau1, t( j1, j1 ), ldt, work )
              call stdlib${ii}$_dlarfx( 'R', j4, 3_${ik}$, u1, tau1, t( 1_${ik}$, j1 ), ldt, work )
              call stdlib${ii}$_dlarfx( 'L', 3_${ik}$, n-j1+1, u2, tau2, t( j2, j1 ), ldt, work )
              call stdlib${ii}$_dlarfx( 'R', j4, 3_${ik}$, u2, tau2, t( 1_${ik}$, j2 ), ldt, work )
              t( j3, j1 ) = zero
              t( j3, j2 ) = zero
              t( j4, j1 ) = zero
              t( j4, j2 ) = zero
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_dlarfx( 'R', n, 3_${ik}$, u1, tau1, q( 1_${ik}$, j1 ), ldq, work )
                 call stdlib${ii}$_dlarfx( 'R', n, 3_${ik}$, u2, tau2, q( 1_${ik}$, j2 ), ldq, work )
              end if
              40 continue
              if( n2==2_${ik}$ ) then
                 ! standardize new 2-by-2 block t11
                 call stdlib${ii}$_dlanv2( t( j1, j1 ), t( j1, j2 ), t( j2, j1 ),t( j2, j2 ), wr1, wi1, &
                           wr2, wi2, cs, sn )
                 call stdlib${ii}$_drot( n-j1-1, t( j1, j1+2 ), ldt, t( j2, j1+2 ), ldt,cs, sn )
                 call stdlib${ii}$_drot( j1-1, t( 1_${ik}$, j1 ), 1_${ik}$, t( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
                 if( wantq )call stdlib${ii}$_drot( n, q( 1_${ik}$, j1 ), 1_${ik}$, q( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              end if
              if( n1==2_${ik}$ ) then
                 ! standardize new 2-by-2 block t22
                 j3 = j1 + n2
                 j4 = j3 + 1_${ik}$
                 call stdlib${ii}$_dlanv2( t( j3, j3 ), t( j3, j4 ), t( j4, j3 ),t( j4, j4 ), wr1, wi1, &
                           wr2, wi2, cs, sn )
                 if( j3+2<=n )call stdlib${ii}$_drot( n-j3-1, t( j3, j3+2 ), ldt, t( j4, j3+2 ),ldt, cs,&
                            sn )
                 call stdlib${ii}$_drot( j3-1, t( 1_${ik}$, j3 ), 1_${ik}$, t( 1_${ik}$, j4 ), 1_${ik}$, cs, sn )
                 if( wantq )call stdlib${ii}$_drot( n, q( 1_${ik}$, j3 ), 1_${ik}$, q( 1_${ik}$, j4 ), 1_${ik}$, cs, sn )
              end if
           end if
           return
           ! exit with info = 1 if swap was rejected.
           50 continue
           info = 1_${ik}$
           return
     end subroutine stdlib${ii}$_dlaexc

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     module subroutine stdlib${ii}$_${ri}$laexc( wantq, n, t, ldt, q, ldq, j1, n1, n2, work,info )
     !! DLAEXC: swaps adjacent diagonal blocks T11 and T22 of order 1 or 2 in
     !! an upper quasi-triangular matrix T by an orthogonal similarity
     !! transformation.
     !! T must be in Schur canonical form, that is, block upper triangular
     !! with 1-by-1 and 2-by-2 diagonal blocks; each 2-by-2 diagonal block
     !! has its diagonal elements equal and its off-diagonal elements of
     !! opposite sign.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: wantq
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: j1, ldq, ldt, n, n1, n2
           ! Array Arguments 
           real(${rk}$), intent(inout) :: q(ldq,*), t(ldt,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: ldd = 4_${ik}$
           integer(${ik}$), parameter :: ldx = 2_${ik}$
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: ierr, j2, j3, j4, k, nd
           real(${rk}$) :: cs, dnorm, eps, scale, smlnum, sn, t11, t22, t33, tau, tau1, tau2, temp, &
                     thresh, wi1, wi2, wr1, wr2, xnorm
           ! Local Arrays 
           real(${rk}$) :: d(ldd,4_${ik}$), u(3_${ik}$), u1(3_${ik}$), u2(3_${ik}$), x(ldx,2_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           info = 0_${ik}$
           ! quick return if possible
           if( n==0 .or. n1==0 .or. n2==0 )return
           if( j1+n1>n )return
           j2 = j1 + 1_${ik}$
           j3 = j1 + 2_${ik}$
           j4 = j1 + 3_${ik}$
           if( n1==1_${ik}$ .and. n2==1_${ik}$ ) then
              ! swap two 1-by-1 blocks.
              t11 = t( j1, j1 )
              t22 = t( j2, j2 )
              ! determine the transformation to perform the interchange.
              call stdlib${ii}$_${ri}$lartg( t( j1, j2 ), t22-t11, cs, sn, temp )
              ! apply transformation to the matrix t.
              if( j3<=n )call stdlib${ii}$_${ri}$rot( n-j1-1, t( j1, j3 ), ldt, t( j2, j3 ), ldt, cs,sn )
                        
              call stdlib${ii}$_${ri}$rot( j1-1, t( 1_${ik}$, j1 ), 1_${ik}$, t( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              t( j1, j1 ) = t22
              t( j2, j2 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_${ri}$rot( n, q( 1_${ik}$, j1 ), 1_${ik}$, q( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              end if
           else
              ! swapping involves at least one 2-by-2 block.
              ! copy the diagonal block of order n1+n2 to the local array d
              ! and compute its norm.
              nd = n1 + n2
              call stdlib${ii}$_${ri}$lacpy( 'FULL', nd, nd, t( j1, j1 ), ldt, d, ldd )
              dnorm = stdlib${ii}$_${ri}$lange( 'MAX', nd, nd, d, ldd, work )
              ! compute machine-dependent threshold for test for accepting
              ! swap.
              eps = stdlib${ii}$_${ri}$lamch( 'P' )
              smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) / eps
              thresh = max( ten*eps*dnorm, smlnum )
              ! solve t11*x - x*t22 = scale*t12 for x.
              call stdlib${ii}$_${ri}$lasy2( .false., .false., -1_${ik}$, n1, n2, d, ldd,d( n1+1, n1+1 ), ldd, d( 1_${ik}$,&
                         n1+1 ), ldd, scale, x,ldx, xnorm, ierr )
              ! swap the adjacent diagonal blocks.
              k = n1 + n1 + n2 - 3_${ik}$
              go to ( 10, 20, 30 )k
              10 continue
              ! n1 = 1, n2 = 2: generate elementary reflector h so that:
              ! ( scale, x11, x12 ) h = ( 0, 0, * )
              u( 1_${ik}$ ) = scale
              u( 2_${ik}$ ) = x( 1_${ik}$, 1_${ik}$ )
              u( 3_${ik}$ ) = x( 1_${ik}$, 2_${ik}$ )
              call stdlib${ii}$_${ri}$larfg( 3_${ik}$, u( 3_${ik}$ ), u, 1_${ik}$, tau )
              u( 3_${ik}$ ) = one
              t11 = t( j1, j1 )
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              call stdlib${ii}$_${ri}$larfx( 'R', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 3, 1 ) ), abs( d( 3, 2 ) ), abs( d( 3,3 )-t11 ) )>thresh ) goto 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, n-j1+1, u, tau, t( j1, j1 ), ldt, work )
              call stdlib${ii}$_${ri}$larfx( 'R', j2, 3_${ik}$, u, tau, t( 1_${ik}$, j1 ), ldt, work )
              t( j3, j1 ) = zero
              t( j3, j2 ) = zero
              t( j3, j3 ) = t11
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_${ri}$larfx( 'R', n, 3_${ik}$, u, tau, q( 1_${ik}$, j1 ), ldq, work )
              end if
              go to 40
              20 continue
              ! n1 = 2, n2 = 1: generate elementary reflector h so that:
              ! h (  -x11 ) = ( * )
                ! (  -x21 ) = ( 0 )
                ! ( scale ) = ( 0 )
              u( 1_${ik}$ ) = -x( 1_${ik}$, 1_${ik}$ )
              u( 2_${ik}$ ) = -x( 2_${ik}$, 1_${ik}$ )
              u( 3_${ik}$ ) = scale
              call stdlib${ii}$_${ri}$larfg( 3_${ik}$, u( 1_${ik}$ ), u( 2_${ik}$ ), 1_${ik}$, tau )
              u( 1_${ik}$ ) = one
              t33 = t( j3, j3 )
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              call stdlib${ii}$_${ri}$larfx( 'R', 3_${ik}$, 3_${ik}$, u, tau, d, ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 2, 1 ) ), abs( d( 3, 1 ) ), abs( d( 1,1 )-t33 ) )>thresh ) goto 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_${ri}$larfx( 'R', j3, 3_${ik}$, u, tau, t( 1_${ik}$, j1 ), ldt, work )
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, n-j1, u, tau, t( j1, j2 ), ldt, work )
              t( j1, j1 ) = t33
              t( j2, j1 ) = zero
              t( j3, j1 ) = zero
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_${ri}$larfx( 'R', n, 3_${ik}$, u, tau, q( 1_${ik}$, j1 ), ldq, work )
              end if
              go to 40
              30 continue
              ! n1 = 2, n2 = 2: generate elementary reflectors h(1) and h(2) so
              ! that:
              ! h(2) h(1) (  -x11  -x12 ) = (  *  * )
                        ! (  -x21  -x22 )   (  0  * )
                        ! ( scale    0  )   (  0  0 )
                        ! (    0  scale )   (  0  0 )
              u1( 1_${ik}$ ) = -x( 1_${ik}$, 1_${ik}$ )
              u1( 2_${ik}$ ) = -x( 2_${ik}$, 1_${ik}$ )
              u1( 3_${ik}$ ) = scale
              call stdlib${ii}$_${ri}$larfg( 3_${ik}$, u1( 1_${ik}$ ), u1( 2_${ik}$ ), 1_${ik}$, tau1 )
              u1( 1_${ik}$ ) = one
              temp = -tau1*( x( 1_${ik}$, 2_${ik}$ )+u1( 2_${ik}$ )*x( 2_${ik}$, 2_${ik}$ ) )
              u2( 1_${ik}$ ) = -temp*u1( 2_${ik}$ ) - x( 2_${ik}$, 2_${ik}$ )
              u2( 2_${ik}$ ) = -temp*u1( 3_${ik}$ )
              u2( 3_${ik}$ ) = scale
              call stdlib${ii}$_${ri}$larfg( 3_${ik}$, u2( 1_${ik}$ ), u2( 2_${ik}$ ), 1_${ik}$, tau2 )
              u2( 1_${ik}$ ) = one
              ! perform swap provisionally on diagonal block in d.
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, 4_${ik}$, u1, tau1, d, ldd, work )
              call stdlib${ii}$_${ri}$larfx( 'R', 4_${ik}$, 3_${ik}$, u1, tau1, d, ldd, work )
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, 4_${ik}$, u2, tau2, d( 2_${ik}$, 1_${ik}$ ), ldd, work )
              call stdlib${ii}$_${ri}$larfx( 'R', 4_${ik}$, 3_${ik}$, u2, tau2, d( 1_${ik}$, 2_${ik}$ ), ldd, work )
              ! test whether to reject swap.
              if( max( abs( d( 3_${ik}$, 1_${ik}$ ) ), abs( d( 3_${ik}$, 2_${ik}$ ) ), abs( d( 4_${ik}$, 1_${ik}$ ) ),abs( d( 4_${ik}$, 2_${ik}$ ) ) )&
                        >thresh )go to 50
              ! accept swap: apply transformation to the entire matrix t.
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, n-j1+1, u1, tau1, t( j1, j1 ), ldt, work )
              call stdlib${ii}$_${ri}$larfx( 'R', j4, 3_${ik}$, u1, tau1, t( 1_${ik}$, j1 ), ldt, work )
              call stdlib${ii}$_${ri}$larfx( 'L', 3_${ik}$, n-j1+1, u2, tau2, t( j2, j1 ), ldt, work )
              call stdlib${ii}$_${ri}$larfx( 'R', j4, 3_${ik}$, u2, tau2, t( 1_${ik}$, j2 ), ldt, work )
              t( j3, j1 ) = zero
              t( j3, j2 ) = zero
              t( j4, j1 ) = zero
              t( j4, j2 ) = zero
              if( wantq ) then
                 ! accumulate transformation in the matrix q.
                 call stdlib${ii}$_${ri}$larfx( 'R', n, 3_${ik}$, u1, tau1, q( 1_${ik}$, j1 ), ldq, work )
                 call stdlib${ii}$_${ri}$larfx( 'R', n, 3_${ik}$, u2, tau2, q( 1_${ik}$, j2 ), ldq, work )
              end if
              40 continue
              if( n2==2_${ik}$ ) then
                 ! standardize new 2-by-2 block t11
                 call stdlib${ii}$_${ri}$lanv2( t( j1, j1 ), t( j1, j2 ), t( j2, j1 ),t( j2, j2 ), wr1, wi1, &
                           wr2, wi2, cs, sn )
                 call stdlib${ii}$_${ri}$rot( n-j1-1, t( j1, j1+2 ), ldt, t( j2, j1+2 ), ldt,cs, sn )
                 call stdlib${ii}$_${ri}$rot( j1-1, t( 1_${ik}$, j1 ), 1_${ik}$, t( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
                 if( wantq )call stdlib${ii}$_${ri}$rot( n, q( 1_${ik}$, j1 ), 1_${ik}$, q( 1_${ik}$, j2 ), 1_${ik}$, cs, sn )
              end if
              if( n1==2_${ik}$ ) then
                 ! standardize new 2-by-2 block t22
                 j3 = j1 + n2
                 j4 = j3 + 1_${ik}$
                 call stdlib${ii}$_${ri}$lanv2( t( j3, j3 ), t( j3, j4 ), t( j4, j3 ),t( j4, j4 ), wr1, wi1, &
                           wr2, wi2, cs, sn )
                 if( j3+2<=n )call stdlib${ii}$_${ri}$rot( n-j3-1, t( j3, j3+2 ), ldt, t( j4, j3+2 ),ldt, cs,&
                            sn )
                 call stdlib${ii}$_${ri}$rot( j3-1, t( 1_${ik}$, j3 ), 1_${ik}$, t( 1_${ik}$, j4 ), 1_${ik}$, cs, sn )
                 if( wantq )call stdlib${ii}$_${ri}$rot( n, q( 1_${ik}$, j3 ), 1_${ik}$, q( 1_${ik}$, j4 ), 1_${ik}$, cs, sn )
              end if
           end if
           return
           ! exit with info = 1 if swap was rejected.
           50 continue
           info = 1_${ik}$
           return
     end subroutine stdlib${ii}$_${ri}$laexc

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_slanv2( a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn )
     !! SLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric
     !! matrix in standard form:
     !! [ A  B ] = [ CS -SN ] [ AA  BB ] [ CS  SN ]
     !! [ C  D ]   [ SN  CS ] [ CC  DD ] [-SN  CS ]
     !! where either
     !! 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or
     !! 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex
     !! conjugate eigenvalues.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           real(sp), intent(inout) :: a, b, c, d
           real(sp), intent(out) :: cs, rt1i, rt1r, rt2i, rt2r, sn
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: multpl = 4.0e+0_sp
           
           
           ! Local Scalars 
           real(sp) :: aa, bb, bcmax, bcmis, cc, cs1, dd, eps, p, sab, sac, scale, sigma, sn1, &
                     tau, temp, z, safmin, safmn2, safmx2
           integer(${ik}$) :: count
           ! Intrinsic Functions 
           ! Executable Statements 
           safmin = stdlib${ii}$_slamch( 'S' )
           eps = stdlib${ii}$_slamch( 'P' )
           safmn2 = stdlib${ii}$_slamch( 'B' )**int( log( safmin / eps ) /log( stdlib${ii}$_slamch( 'B' ) ) / &
                     two,KIND=${ik}$)
           safmx2 = one / safmn2
           if( c==zero ) then
              cs = one
              sn = zero
           else if( b==zero ) then
              ! swap rows and columns
              cs = zero
              sn = one
              temp = d
              d = a
              a = temp
              b = -c
              c = zero
           else if( (a-d)==zero .and. sign( one, b )/=sign( one, c ) ) then
              cs = one
              sn = zero
           else
              temp = a - d
              p = half*temp
              bcmax = max( abs( b ), abs( c ) )
              bcmis = min( abs( b ), abs( c ) )*sign( one, b )*sign( one, c )
              scale = max( abs( p ), bcmax )
              z = ( p / scale )*p + ( bcmax / scale )*bcmis
              ! if z is of the order of the machine accuracy, postpone the
              ! decision on the nature of eigenvalues
              if( z>=multpl*eps ) then
                 ! real eigenvalues. compute a and d.
                 z = p + sign( sqrt( scale )*sqrt( z ), p )
                 a = d + z
                 d = d - ( bcmax / z )*bcmis
                 ! compute b and the rotation matrix
                 tau = stdlib${ii}$_slapy2( c, z )
                 cs = z / tau
                 sn = c / tau
                 b = b - c
                 c = zero
              else
                 ! complex eigenvalues, or real(almost,KIND=sp) equal eigenvalues.
                 ! make diagonal elements equal.
                 count = 0_${ik}$
                 sigma = b + c
                 10 continue
                 count = count + 1_${ik}$
                 scale = max( abs(temp), abs(sigma) )
                 if( scale>=safmx2 ) then
                    sigma = sigma * safmn2
                    temp = temp * safmn2
                    if (count <= 20)goto 10
                 end if
                 if( scale<=safmn2 ) then
                    sigma = sigma * safmx2
                    temp = temp * safmx2
                    if (count <= 20)goto 10
                 end if
                 p = half*temp
                 tau = stdlib${ii}$_slapy2( sigma, temp )
                 cs = sqrt( half*( one+abs( sigma ) / tau ) )
                 sn = -( p / ( tau*cs ) )*sign( one, sigma )
                 ! compute [ aa  bb ] = [ a  b ] [ cs -sn ]
                         ! [ cc  dd ]   [ c  d ] [ sn  cs ]
                 aa = a*cs + b*sn
                 bb = -a*sn + b*cs
                 cc = c*cs + d*sn
                 dd = -c*sn + d*cs
                 ! compute [ a  b ] = [ cs  sn ] [ aa  bb ]
                         ! [ c  d ]   [-sn  cs ] [ cc  dd ]
                 a = aa*cs + cc*sn
                 b = bb*cs + dd*sn
                 c = -aa*sn + cc*cs
                 d = -bb*sn + dd*cs
                 temp = half*( a+d )
                 a = temp
                 d = temp
                 if( c/=zero ) then
                    if( b/=zero ) then
                       if( sign( one, b )==sign( one, c ) ) then
                          ! real eigenvalues: reduce to upper triangular form
                          sab = sqrt( abs( b ) )
                          sac = sqrt( abs( c ) )
                          p = sign( sab*sac, c )
                          tau = one / sqrt( abs( b+c ) )
                          a = temp + p
                          d = temp - p
                          b = b - c
                          c = zero
                          cs1 = sab*tau
                          sn1 = sac*tau
                          temp = cs*cs1 - sn*sn1
                          sn = cs*sn1 + sn*cs1
                          cs = temp
                       end if
                    else
                       b = -c
                       c = zero
                       temp = cs
                       cs = -sn
                       sn = temp
                    end if
                 end if
              end if
           end if
           ! store eigenvalues in (rt1r,rt1i) and (rt2r,rt2i).
           rt1r = a
           rt2r = d
           if( c==zero ) then
              rt1i = zero
              rt2i = zero
           else
              rt1i = sqrt( abs( b ) )*sqrt( abs( c ) )
              rt2i = -rt1i
           end if
           return
     end subroutine stdlib${ii}$_slanv2

     pure module subroutine stdlib${ii}$_dlanv2( a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn )
     !! DLANV2 computes the Schur factorization of a real 2-by-2 nonsymmetric
     !! matrix in standard form:
     !! [ A  B ] = [ CS -SN ] [ AA  BB ] [ CS  SN ]
     !! [ C  D ]   [ SN  CS ] [ CC  DD ] [-SN  CS ]
     !! where either
     !! 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or
     !! 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex
     !! conjugate eigenvalues.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           real(dp), intent(inout) :: a, b, c, d
           real(dp), intent(out) :: cs, rt1i, rt1r, rt2i, rt2r, sn
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: multpl = 4.0e+0_dp
           
           
           ! Local Scalars 
           real(dp) :: aa, bb, bcmax, bcmis, cc, cs1, dd, eps, p, sab, sac, scale, sigma, sn1, &
                     tau, temp, z, safmin, safmn2, safmx2
           integer(${ik}$) :: count
           ! Intrinsic Functions 
           ! Executable Statements 
           safmin = stdlib${ii}$_dlamch( 'S' )
           eps = stdlib${ii}$_dlamch( 'P' )
           safmn2 = stdlib${ii}$_dlamch( 'B' )**int( log( safmin / eps ) /log( stdlib${ii}$_dlamch( 'B' ) ) / &
                     two,KIND=${ik}$)
           safmx2 = one / safmn2
           if( c==zero ) then
              cs = one
              sn = zero
           else if( b==zero ) then
              ! swap rows and columns
              cs = zero
              sn = one
              temp = d
              d = a
              a = temp
              b = -c
              c = zero
           else if( ( a-d )==zero .and. sign( one, b )/=sign( one, c ) )then
              cs = one
              sn = zero
           else
              temp = a - d
              p = half*temp
              bcmax = max( abs( b ), abs( c ) )
              bcmis = min( abs( b ), abs( c ) )*sign( one, b )*sign( one, c )
              scale = max( abs( p ), bcmax )
              z = ( p / scale )*p + ( bcmax / scale )*bcmis
              ! if z is of the order of the machine accuracy, postpone the
              ! decision on the nature of eigenvalues
              if( z>=multpl*eps ) then
                 ! real eigenvalues. compute a and d.
                 z = p + sign( sqrt( scale )*sqrt( z ), p )
                 a = d + z
                 d = d - ( bcmax / z )*bcmis
                 ! compute b and the rotation matrix
                 tau = stdlib${ii}$_dlapy2( c, z )
                 cs = z / tau
                 sn = c / tau
                 b = b - c
                 c = zero
              else
                 ! complex eigenvalues, or real(almost,KIND=dp) equal eigenvalues.
                 ! make diagonal elements equal.
                 count = 0_${ik}$
                 sigma = b + c
                 10 continue
                 count = count + 1_${ik}$
                 scale = max( abs(temp), abs(sigma) )
                 if( scale>=safmx2 ) then
                    sigma = sigma * safmn2
                    temp = temp * safmn2
                    if (count <= 20)goto 10
                 end if
                 if( scale<=safmn2 ) then
                    sigma = sigma * safmx2
                    temp = temp * safmx2
                    if (count <= 20)goto 10
                 end if
                 p = half*temp
                 tau = stdlib${ii}$_dlapy2( sigma, temp )
                 cs = sqrt( half*( one+abs( sigma ) / tau ) )
                 sn = -( p / ( tau*cs ) )*sign( one, sigma )
                 ! compute [ aa  bb ] = [ a  b ] [ cs -sn ]
                         ! [ cc  dd ]   [ c  d ] [ sn  cs ]
                 aa = a*cs + b*sn
                 bb = -a*sn + b*cs
                 cc = c*cs + d*sn
                 dd = -c*sn + d*cs
                 ! compute [ a  b ] = [ cs  sn ] [ aa  bb ]
                         ! [ c  d ]   [-sn  cs ] [ cc  dd ]
                 a = aa*cs + cc*sn
                 b = bb*cs + dd*sn
                 c = -aa*sn + cc*cs
                 d = -bb*sn + dd*cs
                 temp = half*( a+d )
                 a = temp
                 d = temp
                 if( c/=zero ) then
                    if( b/=zero ) then
                       if( sign( one, b )==sign( one, c ) ) then
                          ! real eigenvalues: reduce to upper triangular form
                          sab = sqrt( abs( b ) )
                          sac = sqrt( abs( c ) )
                          p = sign( sab*sac, c )
                          tau = one / sqrt( abs( b+c ) )
                          a = temp + p
                          d = temp - p
                          b = b - c
                          c = zero
                          cs1 = sab*tau
                          sn1 = sac*tau
                          temp = cs*cs1 - sn*sn1
                          sn = cs*sn1 + sn*cs1
                          cs = temp
                       end if
                    else
                       b = -c
                       c = zero
                       temp = cs
                       cs = -sn
                       sn = temp
                    end if
                 end if
              end if
           end if
           ! store eigenvalues in (rt1r,rt1i) and (rt2r,rt2i).
           rt1r = a
           rt2r = d
           if( c==zero ) then
              rt1i = zero
              rt2i = zero
           else
              rt1i = sqrt( abs( b ) )*sqrt( abs( c ) )
              rt2i = -rt1i
           end if
           return
     end subroutine stdlib${ii}$_dlanv2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$lanv2( a, b, c, d, rt1r, rt1i, rt2r, rt2i, cs, sn )
     !! DLANV2: computes the Schur factorization of a real 2-by-2 nonsymmetric
     !! matrix in standard form:
     !! [ A  B ] = [ CS -SN ] [ AA  BB ] [ CS  SN ]
     !! [ C  D ]   [ SN  CS ] [ CC  DD ] [-SN  CS ]
     !! where either
     !! 1) CC = 0 so that AA and DD are real eigenvalues of the matrix, or
     !! 2) AA = DD and BB*CC < 0, so that AA + or - sqrt(BB*CC) are complex
     !! conjugate eigenvalues.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           real(${rk}$), intent(inout) :: a, b, c, d
           real(${rk}$), intent(out) :: cs, rt1i, rt1r, rt2i, rt2r, sn
        ! =====================================================================
           ! Parameters 
           real(${rk}$), parameter :: multpl = 4.0e+0_${rk}$
           
           
           ! Local Scalars 
           real(${rk}$) :: aa, bb, bcmax, bcmis, cc, cs1, dd, eps, p, sab, sac, scale, sigma, sn1, &
                     tau, temp, z, safmin, safmn2, safmx2
           integer(${ik}$) :: count
           ! Intrinsic Functions 
           ! Executable Statements 
           safmin = stdlib${ii}$_${ri}$lamch( 'S' )
           eps = stdlib${ii}$_${ri}$lamch( 'P' )
           safmn2 = stdlib${ii}$_${ri}$lamch( 'B' )**int( log( safmin / eps ) /log( stdlib${ii}$_${ri}$lamch( 'B' ) ) / &
                     two,KIND=${ik}$)
           safmx2 = one / safmn2
           if( c==zero ) then
              cs = one
              sn = zero
           else if( b==zero ) then
              ! swap rows and columns
              cs = zero
              sn = one
              temp = d
              d = a
              a = temp
              b = -c
              c = zero
           else if( ( a-d )==zero .and. sign( one, b )/=sign( one, c ) )then
              cs = one
              sn = zero
           else
              temp = a - d
              p = half*temp
              bcmax = max( abs( b ), abs( c ) )
              bcmis = min( abs( b ), abs( c ) )*sign( one, b )*sign( one, c )
              scale = max( abs( p ), bcmax )
              z = ( p / scale )*p + ( bcmax / scale )*bcmis
              ! if z is of the order of the machine accuracy, postpone the
              ! decision on the nature of eigenvalues
              if( z>=multpl*eps ) then
                 ! real eigenvalues. compute a and d.
                 z = p + sign( sqrt( scale )*sqrt( z ), p )
                 a = d + z
                 d = d - ( bcmax / z )*bcmis
                 ! compute b and the rotation matrix
                 tau = stdlib${ii}$_${ri}$lapy2( c, z )
                 cs = z / tau
                 sn = c / tau
                 b = b - c
                 c = zero
              else
                 ! complex eigenvalues, or real(almost,KIND=${rk}$) equal eigenvalues.
                 ! make diagonal elements equal.
                 count = 0_${ik}$
                 sigma = b + c
                 10 continue
                 count = count + 1_${ik}$
                 scale = max( abs(temp), abs(sigma) )
                 if( scale>=safmx2 ) then
                    sigma = sigma * safmn2
                    temp = temp * safmn2
                    if (count <= 20)goto 10
                 end if
                 if( scale<=safmn2 ) then
                    sigma = sigma * safmx2
                    temp = temp * safmx2
                    if (count <= 20)goto 10
                 end if
                 p = half*temp
                 tau = stdlib${ii}$_${ri}$lapy2( sigma, temp )
                 cs = sqrt( half*( one+abs( sigma ) / tau ) )
                 sn = -( p / ( tau*cs ) )*sign( one, sigma )
                 ! compute [ aa  bb ] = [ a  b ] [ cs -sn ]
                         ! [ cc  dd ]   [ c  d ] [ sn  cs ]
                 aa = a*cs + b*sn
                 bb = -a*sn + b*cs
                 cc = c*cs + d*sn
                 dd = -c*sn + d*cs
                 ! compute [ a  b ] = [ cs  sn ] [ aa  bb ]
                         ! [ c  d ]   [-sn  cs ] [ cc  dd ]
                 a = aa*cs + cc*sn
                 b = bb*cs + dd*sn
                 c = -aa*sn + cc*cs
                 d = -bb*sn + dd*cs
                 temp = half*( a+d )
                 a = temp
                 d = temp
                 if( c/=zero ) then
                    if( b/=zero ) then
                       if( sign( one, b )==sign( one, c ) ) then
                          ! real eigenvalues: reduce to upper triangular form
                          sab = sqrt( abs( b ) )
                          sac = sqrt( abs( c ) )
                          p = sign( sab*sac, c )
                          tau = one / sqrt( abs( b+c ) )
                          a = temp + p
                          d = temp - p
                          b = b - c
                          c = zero
                          cs1 = sab*tau
                          sn1 = sac*tau
                          temp = cs*cs1 - sn*sn1
                          sn = cs*sn1 + sn*cs1
                          cs = temp
                       end if
                    else
                       b = -c
                       c = zero
                       temp = cs
                       cs = -sn
                       sn = temp
                    end if
                 end if
              end if
           end if
           ! store eigenvalues in (rt1r,rt1i) and (rt2r,rt2i).
           rt1r = a
           rt2r = d
           if( c==zero ) then
              rt1i = zero
              rt2i = zero
           else
              rt1i = sqrt( abs( b ) )*sqrt( abs( c ) )
              rt2i = -rt1i
           end if
           return
     end subroutine stdlib${ii}$_${ri}$lanv2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_slaein( rightv, noinit, n, h, ldh, wr, wi, vr, vi, b,ldb, work, eps3, &
     !! SLAEIN uses inverse iteration to find a right or left eigenvector
     !! corresponding to the eigenvalue (WR,WI) of a real upper Hessenberg
     !! matrix H.
               smlnum, bignum, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: noinit, rightv
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldh, n
           real(sp), intent(in) :: bignum, eps3, smlnum, wi, wr
           ! Array Arguments 
           real(sp), intent(out) :: b(ldb,*), work(*)
           real(sp), intent(in) :: h(ldh,*)
           real(sp), intent(inout) :: vi(*), vr(*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: tenth = 1.0e-1_sp
           
           ! Local Scalars 
           character :: normin, trans
           integer(${ik}$) :: i, i1, i2, i3, ierr, its, j
           real(sp) :: absbii, absbjj, ei, ej, growto, norm, nrmsml, rec, rootn, scale, temp, &
                     vcrit, vmax, vnorm, w, w1, x, xi, xr, y
           ! Intrinsic Functions 
           ! Executable Statements 
           info = 0_${ik}$
           ! growto is the threshold used in the acceptance test for an
           ! eigenvector.
           rootn = sqrt( real( n,KIND=sp) )
           growto = tenth / rootn
           nrmsml = max( one, eps3*rootn )*smlnum
           ! form b = h - (wr,wi)*i (except that the subdiagonal elements and
           ! the imaginary parts of the diagonal elements are not stored).
           do j = 1, n
              do i = 1, j - 1
                 b( i, j ) = h( i, j )
              end do
              b( j, j ) = h( j, j ) - wr
           end do
           if( wi==zero ) then
              ! real eigenvalue.
              if( noinit ) then
                 ! set initial vector.
                 do i = 1, n
                    vr( i ) = eps3
                 end do
              else
                 ! scale supplied initial vector.
                 vnorm = stdlib${ii}$_snrm2( n, vr, 1_${ik}$ )
                 call stdlib${ii}$_sscal( n, ( eps3*rootn ) / max( vnorm, nrmsml ), vr,1_${ik}$ )
              end if
              if( rightv ) then
                 ! lu decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 do i = 1, n - 1
                    ei = h( i+1, i )
                    if( abs( b( i, i ) )<abs( ei ) ) then
                       ! interchange rows and eliminate.
                       x = b( i, i ) / ei
                       b( i, i ) = ei
                       do j = i + 1, n
                          temp = b( i+1, j )
                          b( i+1, j ) = b( i, j ) - x*temp
                          b( i, j ) = temp
                       end do
                    else
                       ! eliminate without interchange.
                       if( b( i, i )==zero )b( i, i ) = eps3
                       x = ei / b( i, i )
                       if( x/=zero ) then
                          do j = i + 1, n
                             b( i+1, j ) = b( i+1, j ) - x*b( i, j )
                          end do
                       end if
                    end if
                 end do
                 if( b( n, n )==zero )b( n, n ) = eps3
                 trans = 'N'
              else
                 ! ul decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 do j = n, 2, -1
                    ej = h( j, j-1 )
                    if( abs( b( j, j ) )<abs( ej ) ) then
                       ! interchange columns and eliminate.
                       x = b( j, j ) / ej
                       b( j, j ) = ej
                       do i = 1, j - 1
                          temp = b( i, j-1 )
                          b( i, j-1 ) = b( i, j ) - x*temp
                          b( i, j ) = temp
                       end do
                    else
                       ! eliminate without interchange.
                       if( b( j, j )==zero )b( j, j ) = eps3
                       x = ej / b( j, j )
                       if( x/=zero ) then
                          do i = 1, j - 1
                             b( i, j-1 ) = b( i, j-1 ) - x*b( i, j )
                          end do
                       end if
                    end if
                 end do
                 if( b( 1_${ik}$, 1_${ik}$ )==zero )b( 1_${ik}$, 1_${ik}$ ) = eps3
                 trans = 'T'
              end if
              normin = 'N'
              do its = 1, n
                 ! solve u*x = scale*v for a right eigenvector
                   ! or u**t*x = scale*v for a left eigenvector,
                 ! overwriting x on v.
                 call stdlib${ii}$_slatrs( 'UPPER', trans, 'NONUNIT', normin, n, b, ldb,vr, scale, work,&
                            ierr )
                 normin = 'Y'
                 ! test for sufficient growth in the norm of v.
                 vnorm = stdlib${ii}$_sasum( n, vr, 1_${ik}$ )
                 if( vnorm>=growto*scale )go to 120
                 ! choose new orthogonal starting vector and try again.
                 temp = eps3 / ( rootn+one )
                 vr( 1_${ik}$ ) = eps3
                 do i = 2, n
                    vr( i ) = temp
                 end do
                 vr( n-its+1 ) = vr( n-its+1 ) - eps3*rootn
              end do
              ! failure to find eigenvector in n iterations.
              info = 1_${ik}$
              120 continue
              ! normalize eigenvector.
              i = stdlib${ii}$_isamax( n, vr, 1_${ik}$ )
              call stdlib${ii}$_sscal( n, one / abs( vr( i ) ), vr, 1_${ik}$ )
           else
              ! complex eigenvalue.
              if( noinit ) then
                 ! set initial vector.
                 do i = 1, n
                    vr( i ) = eps3
                    vi( i ) = zero
                 end do
              else
                 ! scale supplied initial vector.
                 norm = stdlib${ii}$_slapy2( stdlib${ii}$_snrm2( n, vr, 1_${ik}$ ), stdlib${ii}$_snrm2( n, vi, 1_${ik}$ ) )
                           
                 rec = ( eps3*rootn ) / max( norm, nrmsml )
                 call stdlib${ii}$_sscal( n, rec, vr, 1_${ik}$ )
                 call stdlib${ii}$_sscal( n, rec, vi, 1_${ik}$ )
              end if
              if( rightv ) then
                 ! lu decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 ! the imaginary part of the (i,j)-th element of u is stored in
                 ! b(j+1,i).
                 b( 2_${ik}$, 1_${ik}$ ) = -wi
                 do i = 2, n
                    b( i+1, 1_${ik}$ ) = zero
                 end do
                 loop_170: do i = 1, n - 1
                    absbii = stdlib${ii}$_slapy2( b( i, i ), b( i+1, i ) )
                    ei = h( i+1, i )
                    if( absbii<abs( ei ) ) then
                       ! interchange rows and eliminate.
                       xr = b( i, i ) / ei
                       xi = b( i+1, i ) / ei
                       b( i, i ) = ei
                       b( i+1, i ) = zero
                       do j = i + 1, n
                          temp = b( i+1, j )
                          b( i+1, j ) = b( i, j ) - xr*temp
                          b( j+1, i+1 ) = b( j+1, i ) - xi*temp
                          b( i, j ) = temp
                          b( j+1, i ) = zero
                       end do
                       b( i+2, i ) = -wi
                       b( i+1, i+1 ) = b( i+1, i+1 ) - xi*wi
                       b( i+2, i+1 ) = b( i+2, i+1 ) + xr*wi
                    else
                       ! eliminate without interchanging rows.
                       if( absbii==zero ) then
                          b( i, i ) = eps3
                          b( i+1, i ) = zero
                          absbii = eps3
                       end if
                       ei = ( ei / absbii ) / absbii
                       xr = b( i, i )*ei
                       xi = -b( i+1, i )*ei
                       do j = i + 1, n
                          b( i+1, j ) = b( i+1, j ) - xr*b( i, j ) +xi*b( j+1, i )
                          b( j+1, i+1 ) = -xr*b( j+1, i ) - xi*b( i, j )
                       end do
                       b( i+2, i+1 ) = b( i+2, i+1 ) - wi
                    end if
                    ! compute 1-norm of offdiagonal elements of i-th row.
                    work( i ) = stdlib${ii}$_sasum( n-i, b( i, i+1 ), ldb ) +stdlib${ii}$_sasum( n-i, b( i+2, &
                              i ), 1_${ik}$ )
                 end do loop_170
                 if( b( n, n )==zero .and. b( n+1, n )==zero )b( n, n ) = eps3
                 work( n ) = zero
                 i1 = n
                 i2 = 1_${ik}$
                 i3 = -1_${ik}$
              else
                 ! ul decomposition with partial pivoting of conjg(b),
                 ! replacing zero pivots by eps3.
                 ! the imaginary part of the (i,j)-th element of u is stored in
                 ! b(j+1,i).
                 b( n+1, n ) = wi
                 do j = 1, n - 1
                    b( n+1, j ) = zero
                 end do
                 loop_210: do j = n, 2, -1
                    ej = h( j, j-1 )
                    absbjj = stdlib${ii}$_slapy2( b( j, j ), b( j+1, j ) )
                    if( absbjj<abs( ej ) ) then
                       ! interchange columns and eliminate
                       xr = b( j, j ) / ej
                       xi = b( j+1, j ) / ej
                       b( j, j ) = ej
                       b( j+1, j ) = zero
                       do i = 1, j - 1
                          temp = b( i, j-1 )
                          b( i, j-1 ) = b( i, j ) - xr*temp
                          b( j, i ) = b( j+1, i ) - xi*temp
                          b( i, j ) = temp
                          b( j+1, i ) = zero
                       end do
                       b( j+1, j-1 ) = wi
                       b( j-1, j-1 ) = b( j-1, j-1 ) + xi*wi
                       b( j, j-1 ) = b( j, j-1 ) - xr*wi
                    else
                       ! eliminate without interchange.
                       if( absbjj==zero ) then
                          b( j, j ) = eps3
                          b( j+1, j ) = zero
                          absbjj = eps3
                       end if
                       ej = ( ej / absbjj ) / absbjj
                       xr = b( j, j )*ej
                       xi = -b( j+1, j )*ej
                       do i = 1, j - 1
                          b( i, j-1 ) = b( i, j-1 ) - xr*b( i, j ) +xi*b( j+1, i )
                          b( j, i ) = -xr*b( j+1, i ) - xi*b( i, j )
                       end do
                       b( j, j-1 ) = b( j, j-1 ) + wi
                    end if
                    ! compute 1-norm of offdiagonal elements of j-th column.
                    work( j ) = stdlib${ii}$_sasum( j-1, b( 1_${ik}$, j ), 1_${ik}$ ) +stdlib${ii}$_sasum( j-1, b( j+1, 1_${ik}$ ),&
                               ldb )
                 end do loop_210
                 if( b( 1_${ik}$, 1_${ik}$ )==zero .and. b( 2_${ik}$, 1_${ik}$ )==zero )b( 1_${ik}$, 1_${ik}$ ) = eps3
                 work( 1_${ik}$ ) = zero
                 i1 = 1_${ik}$
                 i2 = n
                 i3 = 1_${ik}$
              end if
              loop_270: do its = 1, n
                 scale = one
                 vmax = one
                 vcrit = bignum
                 ! solve u*(xr,xi) = scale*(vr,vi) for a right eigenvector,
                   ! or u**t*(xr,xi) = scale*(vr,vi) for a left eigenvector,
                 ! overwriting (xr,xi) on (vr,vi).
                 loop_250: do i = i1, i2, i3
                    if( work( i )>vcrit ) then
                       rec = one / vmax
                       call stdlib${ii}$_sscal( n, rec, vr, 1_${ik}$ )
                       call stdlib${ii}$_sscal( n, rec, vi, 1_${ik}$ )
                       scale = scale*rec
                       vmax = one
                       vcrit = bignum
                    end if
                    xr = vr( i )
                    xi = vi( i )
                    if( rightv ) then
                       do j = i + 1, n
                          xr = xr - b( i, j )*vr( j ) + b( j+1, i )*vi( j )
                          xi = xi - b( i, j )*vi( j ) - b( j+1, i )*vr( j )
                       end do
                    else
                       do j = 1, i - 1
                          xr = xr - b( j, i )*vr( j ) + b( i+1, j )*vi( j )
                          xi = xi - b( j, i )*vi( j ) - b( i+1, j )*vr( j )
                       end do
                    end if
                    w = abs( b( i, i ) ) + abs( b( i+1, i ) )
                    if( w>smlnum ) then
                       if( w<one ) then
                          w1 = abs( xr ) + abs( xi )
                          if( w1>w*bignum ) then
                             rec = one / w1
                             call stdlib${ii}$_sscal( n, rec, vr, 1_${ik}$ )
                             call stdlib${ii}$_sscal( n, rec, vi, 1_${ik}$ )
                             xr = vr( i )
                             xi = vi( i )
                             scale = scale*rec
                             vmax = vmax*rec
                          end if
                       end if
                       ! divide by diagonal element of b.
                       call stdlib${ii}$_sladiv( xr, xi, b( i, i ), b( i+1, i ), vr( i ),vi( i ) )
                                 
                       vmax = max( abs( vr( i ) )+abs( vi( i ) ), vmax )
                       vcrit = bignum / vmax
                    else
                       do j = 1, n
                          vr( j ) = zero
                          vi( j ) = zero
                       end do
                       vr( i ) = one
                       vi( i ) = one
                       scale = zero
                       vmax = one
                       vcrit = bignum
                    end if
                 end do loop_250
                 ! test for sufficient growth in the norm of (vr,vi).
                 vnorm = stdlib${ii}$_sasum( n, vr, 1_${ik}$ ) + stdlib${ii}$_sasum( n, vi, 1_${ik}$ )
                 if( vnorm>=growto*scale )go to 280
                 ! choose a new orthogonal starting vector and try again.
                 y = eps3 / ( rootn+one )
                 vr( 1_${ik}$ ) = eps3
                 vi( 1_${ik}$ ) = zero
                 do i = 2, n
                    vr( i ) = y
                    vi( i ) = zero
                 end do
                 vr( n-its+1 ) = vr( n-its+1 ) - eps3*rootn
              end do loop_270
              ! failure to find eigenvector in n iterations
              info = 1_${ik}$
              280 continue
              ! normalize eigenvector.
              vnorm = zero
              do i = 1, n
                 vnorm = max( vnorm, abs( vr( i ) )+abs( vi( i ) ) )
              end do
              call stdlib${ii}$_sscal( n, one / vnorm, vr, 1_${ik}$ )
              call stdlib${ii}$_sscal( n, one / vnorm, vi, 1_${ik}$ )
           end if
           return
     end subroutine stdlib${ii}$_slaein

     pure module subroutine stdlib${ii}$_dlaein( rightv, noinit, n, h, ldh, wr, wi, vr, vi, b,ldb, work, eps3, &
     !! DLAEIN uses inverse iteration to find a right or left eigenvector
     !! corresponding to the eigenvalue (WR,WI) of a real upper Hessenberg
     !! matrix H.
               smlnum, bignum, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: noinit, rightv
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldh, n
           real(dp), intent(in) :: bignum, eps3, smlnum, wi, wr
           ! Array Arguments 
           real(dp), intent(out) :: b(ldb,*), work(*)
           real(dp), intent(in) :: h(ldh,*)
           real(dp), intent(inout) :: vi(*), vr(*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: tenth = 1.0e-1_dp
           
           ! Local Scalars 
           character :: normin, trans
           integer(${ik}$) :: i, i1, i2, i3, ierr, its, j
           real(dp) :: absbii, absbjj, ei, ej, growto, norm, nrmsml, rec, rootn, scale, temp, &
                     vcrit, vmax, vnorm, w, w1, x, xi, xr, y
           ! Intrinsic Functions 
           ! Executable Statements 
           info = 0_${ik}$
           ! growto is the threshold used in the acceptance test for an
           ! eigenvector.
           rootn = sqrt( real( n,KIND=dp) )
           growto = tenth / rootn
           nrmsml = max( one, eps3*rootn )*smlnum
           ! form b = h - (wr,wi)*i (except that the subdiagonal elements and
           ! the imaginary parts of the diagonal elements are not stored).
           do j = 1, n
              do i = 1, j - 1
                 b( i, j ) = h( i, j )
              end do
              b( j, j ) = h( j, j ) - wr
           end do
           if( wi==zero ) then
              ! real eigenvalue.
              if( noinit ) then
                 ! set initial vector.
                 do i = 1, n
                    vr( i ) = eps3
                 end do
              else
                 ! scale supplied initial vector.
                 vnorm = stdlib${ii}$_dnrm2( n, vr, 1_${ik}$ )
                 call stdlib${ii}$_dscal( n, ( eps3*rootn ) / max( vnorm, nrmsml ), vr,1_${ik}$ )
              end if
              if( rightv ) then
                 ! lu decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 do i = 1, n - 1
                    ei = h( i+1, i )
                    if( abs( b( i, i ) )<abs( ei ) ) then
                       ! interchange rows and eliminate.
                       x = b( i, i ) / ei
                       b( i, i ) = ei
                       do j = i + 1, n
                          temp = b( i+1, j )
                          b( i+1, j ) = b( i, j ) - x*temp
                          b( i, j ) = temp
                       end do
                    else
                       ! eliminate without interchange.
                       if( b( i, i )==zero )b( i, i ) = eps3
                       x = ei / b( i, i )
                       if( x/=zero ) then
                          do j = i + 1, n
                             b( i+1, j ) = b( i+1, j ) - x*b( i, j )
                          end do
                       end if
                    end if
                 end do
                 if( b( n, n )==zero )b( n, n ) = eps3
                 trans = 'N'
              else
                 ! ul decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 do j = n, 2, -1
                    ej = h( j, j-1 )
                    if( abs( b( j, j ) )<abs( ej ) ) then
                       ! interchange columns and eliminate.
                       x = b( j, j ) / ej
                       b( j, j ) = ej
                       do i = 1, j - 1
                          temp = b( i, j-1 )
                          b( i, j-1 ) = b( i, j ) - x*temp
                          b( i, j ) = temp
                       end do
                    else
                       ! eliminate without interchange.
                       if( b( j, j )==zero )b( j, j ) = eps3
                       x = ej / b( j, j )
                       if( x/=zero ) then
                          do i = 1, j - 1
                             b( i, j-1 ) = b( i, j-1 ) - x*b( i, j )
                          end do
                       end if
                    end if
                 end do
                 if( b( 1_${ik}$, 1_${ik}$ )==zero )b( 1_${ik}$, 1_${ik}$ ) = eps3
                 trans = 'T'
              end if
              normin = 'N'
              do its = 1, n
                 ! solve u*x = scale*v for a right eigenvector
                   ! or u**t*x = scale*v for a left eigenvector,
                 ! overwriting x on v.
                 call stdlib${ii}$_dlatrs( 'UPPER', trans, 'NONUNIT', normin, n, b, ldb,vr, scale, work,&
                            ierr )
                 normin = 'Y'
                 ! test for sufficient growth in the norm of v.
                 vnorm = stdlib${ii}$_dasum( n, vr, 1_${ik}$ )
                 if( vnorm>=growto*scale )go to 120
                 ! choose new orthogonal starting vector and try again.
                 temp = eps3 / ( rootn+one )
                 vr( 1_${ik}$ ) = eps3
                 do i = 2, n
                    vr( i ) = temp
                 end do
                 vr( n-its+1 ) = vr( n-its+1 ) - eps3*rootn
              end do
              ! failure to find eigenvector in n iterations.
              info = 1_${ik}$
              120 continue
              ! normalize eigenvector.
              i = stdlib${ii}$_idamax( n, vr, 1_${ik}$ )
              call stdlib${ii}$_dscal( n, one / abs( vr( i ) ), vr, 1_${ik}$ )
           else
              ! complex eigenvalue.
              if( noinit ) then
                 ! set initial vector.
                 do i = 1, n
                    vr( i ) = eps3
                    vi( i ) = zero
                 end do
              else
                 ! scale supplied initial vector.
                 norm = stdlib${ii}$_dlapy2( stdlib${ii}$_dnrm2( n, vr, 1_${ik}$ ), stdlib${ii}$_dnrm2( n, vi, 1_${ik}$ ) )
                           
                 rec = ( eps3*rootn ) / max( norm, nrmsml )
                 call stdlib${ii}$_dscal( n, rec, vr, 1_${ik}$ )
                 call stdlib${ii}$_dscal( n, rec, vi, 1_${ik}$ )
              end if
              if( rightv ) then
                 ! lu decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 ! the imaginary part of the (i,j)-th element of u is stored in
                 ! b(j+1,i).
                 b( 2_${ik}$, 1_${ik}$ ) = -wi
                 do i = 2, n
                    b( i+1, 1_${ik}$ ) = zero
                 end do
                 loop_170: do i = 1, n - 1
                    absbii = stdlib${ii}$_dlapy2( b( i, i ), b( i+1, i ) )
                    ei = h( i+1, i )
                    if( absbii<abs( ei ) ) then
                       ! interchange rows and eliminate.
                       xr = b( i, i ) / ei
                       xi = b( i+1, i ) / ei
                       b( i, i ) = ei
                       b( i+1, i ) = zero
                       do j = i + 1, n
                          temp = b( i+1, j )
                          b( i+1, j ) = b( i, j ) - xr*temp
                          b( j+1, i+1 ) = b( j+1, i ) - xi*temp
                          b( i, j ) = temp
                          b( j+1, i ) = zero
                       end do
                       b( i+2, i ) = -wi
                       b( i+1, i+1 ) = b( i+1, i+1 ) - xi*wi
                       b( i+2, i+1 ) = b( i+2, i+1 ) + xr*wi
                    else
                       ! eliminate without interchanging rows.
                       if( absbii==zero ) then
                          b( i, i ) = eps3
                          b( i+1, i ) = zero
                          absbii = eps3
                       end if
                       ei = ( ei / absbii ) / absbii
                       xr = b( i, i )*ei
                       xi = -b( i+1, i )*ei
                       do j = i + 1, n
                          b( i+1, j ) = b( i+1, j ) - xr*b( i, j ) +xi*b( j+1, i )
                          b( j+1, i+1 ) = -xr*b( j+1, i ) - xi*b( i, j )
                       end do
                       b( i+2, i+1 ) = b( i+2, i+1 ) - wi
                    end if
                    ! compute 1-norm of offdiagonal elements of i-th row.
                    work( i ) = stdlib${ii}$_dasum( n-i, b( i, i+1 ), ldb ) +stdlib${ii}$_dasum( n-i, b( i+2, &
                              i ), 1_${ik}$ )
                 end do loop_170
                 if( b( n, n )==zero .and. b( n+1, n )==zero )b( n, n ) = eps3
                 work( n ) = zero
                 i1 = n
                 i2 = 1_${ik}$
                 i3 = -1_${ik}$
              else
                 ! ul decomposition with partial pivoting of conjg(b),
                 ! replacing zero pivots by eps3.
                 ! the imaginary part of the (i,j)-th element of u is stored in
                 ! b(j+1,i).
                 b( n+1, n ) = wi
                 do j = 1, n - 1
                    b( n+1, j ) = zero
                 end do
                 loop_210: do j = n, 2, -1
                    ej = h( j, j-1 )
                    absbjj = stdlib${ii}$_dlapy2( b( j, j ), b( j+1, j ) )
                    if( absbjj<abs( ej ) ) then
                       ! interchange columns and eliminate
                       xr = b( j, j ) / ej
                       xi = b( j+1, j ) / ej
                       b( j, j ) = ej
                       b( j+1, j ) = zero
                       do i = 1, j - 1
                          temp = b( i, j-1 )
                          b( i, j-1 ) = b( i, j ) - xr*temp
                          b( j, i ) = b( j+1, i ) - xi*temp
                          b( i, j ) = temp
                          b( j+1, i ) = zero
                       end do
                       b( j+1, j-1 ) = wi
                       b( j-1, j-1 ) = b( j-1, j-1 ) + xi*wi
                       b( j, j-1 ) = b( j, j-1 ) - xr*wi
                    else
                       ! eliminate without interchange.
                       if( absbjj==zero ) then
                          b( j, j ) = eps3
                          b( j+1, j ) = zero
                          absbjj = eps3
                       end if
                       ej = ( ej / absbjj ) / absbjj
                       xr = b( j, j )*ej
                       xi = -b( j+1, j )*ej
                       do i = 1, j - 1
                          b( i, j-1 ) = b( i, j-1 ) - xr*b( i, j ) +xi*b( j+1, i )
                          b( j, i ) = -xr*b( j+1, i ) - xi*b( i, j )
                       end do
                       b( j, j-1 ) = b( j, j-1 ) + wi
                    end if
                    ! compute 1-norm of offdiagonal elements of j-th column.
                    work( j ) = stdlib${ii}$_dasum( j-1, b( 1_${ik}$, j ), 1_${ik}$ ) +stdlib${ii}$_dasum( j-1, b( j+1, 1_${ik}$ ),&
                               ldb )
                 end do loop_210
                 if( b( 1_${ik}$, 1_${ik}$ )==zero .and. b( 2_${ik}$, 1_${ik}$ )==zero )b( 1_${ik}$, 1_${ik}$ ) = eps3
                 work( 1_${ik}$ ) = zero
                 i1 = 1_${ik}$
                 i2 = n
                 i3 = 1_${ik}$
              end if
              loop_270: do its = 1, n
                 scale = one
                 vmax = one
                 vcrit = bignum
                 ! solve u*(xr,xi) = scale*(vr,vi) for a right eigenvector,
                   ! or u**t*(xr,xi) = scale*(vr,vi) for a left eigenvector,
                 ! overwriting (xr,xi) on (vr,vi).
                 loop_250: do i = i1, i2, i3
                    if( work( i )>vcrit ) then
                       rec = one / vmax
                       call stdlib${ii}$_dscal( n, rec, vr, 1_${ik}$ )
                       call stdlib${ii}$_dscal( n, rec, vi, 1_${ik}$ )
                       scale = scale*rec
                       vmax = one
                       vcrit = bignum
                    end if
                    xr = vr( i )
                    xi = vi( i )
                    if( rightv ) then
                       do j = i + 1, n
                          xr = xr - b( i, j )*vr( j ) + b( j+1, i )*vi( j )
                          xi = xi - b( i, j )*vi( j ) - b( j+1, i )*vr( j )
                       end do
                    else
                       do j = 1, i - 1
                          xr = xr - b( j, i )*vr( j ) + b( i+1, j )*vi( j )
                          xi = xi - b( j, i )*vi( j ) - b( i+1, j )*vr( j )
                       end do
                    end if
                    w = abs( b( i, i ) ) + abs( b( i+1, i ) )
                    if( w>smlnum ) then
                       if( w<one ) then
                          w1 = abs( xr ) + abs( xi )
                          if( w1>w*bignum ) then
                             rec = one / w1
                             call stdlib${ii}$_dscal( n, rec, vr, 1_${ik}$ )
                             call stdlib${ii}$_dscal( n, rec, vi, 1_${ik}$ )
                             xr = vr( i )
                             xi = vi( i )
                             scale = scale*rec
                             vmax = vmax*rec
                          end if
                       end if
                       ! divide by diagonal element of b.
                       call stdlib${ii}$_dladiv( xr, xi, b( i, i ), b( i+1, i ), vr( i ),vi( i ) )
                                 
                       vmax = max( abs( vr( i ) )+abs( vi( i ) ), vmax )
                       vcrit = bignum / vmax
                    else
                       do j = 1, n
                          vr( j ) = zero
                          vi( j ) = zero
                       end do
                       vr( i ) = one
                       vi( i ) = one
                       scale = zero
                       vmax = one
                       vcrit = bignum
                    end if
                 end do loop_250
                 ! test for sufficient growth in the norm of (vr,vi).
                 vnorm = stdlib${ii}$_dasum( n, vr, 1_${ik}$ ) + stdlib${ii}$_dasum( n, vi, 1_${ik}$ )
                 if( vnorm>=growto*scale )go to 280
                 ! choose a new orthogonal starting vector and try again.
                 y = eps3 / ( rootn+one )
                 vr( 1_${ik}$ ) = eps3
                 vi( 1_${ik}$ ) = zero
                 do i = 2, n
                    vr( i ) = y
                    vi( i ) = zero
                 end do
                 vr( n-its+1 ) = vr( n-its+1 ) - eps3*rootn
              end do loop_270
              ! failure to find eigenvector in n iterations
              info = 1_${ik}$
              280 continue
              ! normalize eigenvector.
              vnorm = zero
              do i = 1, n
                 vnorm = max( vnorm, abs( vr( i ) )+abs( vi( i ) ) )
              end do
              call stdlib${ii}$_dscal( n, one / vnorm, vr, 1_${ik}$ )
              call stdlib${ii}$_dscal( n, one / vnorm, vi, 1_${ik}$ )
           end if
           return
     end subroutine stdlib${ii}$_dlaein

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$laein( rightv, noinit, n, h, ldh, wr, wi, vr, vi, b,ldb, work, eps3, &
     !! DLAEIN: uses inverse iteration to find a right or left eigenvector
     !! corresponding to the eigenvalue (WR,WI) of a real upper Hessenberg
     !! matrix H.
               smlnum, bignum, info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: noinit, rightv
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldh, n
           real(${rk}$), intent(in) :: bignum, eps3, smlnum, wi, wr
           ! Array Arguments 
           real(${rk}$), intent(out) :: b(ldb,*), work(*)
           real(${rk}$), intent(in) :: h(ldh,*)
           real(${rk}$), intent(inout) :: vi(*), vr(*)
        ! =====================================================================
           ! Parameters 
           real(${rk}$), parameter :: tenth = 1.0e-1_${rk}$
           
           ! Local Scalars 
           character :: normin, trans
           integer(${ik}$) :: i, i1, i2, i3, ierr, its, j
           real(${rk}$) :: absbii, absbjj, ei, ej, growto, norm, nrmsml, rec, rootn, scale, temp, &
                     vcrit, vmax, vnorm, w, w1, x, xi, xr, y
           ! Intrinsic Functions 
           ! Executable Statements 
           info = 0_${ik}$
           ! growto is the threshold used in the acceptance test for an
           ! eigenvector.
           rootn = sqrt( real( n,KIND=${rk}$) )
           growto = tenth / rootn
           nrmsml = max( one, eps3*rootn )*smlnum
           ! form b = h - (wr,wi)*i (except that the subdiagonal elements and
           ! the imaginary parts of the diagonal elements are not stored).
           do j = 1, n
              do i = 1, j - 1
                 b( i, j ) = h( i, j )
              end do
              b( j, j ) = h( j, j ) - wr
           end do
           if( wi==zero ) then
              ! real eigenvalue.
              if( noinit ) then
                 ! set initial vector.
                 do i = 1, n
                    vr( i ) = eps3
                 end do
              else
                 ! scale supplied initial vector.
                 vnorm = stdlib${ii}$_${ri}$nrm2( n, vr, 1_${ik}$ )
                 call stdlib${ii}$_${ri}$scal( n, ( eps3*rootn ) / max( vnorm, nrmsml ), vr,1_${ik}$ )
              end if
              if( rightv ) then
                 ! lu decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 do i = 1, n - 1
                    ei = h( i+1, i )
                    if( abs( b( i, i ) )<abs( ei ) ) then
                       ! interchange rows and eliminate.
                       x = b( i, i ) / ei
                       b( i, i ) = ei
                       do j = i + 1, n
                          temp = b( i+1, j )
                          b( i+1, j ) = b( i, j ) - x*temp
                          b( i, j ) = temp
                       end do
                    else
                       ! eliminate without interchange.
                       if( b( i, i )==zero )b( i, i ) = eps3
                       x = ei / b( i, i )
                       if( x/=zero ) then
                          do j = i + 1, n
                             b( i+1, j ) = b( i+1, j ) - x*b( i, j )
                          end do
                       end if
                    end if
                 end do
                 if( b( n, n )==zero )b( n, n ) = eps3
                 trans = 'N'
              else
                 ! ul decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 do j = n, 2, -1
                    ej = h( j, j-1 )
                    if( abs( b( j, j ) )<abs( ej ) ) then
                       ! interchange columns and eliminate.
                       x = b( j, j ) / ej
                       b( j, j ) = ej
                       do i = 1, j - 1
                          temp = b( i, j-1 )
                          b( i, j-1 ) = b( i, j ) - x*temp
                          b( i, j ) = temp
                       end do
                    else
                       ! eliminate without interchange.
                       if( b( j, j )==zero )b( j, j ) = eps3
                       x = ej / b( j, j )
                       if( x/=zero ) then
                          do i = 1, j - 1
                             b( i, j-1 ) = b( i, j-1 ) - x*b( i, j )
                          end do
                       end if
                    end if
                 end do
                 if( b( 1_${ik}$, 1_${ik}$ )==zero )b( 1_${ik}$, 1_${ik}$ ) = eps3
                 trans = 'T'
              end if
              normin = 'N'
              do its = 1, n
                 ! solve u*x = scale*v for a right eigenvector
                   ! or u**t*x = scale*v for a left eigenvector,
                 ! overwriting x on v.
                 call stdlib${ii}$_${ri}$latrs( 'UPPER', trans, 'NONUNIT', normin, n, b, ldb,vr, scale, work,&
                            ierr )
                 normin = 'Y'
                 ! test for sufficient growth in the norm of v.
                 vnorm = stdlib${ii}$_${ri}$asum( n, vr, 1_${ik}$ )
                 if( vnorm>=growto*scale )go to 120
                 ! choose new orthogonal starting vector and try again.
                 temp = eps3 / ( rootn+one )
                 vr( 1_${ik}$ ) = eps3
                 do i = 2, n
                    vr( i ) = temp
                 end do
                 vr( n-its+1 ) = vr( n-its+1 ) - eps3*rootn
              end do
              ! failure to find eigenvector in n iterations.
              info = 1_${ik}$
              120 continue
              ! normalize eigenvector.
              i = stdlib${ii}$_i${ri}$amax( n, vr, 1_${ik}$ )
              call stdlib${ii}$_${ri}$scal( n, one / abs( vr( i ) ), vr, 1_${ik}$ )
           else
              ! complex eigenvalue.
              if( noinit ) then
                 ! set initial vector.
                 do i = 1, n
                    vr( i ) = eps3
                    vi( i ) = zero
                 end do
              else
                 ! scale supplied initial vector.
                 norm = stdlib${ii}$_${ri}$lapy2( stdlib${ii}$_${ri}$nrm2( n, vr, 1_${ik}$ ), stdlib${ii}$_${ri}$nrm2( n, vi, 1_${ik}$ ) )
                           
                 rec = ( eps3*rootn ) / max( norm, nrmsml )
                 call stdlib${ii}$_${ri}$scal( n, rec, vr, 1_${ik}$ )
                 call stdlib${ii}$_${ri}$scal( n, rec, vi, 1_${ik}$ )
              end if
              if( rightv ) then
                 ! lu decomposition with partial pivoting of b, replacing zero
                 ! pivots by eps3.
                 ! the imaginary part of the (i,j)-th element of u is stored in
                 ! b(j+1,i).
                 b( 2_${ik}$, 1_${ik}$ ) = -wi
                 do i = 2, n
                    b( i+1, 1_${ik}$ ) = zero
                 end do
                 loop_170: do i = 1, n - 1
                    absbii = stdlib${ii}$_${ri}$lapy2( b( i, i ), b( i+1, i ) )
                    ei = h( i+1, i )
                    if( absbii<abs( ei ) ) then
                       ! interchange rows and eliminate.
                       xr = b( i, i ) / ei
                       xi = b( i+1, i ) / ei
                       b( i, i ) = ei
                       b( i+1, i ) = zero
                       do j = i + 1, n
                          temp = b( i+1, j )
                          b( i+1, j ) = b( i, j ) - xr*temp
                          b( j+1, i+1 ) = b( j+1, i ) - xi*temp
                          b( i, j ) = temp
                          b( j+1, i ) = zero
                       end do
                       b( i+2, i ) = -wi
                       b( i+1, i+1 ) = b( i+1, i+1 ) - xi*wi
                       b( i+2, i+1 ) = b( i+2, i+1 ) + xr*wi
                    else
                       ! eliminate without interchanging rows.
                       if( absbii==zero ) then
                          b( i, i ) = eps3
                          b( i+1, i ) = zero
                          absbii = eps3
                       end if
                       ei = ( ei / absbii ) / absbii
                       xr = b( i, i )*ei
                       xi = -b( i+1, i )*ei
                       do j = i + 1, n
                          b( i+1, j ) = b( i+1, j ) - xr*b( i, j ) +xi*b( j+1, i )
                          b( j+1, i+1 ) = -xr*b( j+1, i ) - xi*b( i, j )
                       end do
                       b( i+2, i+1 ) = b( i+2, i+1 ) - wi
                    end if
                    ! compute 1-norm of offdiagonal elements of i-th row.
                    work( i ) = stdlib${ii}$_${ri}$asum( n-i, b( i, i+1 ), ldb ) +stdlib${ii}$_${ri}$asum( n-i, b( i+2, &
                              i ), 1_${ik}$ )
                 end do loop_170
                 if( b( n, n )==zero .and. b( n+1, n )==zero )b( n, n ) = eps3
                 work( n ) = zero
                 i1 = n
                 i2 = 1_${ik}$
                 i3 = -1_${ik}$
              else
                 ! ul decomposition with partial pivoting of conjg(b),
                 ! replacing zero pivots by eps3.
                 ! the imaginary part of the (i,j)-th element of u is stored in
                 ! b(j+1,i).
                 b( n+1, n ) = wi
                 do j = 1, n - 1
                    b( n+1, j ) = zero
                 end do
                 loop_210: do j = n, 2, -1
                    ej = h( j, j-1 )
                    absbjj = stdlib${ii}$_${ri}$lapy2( b( j, j ), b( j+1, j ) )
                    if( absbjj<abs( ej ) ) then
                       ! interchange columns and eliminate
                       xr = b( j, j ) / ej
                       xi = b( j+1, j ) / ej
                       b( j, j ) = ej
                       b( j+1, j ) = zero
                       do i = 1, j - 1
                          temp = b( i, j-1 )
                          b( i, j-1 ) = b( i, j ) - xr*temp
                          b( j, i ) = b( j+1, i ) - xi*temp
                          b( i, j ) = temp
                          b( j+1, i ) = zero
                       end do
                       b( j+1, j-1 ) = wi
                       b( j-1, j-1 ) = b( j-1, j-1 ) + xi*wi
                       b( j, j-1 ) = b( j, j-1 ) - xr*wi
                    else
                       ! eliminate without interchange.
                       if( absbjj==zero ) then
                          b( j, j ) = eps3
                          b( j+1, j ) = zero
                          absbjj = eps3
                       end if
                       ej = ( ej / absbjj ) / absbjj
                       xr = b( j, j )*ej
                       xi = -b( j+1, j )*ej
                       do i = 1, j - 1
                          b( i, j-1 ) = b( i, j-1 ) - xr*b( i, j ) +xi*b( j+1, i )
                          b( j, i ) = -xr*b( j+1, i ) - xi*b( i, j )
                       end do
                       b( j, j-1 ) = b( j, j-1 ) + wi
                    end if
                    ! compute 1-norm of offdiagonal elements of j-th column.
                    work( j ) = stdlib${ii}$_${ri}$asum( j-1, b( 1_${ik}$, j ), 1_${ik}$ ) +stdlib${ii}$_${ri}$asum( j-1, b( j+1, 1_${ik}$ ),&
                               ldb )
                 end do loop_210
                 if( b( 1_${ik}$, 1_${ik}$ )==zero .and. b( 2_${ik}$, 1_${ik}$ )==zero )b( 1_${ik}$, 1_${ik}$ ) = eps3
                 work( 1_${ik}$ ) = zero
                 i1 = 1_${ik}$
                 i2 = n
                 i3 = 1_${ik}$
              end if
              loop_270: do its = 1, n
                 scale = one
                 vmax = one
                 vcrit = bignum
                 ! solve u*(xr,xi) = scale*(vr,vi) for a right eigenvector,
                   ! or u**t*(xr,xi) = scale*(vr,vi) for a left eigenvector,
                 ! overwriting (xr,xi) on (vr,vi).
                 loop_250: do i = i1, i2, i3
                    if( work( i )>vcrit ) then
                       rec = one / vmax
                       call stdlib${ii}$_${ri}$scal( n, rec, vr, 1_${ik}$ )
                       call stdlib${ii}$_${ri}$scal( n, rec, vi, 1_${ik}$ )
                       scale = scale*rec
                       vmax = one
                       vcrit = bignum
                    end if
                    xr = vr( i )
                    xi = vi( i )
                    if( rightv ) then
                       do j = i + 1, n
                          xr = xr - b( i, j )*vr( j ) + b( j+1, i )*vi( j )
                          xi = xi - b( i, j )*vi( j ) - b( j+1, i )*vr( j )
                       end do
                    else
                       do j = 1, i - 1
                          xr = xr - b( j, i )*vr( j ) + b( i+1, j )*vi( j )
                          xi = xi - b( j, i )*vi( j ) - b( i+1, j )*vr( j )
                       end do
                    end if
                    w = abs( b( i, i ) ) + abs( b( i+1, i ) )
                    if( w>smlnum ) then
                       if( w<one ) then
                          w1 = abs( xr ) + abs( xi )
                          if( w1>w*bignum ) then
                             rec = one / w1
                             call stdlib${ii}$_${ri}$scal( n, rec, vr, 1_${ik}$ )
                             call stdlib${ii}$_${ri}$scal( n, rec, vi, 1_${ik}$ )
                             xr = vr( i )
                             xi = vi( i )
                             scale = scale*rec
                             vmax = vmax*rec
                          end if
                       end if
                       ! divide by diagonal element of b.
                       call stdlib${ii}$_${ri}$ladiv( xr, xi, b( i, i ), b( i+1, i ), vr( i ),vi( i ) )
                                 
                       vmax = max( abs( vr( i ) )+abs( vi( i ) ), vmax )
                       vcrit = bignum / vmax
                    else
                       do j = 1, n
                          vr( j ) = zero
                          vi( j ) = zero
                       end do
                       vr( i ) = one
                       vi( i ) = one
                       scale = zero
                       vmax = one
                       vcrit = bignum
                    end if
                 end do loop_250
                 ! test for sufficient growth in the norm of (vr,vi).
                 vnorm = stdlib${ii}$_${ri}$asum( n, vr, 1_${ik}$ ) + stdlib${ii}$_${ri}$asum( n, vi, 1_${ik}$ )
                 if( vnorm>=growto*scale )go to 280
                 ! choose a new orthogonal starting vector and try again.
                 y = eps3 / ( rootn+one )
                 vr( 1_${ik}$ ) = eps3
                 vi( 1_${ik}$ ) = zero
                 do i = 2, n
                    vr( i ) = y
                    vi( i ) = zero
                 end do
                 vr( n-its+1 ) = vr( n-its+1 ) - eps3*rootn
              end do loop_270
              ! failure to find eigenvector in n iterations
              info = 1_${ik}$
              280 continue
              ! normalize eigenvector.
              vnorm = zero
              do i = 1, n
                 vnorm = max( vnorm, abs( vr( i ) )+abs( vi( i ) ) )
              end do
              call stdlib${ii}$_${ri}$scal( n, one / vnorm, vr, 1_${ik}$ )
              call stdlib${ii}$_${ri}$scal( n, one / vnorm, vi, 1_${ik}$ )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$laein

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_claein( rightv, noinit, n, h, ldh, w, v, b, ldb, rwork,eps3, smlnum, &
     !! CLAEIN uses inverse iteration to find a right or left eigenvector
     !! corresponding to the eigenvalue W of a complex upper Hessenberg
     !! matrix H.
               info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: noinit, rightv
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldh, n
           real(sp), intent(in) :: eps3, smlnum
           complex(sp), intent(in) :: w
           ! Array Arguments 
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(out) :: b(ldb,*)
           complex(sp), intent(in) :: h(ldh,*)
           complex(sp), intent(inout) :: v(*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: tenth = 1.0e-1_sp
           
           
           ! Local Scalars 
           character :: normin, trans
           integer(${ik}$) :: i, ierr, its, j
           real(sp) :: growto, nrmsml, rootn, rtemp, scale, vnorm
           complex(sp) :: cdum, ei, ej, temp, x
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=sp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           info = 0_${ik}$
           ! growto is the threshold used in the acceptance test for an
           ! eigenvector.
           rootn = sqrt( real( n,KIND=sp) )
           growto = tenth / rootn
           nrmsml = max( one, eps3*rootn )*smlnum
           ! form b = h - w*i (except that the subdiagonal elements are not
           ! stored).
           do j = 1, n
              do i = 1, j - 1
                 b( i, j ) = h( i, j )
              end do
              b( j, j ) = h( j, j ) - w
           end do
           if( noinit ) then
              ! initialize v.
              do i = 1, n
                 v( i ) = eps3
              end do
           else
              ! scale supplied initial vector.
              vnorm = stdlib${ii}$_scnrm2( n, v, 1_${ik}$ )
              call stdlib${ii}$_csscal( n, ( eps3*rootn ) / max( vnorm, nrmsml ), v, 1_${ik}$ )
           end if
           if( rightv ) then
              ! lu decomposition with partial pivoting of b, replacing czero
              ! pivots by eps3.
              do i = 1, n - 1
                 ei = h( i+1, i )
                 if( cabs1( b( i, i ) )<cabs1( ei ) ) then
                    ! interchange rows and eliminate.
                    x = stdlib${ii}$_cladiv( b( i, i ), ei )
                    b( i, i ) = ei
                    do j = i + 1, n
                       temp = b( i+1, j )
                       b( i+1, j ) = b( i, j ) - x*temp
                       b( i, j ) = temp
                    end do
                 else
                    ! eliminate without interchange.
                    if( b( i, i )==czero )b( i, i ) = eps3
                    x = stdlib${ii}$_cladiv( ei, b( i, i ) )
                    if( x/=czero ) then
                       do j = i + 1, n
                          b( i+1, j ) = b( i+1, j ) - x*b( i, j )
                       end do
                    end if
                 end if
              end do
              if( b( n, n )==czero )b( n, n ) = eps3
              trans = 'N'
           else
              ! ul decomposition with partial pivoting of b, replacing czero
              ! pivots by eps3.
              do j = n, 2, -1
                 ej = h( j, j-1 )
                 if( cabs1( b( j, j ) )<cabs1( ej ) ) then
                    ! interchange columns and eliminate.
                    x = stdlib${ii}$_cladiv( b( j, j ), ej )
                    b( j, j ) = ej
                    do i = 1, j - 1
                       temp = b( i, j-1 )
                       b( i, j-1 ) = b( i, j ) - x*temp
                       b( i, j ) = temp
                    end do
                 else
                    ! eliminate without interchange.
                    if( b( j, j )==czero )b( j, j ) = eps3
                    x = stdlib${ii}$_cladiv( ej, b( j, j ) )
                    if( x/=czero ) then
                       do i = 1, j - 1
                          b( i, j-1 ) = b( i, j-1 ) - x*b( i, j )
                       end do
                    end if
                 end if
              end do
              if( b( 1_${ik}$, 1_${ik}$ )==czero )b( 1_${ik}$, 1_${ik}$ ) = eps3
              trans = 'C'
           end if
           normin = 'N'
           do its = 1, n
              ! solve u*x = scale*v for a right eigenvector
                ! or u**h *x = scale*v for a left eigenvector,
              ! overwriting x on v.
              call stdlib${ii}$_clatrs( 'UPPER', trans, 'NONUNIT', normin, n, b, ldb, v,scale, rwork, &
                        ierr )
              normin = 'Y'
              ! test for sufficient growth in the norm of v.
              vnorm = stdlib${ii}$_scasum( n, v, 1_${ik}$ )
              if( vnorm>=growto*scale )go to 120
              ! choose new orthogonal starting vector and try again.
              rtemp = eps3 / ( rootn+one )
              v( 1_${ik}$ ) = eps3
              do i = 2, n
                 v( i ) = rtemp
              end do
              v( n-its+1 ) = v( n-its+1 ) - eps3*rootn
           end do
           ! failure to find eigenvector in n iterations.
           info = 1_${ik}$
           120 continue
           ! normalize eigenvector.
           i = stdlib${ii}$_icamax( n, v, 1_${ik}$ )
           call stdlib${ii}$_csscal( n, one / cabs1( v( i ) ), v, 1_${ik}$ )
           return
     end subroutine stdlib${ii}$_claein

     pure module subroutine stdlib${ii}$_zlaein( rightv, noinit, n, h, ldh, w, v, b, ldb, rwork,eps3, smlnum, &
     !! ZLAEIN uses inverse iteration to find a right or left eigenvector
     !! corresponding to the eigenvalue W of a complex upper Hessenberg
     !! matrix H.
               info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: noinit, rightv
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldh, n
           real(dp), intent(in) :: eps3, smlnum
           complex(dp), intent(in) :: w
           ! Array Arguments 
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(out) :: b(ldb,*)
           complex(dp), intent(in) :: h(ldh,*)
           complex(dp), intent(inout) :: v(*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: tenth = 1.0e-1_dp
           
           
           ! Local Scalars 
           character :: normin, trans
           integer(${ik}$) :: i, ierr, its, j
           real(dp) :: growto, nrmsml, rootn, rtemp, scale, vnorm
           complex(dp) :: cdum, ei, ej, temp, x
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=dp) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           info = 0_${ik}$
           ! growto is the threshold used in the acceptance test for an
           ! eigenvector.
           rootn = sqrt( real( n,KIND=dp) )
           growto = tenth / rootn
           nrmsml = max( one, eps3*rootn )*smlnum
           ! form b = h - w*i (except that the subdiagonal elements are not
           ! stored).
           do j = 1, n
              do i = 1, j - 1
                 b( i, j ) = h( i, j )
              end do
              b( j, j ) = h( j, j ) - w
           end do
           if( noinit ) then
              ! initialize v.
              do i = 1, n
                 v( i ) = eps3
              end do
           else
              ! scale supplied initial vector.
              vnorm = stdlib${ii}$_dznrm2( n, v, 1_${ik}$ )
              call stdlib${ii}$_zdscal( n, ( eps3*rootn ) / max( vnorm, nrmsml ), v, 1_${ik}$ )
           end if
           if( rightv ) then
              ! lu decomposition with partial pivoting of b, replacing czero
              ! pivots by eps3.
              do i = 1, n - 1
                 ei = h( i+1, i )
                 if( cabs1( b( i, i ) )<cabs1( ei ) ) then
                    ! interchange rows and eliminate.
                    x = stdlib${ii}$_zladiv( b( i, i ), ei )
                    b( i, i ) = ei
                    do j = i + 1, n
                       temp = b( i+1, j )
                       b( i+1, j ) = b( i, j ) - x*temp
                       b( i, j ) = temp
                    end do
                 else
                    ! eliminate without interchange.
                    if( b( i, i )==czero )b( i, i ) = eps3
                    x = stdlib${ii}$_zladiv( ei, b( i, i ) )
                    if( x/=czero ) then
                       do j = i + 1, n
                          b( i+1, j ) = b( i+1, j ) - x*b( i, j )
                       end do
                    end if
                 end if
              end do
              if( b( n, n )==czero )b( n, n ) = eps3
              trans = 'N'
           else
              ! ul decomposition with partial pivoting of b, replacing czero
              ! pivots by eps3.
              do j = n, 2, -1
                 ej = h( j, j-1 )
                 if( cabs1( b( j, j ) )<cabs1( ej ) ) then
                    ! interchange columns and eliminate.
                    x = stdlib${ii}$_zladiv( b( j, j ), ej )
                    b( j, j ) = ej
                    do i = 1, j - 1
                       temp = b( i, j-1 )
                       b( i, j-1 ) = b( i, j ) - x*temp
                       b( i, j ) = temp
                    end do
                 else
                    ! eliminate without interchange.
                    if( b( j, j )==czero )b( j, j ) = eps3
                    x = stdlib${ii}$_zladiv( ej, b( j, j ) )
                    if( x/=czero ) then
                       do i = 1, j - 1
                          b( i, j-1 ) = b( i, j-1 ) - x*b( i, j )
                       end do
                    end if
                 end if
              end do
              if( b( 1_${ik}$, 1_${ik}$ )==czero )b( 1_${ik}$, 1_${ik}$ ) = eps3
              trans = 'C'
           end if
           normin = 'N'
           do its = 1, n
              ! solve u*x = scale*v for a right eigenvector
                ! or u**h *x = scale*v for a left eigenvector,
              ! overwriting x on v.
              call stdlib${ii}$_zlatrs( 'UPPER', trans, 'NONUNIT', normin, n, b, ldb, v,scale, rwork, &
                        ierr )
              normin = 'Y'
              ! test for sufficient growth in the norm of v.
              vnorm = stdlib${ii}$_dzasum( n, v, 1_${ik}$ )
              if( vnorm>=growto*scale )go to 120
              ! choose new orthogonal starting vector and try again.
              rtemp = eps3 / ( rootn+one )
              v( 1_${ik}$ ) = eps3
              do i = 2, n
                 v( i ) = rtemp
              end do
              v( n-its+1 ) = v( n-its+1 ) - eps3*rootn
           end do
           ! failure to find eigenvector in n iterations.
           info = 1_${ik}$
           120 continue
           ! normalize eigenvector.
           i = stdlib${ii}$_izamax( n, v, 1_${ik}$ )
           call stdlib${ii}$_zdscal( n, one / cabs1( v( i ) ), v, 1_${ik}$ )
           return
     end subroutine stdlib${ii}$_zlaein

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$laein( rightv, noinit, n, h, ldh, w, v, b, ldb, rwork,eps3, smlnum, &
     !! ZLAEIN: uses inverse iteration to find a right or left eigenvector
     !! corresponding to the eigenvalue W of a complex upper Hessenberg
     !! matrix H.
               info )
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           logical(lk), intent(in) :: noinit, rightv
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldh, n
           real(${ck}$), intent(in) :: eps3, smlnum
           complex(${ck}$), intent(in) :: w
           ! Array Arguments 
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(out) :: b(ldb,*)
           complex(${ck}$), intent(in) :: h(ldh,*)
           complex(${ck}$), intent(inout) :: v(*)
        ! =====================================================================
           ! Parameters 
           real(${ck}$), parameter :: tenth = 1.0e-1_${ck}$
           
           
           ! Local Scalars 
           character :: normin, trans
           integer(${ik}$) :: i, ierr, its, j
           real(${ck}$) :: growto, nrmsml, rootn, rtemp, scale, vnorm
           complex(${ck}$) :: cdum, ei, ej, temp, x
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( cdum ) = abs( real( cdum,KIND=${ck}$) ) + abs( aimag( cdum ) )
           ! Executable Statements 
           info = 0_${ik}$
           ! growto is the threshold used in the acceptance test for an
           ! eigenvector.
           rootn = sqrt( real( n,KIND=${ck}$) )
           growto = tenth / rootn
           nrmsml = max( one, eps3*rootn )*smlnum
           ! form b = h - w*i (except that the subdiagonal elements are not
           ! stored).
           do j = 1, n
              do i = 1, j - 1
                 b( i, j ) = h( i, j )
              end do
              b( j, j ) = h( j, j ) - w
           end do
           if( noinit ) then
              ! initialize v.
              do i = 1, n
                 v( i ) = eps3
              end do
           else
              ! scale supplied initial vector.
              vnorm = stdlib${ii}$_${c2ri(ci)}$znrm2( n, v, 1_${ik}$ )
              call stdlib${ii}$_${ci}$dscal( n, ( eps3*rootn ) / max( vnorm, nrmsml ), v, 1_${ik}$ )
           end if
           if( rightv ) then
              ! lu decomposition with partial pivoting of b, replacing czero
              ! pivots by eps3.
              do i = 1, n - 1
                 ei = h( i+1, i )
                 if( cabs1( b( i, i ) )<cabs1( ei ) ) then
                    ! interchange rows and eliminate.
                    x = stdlib${ii}$_${ci}$ladiv( b( i, i ), ei )
                    b( i, i ) = ei
                    do j = i + 1, n
                       temp = b( i+1, j )
                       b( i+1, j ) = b( i, j ) - x*temp
                       b( i, j ) = temp
                    end do
                 else
                    ! eliminate without interchange.
                    if( b( i, i )==czero )b( i, i ) = eps3
                    x = stdlib${ii}$_${ci}$ladiv( ei, b( i, i ) )
                    if( x/=czero ) then
                       do j = i + 1, n
                          b( i+1, j ) = b( i+1, j ) - x*b( i, j )
                       end do
                    end if
                 end if
              end do
              if( b( n, n )==czero )b( n, n ) = eps3
              trans = 'N'
           else
              ! ul decomposition with partial pivoting of b, replacing czero
              ! pivots by eps3.
              do j = n, 2, -1
                 ej = h( j, j-1 )
                 if( cabs1( b( j, j ) )<cabs1( ej ) ) then
                    ! interchange columns and eliminate.
                    x = stdlib${ii}$_${ci}$ladiv( b( j, j ), ej )
                    b( j, j ) = ej
                    do i = 1, j - 1
                       temp = b( i, j-1 )
                       b( i, j-1 ) = b( i, j ) - x*temp
                       b( i, j ) = temp
                    end do
                 else
                    ! eliminate without interchange.
                    if( b( j, j )==czero )b( j, j ) = eps3
                    x = stdlib${ii}$_${ci}$ladiv( ej, b( j, j ) )
                    if( x/=czero ) then
                       do i = 1, j - 1
                          b( i, j-1 ) = b( i, j-1 ) - x*b( i, j )
                       end do
                    end if
                 end if
              end do
              if( b( 1_${ik}$, 1_${ik}$ )==czero )b( 1_${ik}$, 1_${ik}$ ) = eps3
              trans = 'C'
           end if
           normin = 'N'
           do its = 1, n
              ! solve u*x = scale*v for a right eigenvector
                ! or u**h *x = scale*v for a left eigenvector,
              ! overwriting x on v.
              call stdlib${ii}$_${ci}$latrs( 'UPPER', trans, 'NONUNIT', normin, n, b, ldb, v,scale, rwork, &
                        ierr )
              normin = 'Y'
              ! test for sufficient growth in the norm of v.
              vnorm = stdlib${ii}$_${c2ri(ci)}$zasum( n, v, 1_${ik}$ )
              if( vnorm>=growto*scale )go to 120
              ! choose new orthogonal starting vector and try again.
              rtemp = eps3 / ( rootn+one )
              v( 1_${ik}$ ) = eps3
              do i = 2, n
                 v( i ) = rtemp
              end do
              v( n-its+1 ) = v( n-its+1 ) - eps3*rootn
           end do
           ! failure to find eigenvector in n iterations.
           info = 1_${ik}$
           120 continue
           ! normalize eigenvector.
           i = stdlib${ii}$_i${ci}$amax( n, v, 1_${ik}$ )
           call stdlib${ii}$_${ci}$dscal( n, one / cabs1( v( i ) ), v, 1_${ik}$ )
           return
     end subroutine stdlib${ii}$_${ci}$laein

#:endif
#:endfor


#:endfor
end submodule stdlib_lapack_eigv_gen2