stdlib_lapack_orthogonal_factors_qr.fypp Source File


Source Code

#:include "common.fypp" 
submodule(stdlib_lapack_orthogonal_factors) stdlib_lapack_orthogonal_factors_qr
  implicit none


  contains
#:for ik,it,ii in LINALG_INT_KINDS_TYPES

     pure module subroutine stdlib${ii}$_sgeqr( m, n, a, lda, t, tsize, work, lwork,info )
     !! SGEQR computes a QR factorization of a real M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, tsize, lwork
           ! Array Arguments 
           real(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: t(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery, lminws, mint, minw
           integer(${ik}$) :: mb, nb, mintsz, nblcks
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           lquery = ( tsize==-1_${ik}$ .or. tsize==-2_${ik}$ .or.lwork==-1_${ik}$ .or. lwork==-2_${ik}$ )
           mint = .false.
           minw = .false.
           if( tsize==-2_${ik}$ .or. lwork==-2_${ik}$ ) then
             if( tsize/=-1_${ik}$ ) mint = .true.
             if( lwork/=-1_${ik}$ ) minw = .true.
           end if
           ! determine the block size
           if( min( m, n )>0_${ik}$ ) then
             mb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGEQR ', ' ', m, n, 1_${ik}$, -1_${ik}$ )
             nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGEQR ', ' ', m, n, 2_${ik}$, -1_${ik}$ )
           else
             mb = m
             nb = 1_${ik}$
           end if
           if( mb>m .or. mb<=n ) mb = m
           if( nb>min( m, n ) .or. nb<1_${ik}$ ) nb = 1_${ik}$
           mintsz = n + 5_${ik}$
           if ( mb>n .and. m>n ) then
             if( mod( m - n, mb - n )==0_${ik}$ ) then
               nblcks = ( m - n ) / ( mb - n )
             else
               nblcks = ( m - n ) / ( mb - n ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           ! determine if the workspace size satisfies minimal size
           lminws = .false.
           if( ( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) .or. lwork<nb*n ).and. ( lwork>=n ) .and. ( &
                     tsize>=mintsz ).and. ( .not.lquery ) ) then
             if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) ) then
               lminws = .true.
               nb = 1_${ik}$
               mb = m
             end if
             if( lwork<nb*n ) then
               lminws = .true.
               nb = 1_${ik}$
             end if
           end if
           if( m<0_${ik}$ ) then
             info = -1_${ik}$
           else if( n<0_${ik}$ ) then
             info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
             info = -4_${ik}$
           else if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) &
                     then
             info = -6_${ik}$
           else if( ( lwork<max( 1_${ik}$, n*nb ) ) .and. ( .not.lquery ).and. ( .not.lminws ) ) &
                     then
             info = -8_${ik}$
           end if
           if( info==0_${ik}$ ) then
             if( mint ) then
               t( 1_${ik}$ ) = mintsz
             else
               t( 1_${ik}$ ) = nb*n*nblcks + 5_${ik}$
             end if
             t( 2_${ik}$ ) = mb
             t( 3_${ik}$ ) = nb
             if( minw ) then
               work( 1_${ik}$ ) = max( 1_${ik}$, n )
             else
               work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
             end if
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'SGEQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n )==0_${ik}$ ) then
             return
           end if
           ! the qr decomposition
           if( ( m<=n ) .or. ( mb<=n ) .or. ( mb>=m ) ) then
             call stdlib${ii}$_sgeqrt( m, n, nb, a, lda, t( 6_${ik}$ ), nb, work, info )
           else
             call stdlib${ii}$_slatsqr( m, n, mb, nb, a, lda, t( 6_${ik}$ ), nb, work,lwork, info )
           end if
           work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
           return
     end subroutine stdlib${ii}$_sgeqr

     pure module subroutine stdlib${ii}$_dgeqr( m, n, a, lda, t, tsize, work, lwork,info )
     !! DGEQR computes a QR factorization of a real M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, tsize, lwork
           ! Array Arguments 
           real(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: t(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery, lminws, mint, minw
           integer(${ik}$) :: mb, nb, mintsz, nblcks
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           lquery = ( tsize==-1_${ik}$ .or. tsize==-2_${ik}$ .or.lwork==-1_${ik}$ .or. lwork==-2_${ik}$ )
           mint = .false.
           minw = .false.
           if( tsize==-2_${ik}$ .or. lwork==-2_${ik}$ ) then
             if( tsize/=-1_${ik}$ ) mint = .true.
             if( lwork/=-1_${ik}$ ) minw = .true.
           end if
           ! determine the block size
           if( min( m, n )>0_${ik}$ ) then
             mb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGEQR ', ' ', m, n, 1_${ik}$, -1_${ik}$ )
             nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGEQR ', ' ', m, n, 2_${ik}$, -1_${ik}$ )
           else
             mb = m
             nb = 1_${ik}$
           end if
           if( mb>m .or. mb<=n ) mb = m
           if( nb>min( m, n ) .or. nb<1_${ik}$ ) nb = 1_${ik}$
           mintsz = n + 5_${ik}$
           if( mb>n .and. m>n ) then
             if( mod( m - n, mb - n )==0_${ik}$ ) then
               nblcks = ( m - n ) / ( mb - n )
             else
               nblcks = ( m - n ) / ( mb - n ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           ! determine if the workspace size satisfies minimal size
           lminws = .false.
           if( ( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) .or. lwork<nb*n ).and. ( lwork>=n ) .and. ( &
                     tsize>=mintsz ).and. ( .not.lquery ) ) then
             if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) ) then
               lminws = .true.
               nb = 1_${ik}$
               mb = m
             end if
             if( lwork<nb*n ) then
               lminws = .true.
               nb = 1_${ik}$
             end if
           end if
           if( m<0_${ik}$ ) then
             info = -1_${ik}$
           else if( n<0_${ik}$ ) then
             info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
             info = -4_${ik}$
           else if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) &
                     then
             info = -6_${ik}$
           else if( ( lwork<max( 1_${ik}$, n*nb ) ) .and. ( .not.lquery ).and. ( .not.lminws ) ) &
                     then
             info = -8_${ik}$
           end if
           if( info==0_${ik}$ ) then
             if( mint ) then
               t( 1_${ik}$ ) = mintsz
             else
               t( 1_${ik}$ ) = nb*n*nblcks + 5_${ik}$
             end if
             t( 2_${ik}$ ) = mb
             t( 3_${ik}$ ) = nb
             if( minw ) then
               work( 1_${ik}$ ) = max( 1_${ik}$, n )
             else
               work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
             end if
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'DGEQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n )==0_${ik}$ ) then
             return
           end if
           ! the qr decomposition
           if( ( m<=n ) .or. ( mb<=n ) .or. ( mb>=m ) ) then
             call stdlib${ii}$_dgeqrt( m, n, nb, a, lda, t( 6_${ik}$ ), nb, work, info )
           else
             call stdlib${ii}$_dlatsqr( m, n, mb, nb, a, lda, t( 6_${ik}$ ), nb, work,lwork, info )
           end if
           work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
           return
     end subroutine stdlib${ii}$_dgeqr

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$geqr( m, n, a, lda, t, tsize, work, lwork,info )
     !! DGEQR: computes a QR factorization of a real M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, tsize, lwork
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(lda,*)
           real(${rk}$), intent(out) :: t(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery, lminws, mint, minw
           integer(${ik}$) :: mb, nb, mintsz, nblcks
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           lquery = ( tsize==-1_${ik}$ .or. tsize==-2_${ik}$ .or.lwork==-1_${ik}$ .or. lwork==-2_${ik}$ )
           mint = .false.
           minw = .false.
           if( tsize==-2_${ik}$ .or. lwork==-2_${ik}$ ) then
             if( tsize/=-1_${ik}$ ) mint = .true.
             if( lwork/=-1_${ik}$ ) minw = .true.
           end if
           ! determine the block size
           if( min( m, n )>0_${ik}$ ) then
             mb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGEQR ', ' ', m, n, 1_${ik}$, -1_${ik}$ )
             nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGEQR ', ' ', m, n, 2_${ik}$, -1_${ik}$ )
           else
             mb = m
             nb = 1_${ik}$
           end if
           if( mb>m .or. mb<=n ) mb = m
           if( nb>min( m, n ) .or. nb<1_${ik}$ ) nb = 1_${ik}$
           mintsz = n + 5_${ik}$
           if( mb>n .and. m>n ) then
             if( mod( m - n, mb - n )==0_${ik}$ ) then
               nblcks = ( m - n ) / ( mb - n )
             else
               nblcks = ( m - n ) / ( mb - n ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           ! determine if the workspace size satisfies minimal size
           lminws = .false.
           if( ( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) .or. lwork<nb*n ).and. ( lwork>=n ) .and. ( &
                     tsize>=mintsz ).and. ( .not.lquery ) ) then
             if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) ) then
               lminws = .true.
               nb = 1_${ik}$
               mb = m
             end if
             if( lwork<nb*n ) then
               lminws = .true.
               nb = 1_${ik}$
             end if
           end if
           if( m<0_${ik}$ ) then
             info = -1_${ik}$
           else if( n<0_${ik}$ ) then
             info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
             info = -4_${ik}$
           else if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) &
                     then
             info = -6_${ik}$
           else if( ( lwork<max( 1_${ik}$, n*nb ) ) .and. ( .not.lquery ).and. ( .not.lminws ) ) &
                     then
             info = -8_${ik}$
           end if
           if( info==0_${ik}$ ) then
             if( mint ) then
               t( 1_${ik}$ ) = mintsz
             else
               t( 1_${ik}$ ) = nb*n*nblcks + 5_${ik}$
             end if
             t( 2_${ik}$ ) = mb
             t( 3_${ik}$ ) = nb
             if( minw ) then
               work( 1_${ik}$ ) = max( 1_${ik}$, n )
             else
               work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
             end if
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'DGEQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n )==0_${ik}$ ) then
             return
           end if
           ! the qr decomposition
           if( ( m<=n ) .or. ( mb<=n ) .or. ( mb>=m ) ) then
             call stdlib${ii}$_${ri}$geqrt( m, n, nb, a, lda, t( 6_${ik}$ ), nb, work, info )
           else
             call stdlib${ii}$_${ri}$latsqr( m, n, mb, nb, a, lda, t( 6_${ik}$ ), nb, work,lwork, info )
           end if
           work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
           return
     end subroutine stdlib${ii}$_${ri}$geqr

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cgeqr( m, n, a, lda, t, tsize, work, lwork,info )
     !! CGEQR computes a QR factorization of a complex M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, tsize, lwork
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           complex(sp), intent(out) :: t(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery, lminws, mint, minw
           integer(${ik}$) :: mb, nb, mintsz, nblcks
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           lquery = ( tsize==-1_${ik}$ .or. tsize==-2_${ik}$ .or.lwork==-1_${ik}$ .or. lwork==-2_${ik}$ )
           mint = .false.
           minw = .false.
           if( tsize==-2_${ik}$ .or. lwork==-2_${ik}$ ) then
             if( tsize/=-1_${ik}$ ) mint = .true.
             if( lwork/=-1_${ik}$ ) minw = .true.
           end if
           ! determine the block size
           if( min( m, n )>0_${ik}$ ) then
             mb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGEQR ', ' ', m, n, 1_${ik}$, -1_${ik}$ )
             nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGEQR ', ' ', m, n, 2_${ik}$, -1_${ik}$ )
           else
             mb = m
             nb = 1_${ik}$
           end if
           if( mb>m .or. mb<=n ) mb = m
           if( nb>min( m, n ) .or. nb<1_${ik}$ ) nb = 1_${ik}$
           mintsz = n + 5_${ik}$
           if( mb>n .and. m>n ) then
             if( mod( m - n, mb - n )==0_${ik}$ ) then
               nblcks = ( m - n ) / ( mb - n )
             else
               nblcks = ( m - n ) / ( mb - n ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           ! determine if the workspace size satisfies minimal size
           lminws = .false.
           if( ( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) .or. lwork<nb*n ).and. ( lwork>=n ) .and. ( &
                     tsize>=mintsz ).and. ( .not.lquery ) ) then
             if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) ) then
               lminws = .true.
               nb = 1_${ik}$
               mb = m
             end if
             if( lwork<nb*n ) then
               lminws = .true.
               nb = 1_${ik}$
             end if
           end if
           if( m<0_${ik}$ ) then
             info = -1_${ik}$
           else if( n<0_${ik}$ ) then
             info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
             info = -4_${ik}$
           else if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) &
                     then
             info = -6_${ik}$
           else if( ( lwork<max( 1_${ik}$, n*nb ) ) .and. ( .not.lquery ).and. ( .not.lminws ) ) &
                     then
             info = -8_${ik}$
           end if
           if( info==0_${ik}$ ) then
             if( mint ) then
               t( 1_${ik}$ ) = mintsz
             else
               t( 1_${ik}$ ) = nb*n*nblcks + 5_${ik}$
             end if
             t( 2_${ik}$ ) = mb
             t( 3_${ik}$ ) = nb
             if( minw ) then
               work( 1_${ik}$ ) = max( 1_${ik}$, n )
             else
               work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
             end if
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'CGEQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n )==0_${ik}$ ) then
             return
           end if
           ! the qr decomposition
           if( ( m<=n ) .or. ( mb<=n ) .or. ( mb>=m ) ) then
             call stdlib${ii}$_cgeqrt( m, n, nb, a, lda, t( 6_${ik}$ ), nb, work, info )
           else
             call stdlib${ii}$_clatsqr( m, n, mb, nb, a, lda, t( 6_${ik}$ ), nb, work,lwork, info )
           end if
           work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
           return
     end subroutine stdlib${ii}$_cgeqr

     pure module subroutine stdlib${ii}$_zgeqr( m, n, a, lda, t, tsize, work, lwork,info )
     !! ZGEQR computes a QR factorization of a complex M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, tsize, lwork
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           complex(dp), intent(out) :: t(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery, lminws, mint, minw
           integer(${ik}$) :: mb, nb, mintsz, nblcks
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           lquery = ( tsize==-1_${ik}$ .or. tsize==-2_${ik}$ .or.lwork==-1_${ik}$ .or. lwork==-2_${ik}$ )
           mint = .false.
           minw = .false.
           if( tsize==-2_${ik}$ .or. lwork==-2_${ik}$ ) then
             if( tsize/=-1_${ik}$ ) mint = .true.
             if( lwork/=-1_${ik}$ ) minw = .true.
           end if
           ! determine the block size
           if( min ( m, n )>0_${ik}$ ) then
             mb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGEQR ', ' ', m, n, 1_${ik}$, -1_${ik}$ )
             nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGEQR ', ' ', m, n, 2_${ik}$, -1_${ik}$ )
           else
             mb = m
             nb = 1_${ik}$
           end if
           if( mb>m .or. mb<=n ) mb = m
           if( nb>min( m, n ) .or. nb<1_${ik}$ ) nb = 1_${ik}$
           mintsz = n + 5_${ik}$
           if( mb>n .and. m>n ) then
             if( mod( m - n, mb - n )==0_${ik}$ ) then
               nblcks = ( m - n ) / ( mb - n )
             else
               nblcks = ( m - n ) / ( mb - n ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           ! determine if the workspace size satisfies minimal size
           lminws = .false.
           if( ( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) .or. lwork<nb*n ).and. ( lwork>=n ) .and. ( &
                     tsize>=mintsz ).and. ( .not.lquery ) ) then
             if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) ) then
               lminws = .true.
               nb = 1_${ik}$
               mb = m
             end if
             if( lwork<nb*n ) then
               lminws = .true.
               nb = 1_${ik}$
             end if
           end if
           if( m<0_${ik}$ ) then
             info = -1_${ik}$
           else if( n<0_${ik}$ ) then
             info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
             info = -4_${ik}$
           else if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) &
                     then
             info = -6_${ik}$
           else if( ( lwork<max( 1_${ik}$, n*nb ) ) .and. ( .not.lquery ).and. ( .not.lminws ) ) &
                     then
             info = -8_${ik}$
           end if
           if( info==0_${ik}$ ) then
             if( mint ) then
               t( 1_${ik}$ ) = mintsz
             else
               t( 1_${ik}$ ) = nb*n*nblcks + 5_${ik}$
             end if
             t( 2_${ik}$ ) = mb
             t( 3_${ik}$ ) = nb
             if( minw ) then
               work( 1_${ik}$ ) = max( 1_${ik}$, n )
             else
               work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
             end if
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'ZGEQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n )==0_${ik}$ ) then
             return
           end if
           ! the qr decomposition
           if( ( m<=n ) .or. ( mb<=n ) .or. ( mb>=m ) ) then
             call stdlib${ii}$_zgeqrt( m, n, nb, a, lda, t( 6_${ik}$ ), nb, work, info )
           else
             call stdlib${ii}$_zlatsqr( m, n, mb, nb, a, lda, t( 6_${ik}$ ), nb, work,lwork, info )
           end if
           work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
           return
     end subroutine stdlib${ii}$_zgeqr

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$geqr( m, n, a, lda, t, tsize, work, lwork,info )
     !! ZGEQR: computes a QR factorization of a complex M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, tsize, lwork
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           complex(${ck}$), intent(out) :: t(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery, lminws, mint, minw
           integer(${ik}$) :: mb, nb, mintsz, nblcks
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           lquery = ( tsize==-1_${ik}$ .or. tsize==-2_${ik}$ .or.lwork==-1_${ik}$ .or. lwork==-2_${ik}$ )
           mint = .false.
           minw = .false.
           if( tsize==-2_${ik}$ .or. lwork==-2_${ik}$ ) then
             if( tsize/=-1_${ik}$ ) mint = .true.
             if( lwork/=-1_${ik}$ ) minw = .true.
           end if
           ! determine the block size
           if( min ( m, n )>0_${ik}$ ) then
             mb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGEQR ', ' ', m, n, 1_${ik}$, -1_${ik}$ )
             nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGEQR ', ' ', m, n, 2_${ik}$, -1_${ik}$ )
           else
             mb = m
             nb = 1_${ik}$
           end if
           if( mb>m .or. mb<=n ) mb = m
           if( nb>min( m, n ) .or. nb<1_${ik}$ ) nb = 1_${ik}$
           mintsz = n + 5_${ik}$
           if( mb>n .and. m>n ) then
             if( mod( m - n, mb - n )==0_${ik}$ ) then
               nblcks = ( m - n ) / ( mb - n )
             else
               nblcks = ( m - n ) / ( mb - n ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           ! determine if the workspace size satisfies minimal size
           lminws = .false.
           if( ( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) .or. lwork<nb*n ).and. ( lwork>=n ) .and. ( &
                     tsize>=mintsz ).and. ( .not.lquery ) ) then
             if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ) ) then
               lminws = .true.
               nb = 1_${ik}$
               mb = m
             end if
             if( lwork<nb*n ) then
               lminws = .true.
               nb = 1_${ik}$
             end if
           end if
           if( m<0_${ik}$ ) then
             info = -1_${ik}$
           else if( n<0_${ik}$ ) then
             info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
             info = -4_${ik}$
           else if( tsize<max( 1_${ik}$, nb*n*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) &
                     then
             info = -6_${ik}$
           else if( ( lwork<max( 1_${ik}$, n*nb ) ) .and. ( .not.lquery ).and. ( .not.lminws ) ) &
                     then
             info = -8_${ik}$
           end if
           if( info==0_${ik}$ ) then
             if( mint ) then
               t( 1_${ik}$ ) = mintsz
             else
               t( 1_${ik}$ ) = nb*n*nblcks + 5_${ik}$
             end if
             t( 2_${ik}$ ) = mb
             t( 3_${ik}$ ) = nb
             if( minw ) then
               work( 1_${ik}$ ) = max( 1_${ik}$, n )
             else
               work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
             end if
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'ZGEQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n )==0_${ik}$ ) then
             return
           end if
           ! the qr decomposition
           if( ( m<=n ) .or. ( mb<=n ) .or. ( mb>=m ) ) then
             call stdlib${ii}$_${ci}$geqrt( m, n, nb, a, lda, t( 6_${ik}$ ), nb, work, info )
           else
             call stdlib${ii}$_${ci}$latsqr( m, n, mb, nb, a, lda, t( 6_${ik}$ ), nb, work,lwork, info )
           end if
           work( 1_${ik}$ ) = max( 1_${ik}$, nb*n )
           return
     end subroutine stdlib${ii}$_${ci}$geqr

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sgemqr( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, &
     !! SGEMQR overwrites the general real M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'T':      Q**T * C       C * Q**T
     !! where Q is a real orthogonal matrix defined as the product
     !! of blocked elementary reflectors computed by tall skinny
     !! QR factorization (SGEQR)
               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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, k, tsize, lwork, ldc
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*), t(*)
           real(sp), intent(inout) :: c(ldc,*)
           real(sp), intent(out) :: work(*)
       ! =====================================================================
           ! Local Scalars 
           logical(lk) :: left, right, tran, notran, lquery
           integer(${ik}$) :: mb, nb, lw, nblcks, mn
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           lquery  = lwork==-1_${ik}$
           notran  = stdlib_lsame( trans, 'N' )
           tran    = stdlib_lsame( trans, 'T' )
           left    = stdlib_lsame( side, 'L' )
           right   = stdlib_lsame( side, 'R' )
           mb = int( t( 2_${ik}$ ),KIND=${ik}$)
           nb = int( t( 3_${ik}$ ),KIND=${ik}$)
           if( left ) then
             lw = n * nb
             mn = m
           else
             lw = mb * nb
             mn = n
           end if
           if( ( mb>k ) .and. ( mn>k ) ) then
             if( mod( mn - k, mb - k )==0_${ik}$ ) then
               nblcks = ( mn - k ) / ( mb - k )
             else
               nblcks = ( mn - k ) / ( mb - k ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           info = 0_${ik}$
           if( .not.left .and. .not.right ) then
             info = -1_${ik}$
           else if( .not.tran .and. .not.notran ) then
             info = -2_${ik}$
           else if( m<0_${ik}$ ) then
             info = -3_${ik}$
           else if( n<0_${ik}$ ) then
             info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>mn ) then
             info = -5_${ik}$
           else if( lda<max( 1_${ik}$, mn ) ) then
             info = -7_${ik}$
           else if( tsize<5_${ik}$ ) then
             info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
             info = -11_${ik}$
           else if( ( lwork<max( 1_${ik}$, lw ) ) .and. ( .not.lquery ) ) then
             info = -13_${ik}$
           end if
           if( info==0_${ik}$ ) then
             work( 1_${ik}$ ) = lw
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'SGEMQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n, k )==0_${ik}$ ) then
             return
           end if
           if( ( left .and. m<=k ) .or. ( right .and. n<=k ).or. ( mb<=k ) .or. ( mb>=max( m, n, &
                     k ) ) ) then
             call stdlib${ii}$_sgemqrt( side, trans, m, n, k, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, info &
                       )
           else
             call stdlib${ii}$_slamtsqr( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, &
                       lwork, info )
           end if
           work( 1_${ik}$ ) = lw
           return
     end subroutine stdlib${ii}$_sgemqr

     pure module subroutine stdlib${ii}$_dgemqr( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, &
     !! DGEMQR overwrites the general real M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'T':      Q**T * C       C * Q**T
     !! where Q is a real orthogonal matrix defined as the product
     !! of blocked elementary reflectors computed by tall skinny
     !! QR factorization (DGEQR)
               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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, k, tsize, lwork, ldc
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*), t(*)
           real(dp), intent(inout) :: c(ldc,*)
           real(dp), intent(out) :: work(*)
       ! =====================================================================
           ! Local Scalars 
           logical(lk) :: left, right, tran, notran, lquery
           integer(${ik}$) :: mb, nb, lw, nblcks, mn
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           lquery  = lwork==-1_${ik}$
           notran  = stdlib_lsame( trans, 'N' )
           tran    = stdlib_lsame( trans, 'T' )
           left    = stdlib_lsame( side, 'L' )
           right   = stdlib_lsame( side, 'R' )
           mb = int( t( 2_${ik}$ ),KIND=${ik}$)
           nb = int( t( 3_${ik}$ ),KIND=${ik}$)
           if( left ) then
             lw = n * nb
             mn = m
           else
             lw = mb * nb
             mn = n
           end if
           if( ( mb>k ) .and. ( mn>k ) ) then
             if( mod( mn - k, mb - k )==0_${ik}$ ) then
               nblcks = ( mn - k ) / ( mb - k )
             else
               nblcks = ( mn - k ) / ( mb - k ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           info = 0_${ik}$
           if( .not.left .and. .not.right ) then
             info = -1_${ik}$
           else if( .not.tran .and. .not.notran ) then
             info = -2_${ik}$
           else if( m<0_${ik}$ ) then
             info = -3_${ik}$
           else if( n<0_${ik}$ ) then
             info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>mn ) then
             info = -5_${ik}$
           else if( lda<max( 1_${ik}$, mn ) ) then
             info = -7_${ik}$
           else if( tsize<5_${ik}$ ) then
             info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
             info = -11_${ik}$
           else if( ( lwork<max( 1_${ik}$, lw ) ) .and. ( .not.lquery ) ) then
             info = -13_${ik}$
           end if
           if( info==0_${ik}$ ) then
             work( 1_${ik}$ ) = lw
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'DGEMQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n, k )==0_${ik}$ ) then
             return
           end if
           if( ( left .and. m<=k ) .or. ( right .and. n<=k ).or. ( mb<=k ) .or. ( mb>=max( m, n, &
                     k ) ) ) then
             call stdlib${ii}$_dgemqrt( side, trans, m, n, k, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, info &
                       )
           else
             call stdlib${ii}$_dlamtsqr( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, &
                       lwork, info )
           end if
           work( 1_${ik}$ ) = lw
           return
     end subroutine stdlib${ii}$_dgemqr

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$gemqr( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, &
     !! DGEMQR: overwrites the general real M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'T':      Q**T * C       C * Q**T
     !! where Q is a real orthogonal matrix defined as the product
     !! of blocked elementary reflectors computed by tall skinny
     !! QR factorization (DGEQR)
               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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, k, tsize, lwork, ldc
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*), t(*)
           real(${rk}$), intent(inout) :: c(ldc,*)
           real(${rk}$), intent(out) :: work(*)
       ! =====================================================================
           ! Local Scalars 
           logical(lk) :: left, right, tran, notran, lquery
           integer(${ik}$) :: mb, nb, lw, nblcks, mn
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           lquery  = lwork==-1_${ik}$
           notran  = stdlib_lsame( trans, 'N' )
           tran    = stdlib_lsame( trans, 'T' )
           left    = stdlib_lsame( side, 'L' )
           right   = stdlib_lsame( side, 'R' )
           mb = int( t( 2_${ik}$ ),KIND=${ik}$)
           nb = int( t( 3_${ik}$ ),KIND=${ik}$)
           if( left ) then
             lw = n * nb
             mn = m
           else
             lw = mb * nb
             mn = n
           end if
           if( ( mb>k ) .and. ( mn>k ) ) then
             if( mod( mn - k, mb - k )==0_${ik}$ ) then
               nblcks = ( mn - k ) / ( mb - k )
             else
               nblcks = ( mn - k ) / ( mb - k ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           info = 0_${ik}$
           if( .not.left .and. .not.right ) then
             info = -1_${ik}$
           else if( .not.tran .and. .not.notran ) then
             info = -2_${ik}$
           else if( m<0_${ik}$ ) then
             info = -3_${ik}$
           else if( n<0_${ik}$ ) then
             info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>mn ) then
             info = -5_${ik}$
           else if( lda<max( 1_${ik}$, mn ) ) then
             info = -7_${ik}$
           else if( tsize<5_${ik}$ ) then
             info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
             info = -11_${ik}$
           else if( ( lwork<max( 1_${ik}$, lw ) ) .and. ( .not.lquery ) ) then
             info = -13_${ik}$
           end if
           if( info==0_${ik}$ ) then
             work( 1_${ik}$ ) = lw
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'DGEMQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n, k )==0_${ik}$ ) then
             return
           end if
           if( ( left .and. m<=k ) .or. ( right .and. n<=k ).or. ( mb<=k ) .or. ( mb>=max( m, n, &
                     k ) ) ) then
             call stdlib${ii}$_${ri}$gemqrt( side, trans, m, n, k, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, info &
                       )
           else
             call stdlib${ii}$_${ri}$lamtsqr( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, &
                       lwork, info )
           end if
           work( 1_${ik}$ ) = lw
           return
     end subroutine stdlib${ii}$_${ri}$gemqr

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cgemqr( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, &
     !! CGEMQR overwrites the general real M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'T':      Q**H * C       C * Q**H
     !! where Q is a complex unitary matrix defined as the product
     !! of blocked elementary reflectors computed by tall skinny
     !! QR factorization (CGEQR)
               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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, k, tsize, lwork, ldc
           ! Array Arguments 
           complex(sp), intent(in) :: a(lda,*), t(*)
           complex(sp), intent(inout) :: c(ldc,*)
           complex(sp), intent(out) :: work(*)
       ! =====================================================================
           ! Local Scalars 
           logical(lk) :: left, right, tran, notran, lquery
           integer(${ik}$) :: mb, nb, lw, nblcks, mn
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           lquery  = lwork==-1_${ik}$
           notran  = stdlib_lsame( trans, 'N' )
           tran    = stdlib_lsame( trans, 'C' )
           left    = stdlib_lsame( side, 'L' )
           right   = stdlib_lsame( side, 'R' )
           mb = int( t( 2_${ik}$ ),KIND=${ik}$)
           nb = int( t( 3_${ik}$ ),KIND=${ik}$)
           if( left ) then
             lw = n * nb
             mn = m
           else
             lw = mb * nb
             mn = n
           end if
           if( ( mb>k ) .and. ( mn>k ) ) then
             if( mod( mn - k, mb - k )==0_${ik}$ ) then
               nblcks = ( mn - k ) / ( mb - k )
             else
               nblcks = ( mn - k ) / ( mb - k ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           info = 0_${ik}$
           if( .not.left .and. .not.right ) then
             info = -1_${ik}$
           else if( .not.tran .and. .not.notran ) then
             info = -2_${ik}$
           else if( m<0_${ik}$ ) then
             info = -3_${ik}$
           else if( n<0_${ik}$ ) then
             info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>mn ) then
             info = -5_${ik}$
           else if( lda<max( 1_${ik}$, mn ) ) then
             info = -7_${ik}$
           else if( tsize<5_${ik}$ ) then
             info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
             info = -11_${ik}$
           else if( ( lwork<max( 1_${ik}$, lw ) ) .and. ( .not.lquery ) ) then
             info = -13_${ik}$
           end if
           if( info==0_${ik}$ ) then
             work( 1_${ik}$ ) = lw
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'CGEMQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n, k )==0_${ik}$ ) then
             return
           end if
           if( ( left .and. m<=k ) .or. ( right .and. n<=k ).or. ( mb<=k ) .or. ( mb>=max( m, n, &
                     k ) ) ) then
             call stdlib${ii}$_cgemqrt( side, trans, m, n, k, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, info &
                       )
           else
             call stdlib${ii}$_clamtsqr( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, &
                       lwork, info )
           end if
           work( 1_${ik}$ ) = lw
           return
     end subroutine stdlib${ii}$_cgemqr

     pure module subroutine stdlib${ii}$_zgemqr( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, &
     !! ZGEMQR overwrites the general real M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'T':      Q**H * C       C * Q**H
     !! where Q is a complex unitary matrix defined as the product
     !! of blocked elementary reflectors computed by tall skinny
     !! QR factorization (ZGEQR)
               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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, k, tsize, lwork, ldc
           ! Array Arguments 
           complex(dp), intent(in) :: a(lda,*), t(*)
           complex(dp), intent(inout) :: c(ldc,*)
           complex(dp), intent(out) :: work(*)
       ! =====================================================================
           ! Local Scalars 
           logical(lk) :: left, right, tran, notran, lquery
           integer(${ik}$) :: mb, nb, lw, nblcks, mn
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           lquery  = lwork==-1_${ik}$
           notran  = stdlib_lsame( trans, 'N' )
           tran    = stdlib_lsame( trans, 'C' )
           left    = stdlib_lsame( side, 'L' )
           right   = stdlib_lsame( side, 'R' )
           mb = int( t( 2_${ik}$ ),KIND=${ik}$)
           nb = int( t( 3_${ik}$ ),KIND=${ik}$)
           if( left ) then
             lw = n * nb
             mn = m
           else
             lw = mb * nb
             mn = n
           end if
           if( ( mb>k ) .and. ( mn>k ) ) then
             if( mod( mn - k, mb - k )==0_${ik}$ ) then
               nblcks = ( mn - k ) / ( mb - k )
             else
               nblcks = ( mn - k ) / ( mb - k ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           info = 0_${ik}$
           if( .not.left .and. .not.right ) then
             info = -1_${ik}$
           else if( .not.tran .and. .not.notran ) then
             info = -2_${ik}$
           else if( m<0_${ik}$ ) then
             info = -3_${ik}$
           else if( n<0_${ik}$ ) then
             info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>mn ) then
             info = -5_${ik}$
           else if( lda<max( 1_${ik}$, mn ) ) then
             info = -7_${ik}$
           else if( tsize<5_${ik}$ ) then
             info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
             info = -11_${ik}$
           else if( ( lwork<max( 1_${ik}$, lw ) ) .and. ( .not.lquery ) ) then
             info = -13_${ik}$
           end if
           if( info==0_${ik}$ ) then
             work( 1_${ik}$ ) = lw
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'ZGEMQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n, k )==0_${ik}$ ) then
             return
           end if
           if( ( left .and. m<=k ) .or. ( right .and. n<=k ).or. ( mb<=k ) .or. ( mb>=max( m, n, &
                     k ) ) ) then
             call stdlib${ii}$_zgemqrt( side, trans, m, n, k, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, info &
                       )
           else
             call stdlib${ii}$_zlamtsqr( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, &
                       lwork, info )
           end if
           work( 1_${ik}$ ) = lw
           return
     end subroutine stdlib${ii}$_zgemqr

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$gemqr( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, &
     !! ZGEMQR: overwrites the general real M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'T':      Q**H * C       C * Q**H
     !! where Q is a complex unitary matrix defined as the product
     !! of blocked elementary reflectors computed by tall skinny
     !! QR factorization (ZGEQR)
               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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n, k, tsize, lwork, ldc
           ! Array Arguments 
           complex(${ck}$), intent(in) :: a(lda,*), t(*)
           complex(${ck}$), intent(inout) :: c(ldc,*)
           complex(${ck}$), intent(out) :: work(*)
       ! =====================================================================
           ! Local Scalars 
           logical(lk) :: left, right, tran, notran, lquery
           integer(${ik}$) :: mb, nb, lw, nblcks, mn
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           lquery  = lwork==-1_${ik}$
           notran  = stdlib_lsame( trans, 'N' )
           tran    = stdlib_lsame( trans, 'C' )
           left    = stdlib_lsame( side, 'L' )
           right   = stdlib_lsame( side, 'R' )
           mb = int( t( 2_${ik}$ ),KIND=${ik}$)
           nb = int( t( 3_${ik}$ ),KIND=${ik}$)
           if( left ) then
             lw = n * nb
             mn = m
           else
             lw = mb * nb
             mn = n
           end if
           if( ( mb>k ) .and. ( mn>k ) ) then
             if( mod( mn - k, mb - k )==0_${ik}$ ) then
               nblcks = ( mn - k ) / ( mb - k )
             else
               nblcks = ( mn - k ) / ( mb - k ) + 1_${ik}$
             end if
           else
             nblcks = 1_${ik}$
           end if
           info = 0_${ik}$
           if( .not.left .and. .not.right ) then
             info = -1_${ik}$
           else if( .not.tran .and. .not.notran ) then
             info = -2_${ik}$
           else if( m<0_${ik}$ ) then
             info = -3_${ik}$
           else if( n<0_${ik}$ ) then
             info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>mn ) then
             info = -5_${ik}$
           else if( lda<max( 1_${ik}$, mn ) ) then
             info = -7_${ik}$
           else if( tsize<5_${ik}$ ) then
             info = -9_${ik}$
           else if( ldc<max( 1_${ik}$, m ) ) then
             info = -11_${ik}$
           else if( ( lwork<max( 1_${ik}$, lw ) ) .and. ( .not.lquery ) ) then
             info = -13_${ik}$
           end if
           if( info==0_${ik}$ ) then
             work( 1_${ik}$ ) = lw
           end if
           if( info/=0_${ik}$ ) then
             call stdlib${ii}$_xerbla( 'ZGEMQR', -info )
             return
           else if( lquery ) then
             return
           end if
           ! quick return if possible
           if( min( m, n, k )==0_${ik}$ ) then
             return
           end if
           if( ( left .and. m<=k ) .or. ( right .and. n<=k ).or. ( mb<=k ) .or. ( mb>=max( m, n, &
                     k ) ) ) then
             call stdlib${ii}$_${ci}$gemqrt( side, trans, m, n, k, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, info &
                       )
           else
             call stdlib${ii}$_${ci}$lamtsqr( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),nb, c, ldc, work, &
                       lwork, info )
           end if
           work( 1_${ik}$ ) = lw
           return
     end subroutine stdlib${ii}$_${ci}$gemqr

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sgeqrf( m, n, a, lda, tau, work, lwork, info )
     !! SGEQRF computes a QR factorization of a real M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, lwork, m, n
           ! Array Arguments 
           real(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, k, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           k = min( m, n )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ )
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           else if( .not.lquery ) then
              if( lwork<=0_${ik}$ .or. ( m>0_${ik}$ .and. lwork<max( 1_${ik}$, n ) ) )info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SGEQRF', -info )
              return
           else if( lquery ) then
              if( k==0_${ik}$ ) then
                 lwkopt = 1_${ik}$
              else
                 lwkopt = n*nb
              end if
              work( 1_${ik}$ ) = lwkopt
              return
           end if
           ! quick return if possible
           if( k==0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'SGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'SGEQRF', ' ', m, n, -1_${ik}$,-1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code initially
              do i = 1, k - nx, nb
                 ib = min( k-i+1, nb )
                 ! compute the qr factorization of the current block
                 ! a(i:m,i:i+ib-1)
                 call stdlib${ii}$_sgeqr2( m-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_slarft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h**t to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_slarfb( 'LEFT', 'TRANSPOSE', 'FORWARD','COLUMNWISE', m-i+1, n-i-&
                    ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 ), ldwork &
                              )
                 end if
              end do
           else
              i = 1_${ik}$
           end if
           ! use unblocked code to factor the last or only block.
           if( i<=k )call stdlib${ii}$_sgeqr2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo )
                     
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_sgeqrf

     pure module subroutine stdlib${ii}$_dgeqrf( m, n, a, lda, tau, work, lwork, info )
     !! DGEQRF computes a QR factorization of a real M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, lwork, m, n
           ! Array Arguments 
           real(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, k, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           k = min( m, n )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ )
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           else if( .not.lquery ) then
              if( lwork<=0_${ik}$ .or. ( m>0_${ik}$ .and. lwork<max( 1_${ik}$, n ) ) )info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DGEQRF', -info )
              return
           else if( lquery ) then
              if( k==0_${ik}$ ) then
                 lwkopt = 1_${ik}$
              else
                 lwkopt = n*nb
              end if
              work( 1_${ik}$ ) = lwkopt
              return
           end if
           ! quick return if possible
           if( k==0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'DGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'DGEQRF', ' ', m, n, -1_${ik}$,-1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code initially
              do i = 1, k - nx, nb
                 ib = min( k-i+1, nb )
                 ! compute the qr factorization of the current block
                 ! a(i:m,i:i+ib-1)
                 call stdlib${ii}$_dgeqr2( m-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_dlarft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h**t to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_dlarfb( 'LEFT', 'TRANSPOSE', 'FORWARD','COLUMNWISE', m-i+1, n-i-&
                    ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 ), ldwork &
                              )
                 end if
              end do
           else
              i = 1_${ik}$
           end if
           ! use unblocked code to factor the last or only block.
           if( i<=k )call stdlib${ii}$_dgeqr2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo )
                     
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_dgeqrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$geqrf( m, n, a, lda, tau, work, lwork, info )
     !! DGEQRF: computes a QR factorization of a real M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, lwork, m, n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(lda,*)
           real(${rk}$), intent(out) :: tau(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, k, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           k = min( m, n )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ )
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           else if( .not.lquery ) then
              if( lwork<=0_${ik}$ .or. ( m>0_${ik}$ .and. lwork<max( 1_${ik}$, n ) ) )info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DGEQRF', -info )
              return
           else if( lquery ) then
              if( k==0_${ik}$ ) then
                 lwkopt = 1_${ik}$
              else
                 lwkopt = n*nb
              end if
              work( 1_${ik}$ ) = lwkopt
              return
           end if
           ! quick return if possible
           if( k==0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'DGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'DGEQRF', ' ', m, n, -1_${ik}$,-1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code initially
              do i = 1, k - nx, nb
                 ib = min( k-i+1, nb )
                 ! compute the qr factorization of the current block
                 ! a(i:m,i:i+ib-1)
                 call stdlib${ii}$_${ri}$geqr2( m-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_${ri}$larft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h**t to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_${ri}$larfb( 'LEFT', 'TRANSPOSE', 'FORWARD','COLUMNWISE', m-i+1, n-i-&
                    ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 ), ldwork &
                              )
                 end if
              end do
           else
              i = 1_${ik}$
           end if
           ! use unblocked code to factor the last or only block.
           if( i<=k )call stdlib${ii}$_${ri}$geqr2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo )
                     
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_${ri}$geqrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cgeqrf( m, n, a, lda, tau, work, lwork, info )
     !! CGEQRF computes a QR factorization of a complex M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, lwork, m, n
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           complex(sp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, k, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           k = min( m, n )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ )
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           else if( .not.lquery ) then
              if( lwork<=0_${ik}$ .or. ( m>0_${ik}$ .and. lwork<max( 1_${ik}$, n ) ) )info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CGEQRF', -info )
              return
           else if( lquery ) then
              if( k==0_${ik}$ ) then
                 lwkopt = 1_${ik}$
              else
                 lwkopt = n*nb
              end if
              work( 1_${ik}$ ) = lwkopt
              return
           end if
           ! quick return if possible
           if( k==0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'CGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'CGEQRF', ' ', m, n, -1_${ik}$,-1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code initially
              do i = 1, k - nx, nb
                 ib = min( k-i+1, nb )
                 ! compute the qr factorization of the current block
                 ! a(i:m,i:i+ib-1)
                 call stdlib${ii}$_cgeqr2( m-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_clarft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h**h to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_clarfb( 'LEFT', 'CONJUGATE TRANSPOSE', 'FORWARD','COLUMNWISE', m-&
                    i+1, n-i-ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 )&
                              , ldwork )
                 end if
              end do
           else
              i = 1_${ik}$
           end if
           ! use unblocked code to factor the last or only block.
           if( i<=k )call stdlib${ii}$_cgeqr2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo )
                     
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_cgeqrf

     pure module subroutine stdlib${ii}$_zgeqrf( m, n, a, lda, tau, work, lwork, info )
     !! ZGEQRF computes a QR factorization of a complex M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, lwork, m, n
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           complex(dp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, k, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           k = min( m, n )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ )
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           else if( .not.lquery ) then
              if( lwork<=0_${ik}$ .or. ( m>0_${ik}$ .and. lwork<max( 1_${ik}$, n ) ) )info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZGEQRF', -info )
              return
           else if( lquery ) then
              if( k==0_${ik}$ ) then
                 lwkopt = 1_${ik}$
              else
                 lwkopt = n*nb
              end if
              work( 1_${ik}$ ) = lwkopt
              return
           end if
           ! quick return if possible
           if( k==0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'ZGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'ZGEQRF', ' ', m, n, -1_${ik}$,-1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code initially
              do i = 1, k - nx, nb
                 ib = min( k-i+1, nb )
                 ! compute the qr factorization of the current block
                 ! a(i:m,i:i+ib-1)
                 call stdlib${ii}$_zgeqr2( m-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_zlarft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h**h to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_zlarfb( 'LEFT', 'CONJUGATE TRANSPOSE', 'FORWARD','COLUMNWISE', m-&
                    i+1, n-i-ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 )&
                              , ldwork )
                 end if
              end do
           else
              i = 1_${ik}$
           end if
           ! use unblocked code to factor the last or only block.
           if( i<=k )call stdlib${ii}$_zgeqr2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo )
                     
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_zgeqrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$geqrf( m, n, a, lda, tau, work, lwork, info )
     !! ZGEQRF: computes a QR factorization of a complex M-by-N matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a M-by-M orthogonal matrix;
     !! R is an upper-triangular N-by-N matrix;
     !! 0 is a (M-N)-by-N zero matrix, if M > N.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, lwork, m, n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           complex(${ck}$), intent(out) :: tau(*), work(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, k, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           k = min( m, n )
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ )
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           else if( .not.lquery ) then
              if( lwork<=0_${ik}$ .or. ( m>0_${ik}$ .and. lwork<max( 1_${ik}$, n ) ) )info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZGEQRF', -info )
              return
           else if( lquery ) then
              if( k==0_${ik}$ ) then
                 lwkopt = 1_${ik}$
              else
                 lwkopt = n*nb
              end if
              work( 1_${ik}$ ) = lwkopt
              return
           end if
           ! quick return if possible
           if( k==0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'ZGEQRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'ZGEQRF', ' ', m, n, -1_${ik}$,-1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code initially
              do i = 1, k - nx, nb
                 ib = min( k-i+1, nb )
                 ! compute the qr factorization of the current block
                 ! a(i:m,i:i+ib-1)
                 call stdlib${ii}$_${ci}$geqr2( m-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_${ci}$larft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h**h to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_${ci}$larfb( 'LEFT', 'CONJUGATE TRANSPOSE', 'FORWARD','COLUMNWISE', m-&
                    i+1, n-i-ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 )&
                              , ldwork )
                 end if
              end do
           else
              i = 1_${ik}$
           end if
           ! use unblocked code to factor the last or only block.
           if( i<=k )call stdlib${ii}$_${ci}$geqr2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo )
                     
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_${ci}$geqrf

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sgeqr2( m, n, a, lda, tau, work, info )
     !! SGEQR2 computes a QR factorization of a real m-by-n matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a m-by-m orthogonal matrix;
     !! R is an upper-triangular n-by-n matrix;
     !! 0 is a (m-n)-by-n zero matrix, if m > n.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n
           ! Array Arguments 
           real(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, k
           real(sp) :: aii
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SGEQR2', -info )
              return
           end if
           k = min( m, n )
           do i = 1, k
              ! generate elementary reflector h(i) to annihilate a(i+1:m,i)
              call stdlib${ii}$_slarfg( m-i+1, a( i, i ), a( min( i+1, m ), i ), 1_${ik}$,tau( i ) )
              if( i<n ) then
                 ! apply h(i) to a(i:m,i+1:n) from the left
                 aii = a( i, i )
                 a( i, i ) = one
                 call stdlib${ii}$_slarf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$, tau( i ),a( i, i+1 ), lda, &
                           work )
                 a( i, i ) = aii
              end if
           end do
           return
     end subroutine stdlib${ii}$_sgeqr2

     pure module subroutine stdlib${ii}$_dgeqr2( m, n, a, lda, tau, work, info )
     !! DGEQR2 computes a QR factorization of a real m-by-n matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a m-by-m orthogonal matrix;
     !! R is an upper-triangular n-by-n matrix;
     !! 0 is a (m-n)-by-n zero matrix, if m > n.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n
           ! Array Arguments 
           real(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, k
           real(dp) :: aii
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DGEQR2', -info )
              return
           end if
           k = min( m, n )
           do i = 1, k
              ! generate elementary reflector h(i) to annihilate a(i+1:m,i)
              call stdlib${ii}$_dlarfg( m-i+1, a( i, i ), a( min( i+1, m ), i ), 1_${ik}$,tau( i ) )
              if( i<n ) then
                 ! apply h(i) to a(i:m,i+1:n) from the left
                 aii = a( i, i )
                 a( i, i ) = one
                 call stdlib${ii}$_dlarf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$, tau( i ),a( i, i+1 ), lda, &
                           work )
                 a( i, i ) = aii
              end if
           end do
           return
     end subroutine stdlib${ii}$_dgeqr2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$geqr2( m, n, a, lda, tau, work, info )
     !! DGEQR2: computes a QR factorization of a real m-by-n matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a m-by-m orthogonal matrix;
     !! R is an upper-triangular n-by-n matrix;
     !! 0 is a (m-n)-by-n zero matrix, if m > n.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(lda,*)
           real(${rk}$), intent(out) :: tau(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, k
           real(${rk}$) :: aii
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DGEQR2', -info )
              return
           end if
           k = min( m, n )
           do i = 1, k
              ! generate elementary reflector h(i) to annihilate a(i+1:m,i)
              call stdlib${ii}$_${ri}$larfg( m-i+1, a( i, i ), a( min( i+1, m ), i ), 1_${ik}$,tau( i ) )
              if( i<n ) then
                 ! apply h(i) to a(i:m,i+1:n) from the left
                 aii = a( i, i )
                 a( i, i ) = one
                 call stdlib${ii}$_${ri}$larf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$, tau( i ),a( i, i+1 ), lda, &
                           work )
                 a( i, i ) = aii
              end if
           end do
           return
     end subroutine stdlib${ii}$_${ri}$geqr2

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cgeqr2( m, n, a, lda, tau, work, info )
     !! CGEQR2 computes a QR factorization of a complex m-by-n matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a m-by-m orthogonal matrix;
     !! R is an upper-triangular n-by-n matrix;
     !! 0 is a (m-n)-by-n zero matrix, if m > n.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           complex(sp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, k
           complex(sp) :: alpha
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CGEQR2', -info )
              return
           end if
           k = min( m, n )
           do i = 1, k
              ! generate elementary reflector h(i) to annihilate a(i+1:m,i)
              call stdlib${ii}$_clarfg( m-i+1, a( i, i ), a( min( i+1, m ), i ), 1_${ik}$,tau( i ) )
              if( i<n ) then
                 ! apply h(i)**h to a(i:m,i+1:n) from the left
                 alpha = a( i, i )
                 a( i, i ) = cone
                 call stdlib${ii}$_clarf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$,conjg( tau( i ) ), a( i, i+1 &
                           ), lda, work )
                 a( i, i ) = alpha
              end if
           end do
           return
     end subroutine stdlib${ii}$_cgeqr2

     pure module subroutine stdlib${ii}$_zgeqr2( m, n, a, lda, tau, work, info )
     !! ZGEQR2 computes a QR factorization of a complex m-by-n matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a m-by-m orthogonal matrix;
     !! R is an upper-triangular n-by-n matrix;
     !! 0 is a (m-n)-by-n zero matrix, if m > n.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           complex(dp), intent(out) :: tau(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, k
           complex(dp) :: alpha
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZGEQR2', -info )
              return
           end if
           k = min( m, n )
           do i = 1, k
              ! generate elementary reflector h(i) to annihilate a(i+1:m,i)
              call stdlib${ii}$_zlarfg( m-i+1, a( i, i ), a( min( i+1, m ), i ), 1_${ik}$,tau( i ) )
              if( i<n ) then
                 ! apply h(i)**h to a(i:m,i+1:n) from the left
                 alpha = a( i, i )
                 a( i, i ) = cone
                 call stdlib${ii}$_zlarf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$,conjg( tau( i ) ), a( i, i+1 &
                           ), lda, work )
                 a( i, i ) = alpha
              end if
           end do
           return
     end subroutine stdlib${ii}$_zgeqr2

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$geqr2( m, n, a, lda, tau, work, info )
     !! ZGEQR2: computes a QR factorization of a complex m-by-n matrix A:
     !! A = Q * ( R ),
     !! ( 0 )
     !! where:
     !! Q is a m-by-m orthogonal matrix;
     !! R is an upper-triangular n-by-n matrix;
     !! 0 is a (m-n)-by-n zero matrix, if m > n.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: lda, m, n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           complex(${ck}$), intent(out) :: tau(*), work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, k
           complex(${ck}$) :: alpha
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZGEQR2', -info )
              return
           end if
           k = min( m, n )
           do i = 1, k
              ! generate elementary reflector h(i) to annihilate a(i+1:m,i)
              call stdlib${ii}$_${ci}$larfg( m-i+1, a( i, i ), a( min( i+1, m ), i ), 1_${ik}$,tau( i ) )
              if( i<n ) then
                 ! apply h(i)**h to a(i:m,i+1:n) from the left
                 alpha = a( i, i )
                 a( i, i ) = cone
                 call stdlib${ii}$_${ci}$larf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$,conjg( tau( i ) ), a( i, i+1 &
                           ), lda, work )
                 a( i, i ) = alpha
              end if
           end do
           return
     end subroutine stdlib${ii}$_${ci}$geqr2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_cungqr( m, n, k, a, lda, tau, work, lwork, info )
     !! CUNGQR generates an M-by-N complex matrix Q with orthonormal columns,
     !! which is defined as the first N columns of a product of K elementary
     !! reflectors of order M
     !! Q  =  H(1) H(2) . . . H(k)
     !! as returned by CGEQRF.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: k, lda, lwork, m, n
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           complex(sp), intent(in) :: tau(*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, j, ki, kk, l, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNGQR', ' ', m, n, k, -1_${ik}$ )
           lwkopt = max( 1_${ik}$, n )*nb
           work( 1_${ik}$ ) = lwkopt
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ .or. n>m ) then
              info = -2_${ik}$
           else if( k<0_${ik}$ .or. k>n ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -5_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CUNGQR', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'CUNGQR', ' ', m, n, k, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'CUNGQR', ' ', m, n, k, -1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code after the last block.
              ! the first kk columns are handled by the block method.
              ki = ( ( k-nx-1 ) / nb )*nb
              kk = min( k, ki+nb )
              ! set a(1:kk,kk+1:n) to czero.
              do j = kk + 1, n
                 do i = 1, kk
                    a( i, j ) = czero
                 end do
              end do
           else
              kk = 0_${ik}$
           end if
           ! use unblocked code for the last or only block.
           if( kk<n )call stdlib${ii}$_cung2r( m-kk, n-kk, k-kk, a( kk+1, kk+1 ), lda,tau( kk+1 ), work,&
                      iinfo )
           if( kk>0_${ik}$ ) then
              ! use blocked code
              do i = ki + 1, 1, -nb
                 ib = min( nb, k-i+1 )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_clarft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_clarfb( 'LEFT', 'NO TRANSPOSE', 'FORWARD','COLUMNWISE', m-i+1, n-&
                    i-ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 ), &
                              ldwork )
                 end if
                 ! apply h to rows i:m of current block
                 call stdlib${ii}$_cung2r( m-i+1, ib, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 ! set rows 1:i-1 of current block to czero
                 do j = i, i + ib - 1
                    do l = 1, i - 1
                       a( l, j ) = czero
                    end do
                 end do
              end do
           end if
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_cungqr

     pure module subroutine stdlib${ii}$_zungqr( m, n, k, a, lda, tau, work, lwork, info )
     !! ZUNGQR generates an M-by-N complex matrix Q with orthonormal columns,
     !! which is defined as the first N columns of a product of K elementary
     !! reflectors of order M
     !! Q  =  H(1) H(2) . . . H(k)
     !! as returned by ZGEQRF.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: k, lda, lwork, m, n
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           complex(dp), intent(in) :: tau(*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, j, ki, kk, l, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNGQR', ' ', m, n, k, -1_${ik}$ )
           lwkopt = max( 1_${ik}$, n )*nb
           work( 1_${ik}$ ) = lwkopt
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ .or. n>m ) then
              info = -2_${ik}$
           else if( k<0_${ik}$ .or. k>n ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -5_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZUNGQR', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'ZUNGQR', ' ', m, n, k, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'ZUNGQR', ' ', m, n, k, -1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code after the last block.
              ! the first kk columns are handled by the block method.
              ki = ( ( k-nx-1 ) / nb )*nb
              kk = min( k, ki+nb )
              ! set a(1:kk,kk+1:n) to czero.
              do j = kk + 1, n
                 do i = 1, kk
                    a( i, j ) = czero
                 end do
              end do
           else
              kk = 0_${ik}$
           end if
           ! use unblocked code for the last or only block.
           if( kk<n )call stdlib${ii}$_zung2r( m-kk, n-kk, k-kk, a( kk+1, kk+1 ), lda,tau( kk+1 ), work,&
                      iinfo )
           if( kk>0_${ik}$ ) then
              ! use blocked code
              do i = ki + 1, 1, -nb
                 ib = min( nb, k-i+1 )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_zlarft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_zlarfb( 'LEFT', 'NO TRANSPOSE', 'FORWARD','COLUMNWISE', m-i+1, n-&
                    i-ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 ), &
                              ldwork )
                 end if
                 ! apply h to rows i:m of current block
                 call stdlib${ii}$_zung2r( m-i+1, ib, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 ! set rows 1:i-1 of current block to czero
                 do j = i, i + ib - 1
                    do l = 1, i - 1
                       a( l, j ) = czero
                    end do
                 end do
              end do
           end if
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_zungqr

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ungqr( m, n, k, a, lda, tau, work, lwork, info )
     !! ZUNGQR: generates an M-by-N complex matrix Q with orthonormal columns,
     !! which is defined as the first N columns of a product of K elementary
     !! reflectors of order M
     !! Q  =  H(1) H(2) . . . H(k)
     !! as returned by ZGEQRF.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: k, lda, lwork, m, n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           complex(${ck}$), intent(in) :: tau(*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lquery
           integer(${ik}$) :: i, ib, iinfo, iws, j, ki, kk, l, ldwork, lwkopt, nb, nbmin, nx
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNGQR', ' ', m, n, k, -1_${ik}$ )
           lwkopt = max( 1_${ik}$, n )*nb
           work( 1_${ik}$ ) = lwkopt
           lquery = ( lwork==-1_${ik}$ )
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ .or. n>m ) then
              info = -2_${ik}$
           else if( k<0_${ik}$ .or. k>n ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -5_${ik}$
           else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZUNGQR', -info )
              return
           else if( lquery ) then
              return
           end if
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              work( 1_${ik}$ ) = 1_${ik}$
              return
           end if
           nbmin = 2_${ik}$
           nx = 0_${ik}$
           iws = n
           if( nb>1_${ik}$ .and. nb<k ) then
              ! determine when to cross over from blocked to unblocked code.
              nx = max( 0_${ik}$, stdlib${ii}$_ilaenv( 3_${ik}$, 'ZUNGQR', ' ', m, n, k, -1_${ik}$ ) )
              if( nx<k ) then
                 ! determine if workspace is large enough for blocked code.
                 ldwork = n
                 iws = ldwork*nb
                 if( lwork<iws ) then
                    ! not enough workspace to use optimal nb:  reduce nb and
                    ! determine the minimum value of nb.
                    nb = lwork / ldwork
                    nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'ZUNGQR', ' ', m, n, k, -1_${ik}$ ) )
                 end if
              end if
           end if
           if( nb>=nbmin .and. nb<k .and. nx<k ) then
              ! use blocked code after the last block.
              ! the first kk columns are handled by the block method.
              ki = ( ( k-nx-1 ) / nb )*nb
              kk = min( k, ki+nb )
              ! set a(1:kk,kk+1:n) to czero.
              do j = kk + 1, n
                 do i = 1, kk
                    a( i, j ) = czero
                 end do
              end do
           else
              kk = 0_${ik}$
           end if
           ! use unblocked code for the last or only block.
           if( kk<n )call stdlib${ii}$_${ci}$ung2r( m-kk, n-kk, k-kk, a( kk+1, kk+1 ), lda,tau( kk+1 ), work,&
                      iinfo )
           if( kk>0_${ik}$ ) then
              ! use blocked code
              do i = ki + 1, 1, -nb
                 ib = min( nb, k-i+1 )
                 if( i+ib<=n ) then
                    ! form the triangular factor of the block reflector
                    ! h = h(i) h(i+1) . . . h(i+ib-1)
                    call stdlib${ii}$_${ci}$larft( 'FORWARD', 'COLUMNWISE', m-i+1, ib,a( i, i ), lda, tau( i &
                              ), work, ldwork )
                    ! apply h to a(i:m,i+ib:n) from the left
                    call stdlib${ii}$_${ci}$larfb( 'LEFT', 'NO TRANSPOSE', 'FORWARD','COLUMNWISE', m-i+1, n-&
                    i-ib+1, ib,a( i, i ), lda, work, ldwork, a( i, i+ib ),lda, work( ib+1 ), &
                              ldwork )
                 end if
                 ! apply h to rows i:m of current block
                 call stdlib${ii}$_${ci}$ung2r( m-i+1, ib, ib, a( i, i ), lda, tau( i ), work,iinfo )
                 ! set rows 1:i-1 of current block to czero
                 do j = i, i + ib - 1
                    do l = 1, i - 1
                       a( l, j ) = czero
                    end do
                 end do
              end do
           end if
           work( 1_${ik}$ ) = iws
           return
     end subroutine stdlib${ii}$_${ci}$ungqr

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_cung2r( m, n, k, a, lda, tau, work, info )
     !! CUNG2R generates an m by n complex matrix Q with orthonormal columns,
     !! which is defined as the first n columns of a product of k elementary
     !! reflectors of order m
     !! Q  =  H(1) H(2) . . . H(k)
     !! as returned by CGEQRF.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: k, lda, m, n
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           complex(sp), intent(in) :: tau(*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, l
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ .or. n>m ) then
              info = -2_${ik}$
           else if( k<0_${ik}$ .or. k>n ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CUNG2R', -info )
              return
           end if
           ! quick return if possible
           if( n<=0 )return
           ! initialise columns k+1:n to columns of the unit matrix
           do j = k + 1, n
              do l = 1, m
                 a( l, j ) = czero
              end do
              a( j, j ) = cone
           end do
           do i = k, 1, -1
              ! apply h(i) to a(i:m,i:n) from the left
              if( i<n ) then
                 a( i, i ) = cone
                 call stdlib${ii}$_clarf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$, tau( i ),a( i, i+1 ), lda, &
                           work )
              end if
              if( i<m )call stdlib${ii}$_cscal( m-i, -tau( i ), a( i+1, i ), 1_${ik}$ )
              a( i, i ) = cone - tau( i )
              ! set a(1:i-1,i) to czero
              do l = 1, i - 1
                 a( l, i ) = czero
              end do
           end do
           return
     end subroutine stdlib${ii}$_cung2r

     pure module subroutine stdlib${ii}$_zung2r( m, n, k, a, lda, tau, work, info )
     !! ZUNG2R generates an m by n complex matrix Q with orthonormal columns,
     !! which is defined as the first n columns of a product of k elementary
     !! reflectors of order m
     !! Q  =  H(1) H(2) . . . H(k)
     !! as returned by ZGEQRF.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: k, lda, m, n
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           complex(dp), intent(in) :: tau(*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, l
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ .or. n>m ) then
              info = -2_${ik}$
           else if( k<0_${ik}$ .or. k>n ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZUNG2R', -info )
              return
           end if
           ! quick return if possible
           if( n<=0 )return
           ! initialise columns k+1:n to columns of the unit matrix
           do j = k + 1, n
              do l = 1, m
                 a( l, j ) = czero
              end do
              a( j, j ) = cone
           end do
           do i = k, 1, -1
              ! apply h(i) to a(i:m,i:n) from the left
              if( i<n ) then
                 a( i, i ) = cone
                 call stdlib${ii}$_zlarf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$, tau( i ),a( i, i+1 ), lda, &
                           work )
              end if
              if( i<m )call stdlib${ii}$_zscal( m-i, -tau( i ), a( i+1, i ), 1_${ik}$ )
              a( i, i ) = cone - tau( i )
              ! set a(1:i-1,i) to czero
              do l = 1, i - 1
                 a( l, i ) = czero
              end do
           end do
           return
     end subroutine stdlib${ii}$_zung2r

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ung2r( m, n, k, a, lda, tau, work, info )
     !! ZUNG2R: generates an m by n complex matrix Q with orthonormal columns,
     !! which is defined as the first n columns of a product of k elementary
     !! reflectors of order m
     !! Q  =  H(1) H(2) . . . H(k)
     !! as returned by ZGEQRF.
        ! -- 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(out) :: info
           integer(${ik}$), intent(in) :: k, lda, m, n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           complex(${ck}$), intent(in) :: tau(*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, l
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           if( m<0_${ik}$ ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ .or. n>m ) then
              info = -2_${ik}$
           else if( k<0_${ik}$ .or. k>n ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, m ) ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZUNG2R', -info )
              return
           end if
           ! quick return if possible
           if( n<=0 )return
           ! initialise columns k+1:n to columns of the unit matrix
           do j = k + 1, n
              do l = 1, m
                 a( l, j ) = czero
              end do
              a( j, j ) = cone
           end do
           do i = k, 1, -1
              ! apply h(i) to a(i:m,i:n) from the left
              if( i<n ) then
                 a( i, i ) = cone
                 call stdlib${ii}$_${ci}$larf( 'LEFT', m-i+1, n-i, a( i, i ), 1_${ik}$, tau( i ),a( i, i+1 ), lda, &
                           work )
              end if
              if( i<m )call stdlib${ii}$_${ci}$scal( m-i, -tau( i ), a( i+1, i ), 1_${ik}$ )
              a( i, i ) = cone - tau( i )
              ! set a(1:i-1,i) to czero
              do l = 1, i - 1
                 a( l, i ) = czero
              end do
           end do
           return
     end subroutine stdlib${ii}$_${ci}$ung2r

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_cunmqr( side, trans, m, n, k, a, lda, tau, c, ldc,work, lwork, info )
     !! CUNMQR overwrites the general complex M-by-N matrix C with
     !! SIDE = 'L'     SIDE = 'R'
     !! TRANS = 'N':      Q * C          C * Q
     !! TRANS = 'C':      Q**H * C       C * Q**H
     !! where Q is a complex unitary matrix defined as the product of k
     !! elementary reflectors
     !! Q = H(1) H(2) . . . H(k)
     !! as returned by CGEQRF. Q is of order M if SIDE = 'L' and of order N
     !! if SIDE = 'R'.
               
        ! -- 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) :: side, trans
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: k, lda, ldc, lwork, m, n
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*), c(ldc,*)
           complex(sp), intent(in) :: tau(*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 64_${ik}$
           integer(${ik}$), parameter :: ldt = nbmax+1
           integer(${ik}$), parameter :: tsize = ldt*nbmax
           
           ! Local Scalars 
           logical(lk) :: left, lquery, notran
           integer(${ik}$) :: i, i1, i2, i3, ib, ic, iinfo, iwt, jc, ldwork, lwkopt, mi, nb, nbmin, &
                     ni, nq, nw
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments
           info = 0_${ik}$
           left = stdlib_lsame( side, 'L' )
           notran = stdlib_lsame( trans, 'N' )
           lquery = ( lwork==-1_${ik}$ )
           ! nq is the order of q and nw is the minimum dimension of work
           if( left ) then
              nq = m
              nw = max( 1_${ik}$, n )
           else
              nq = n
              nw = max( 1_${ik}$, m )
           end if
           if( .not.left .and. .not.stdlib_lsame( side, 'R' ) ) then
              info = -1_${ik}$
           else if( .not.notran .and. .not.stdlib_lsame( trans, 'C' ) ) then
              info = -2_${ik}$
           else if( m<0_${ik}$ ) then
              info = -3_${ik}$
           else if( n<0_${ik}$ ) then
              info = -4_${ik}$
           else if( k<0_${ik}$ .or. k>nq ) then
              info = -5_${ik}$
           else if( lda