#:include "common.fypp" submodule(stdlib_lapack_orthogonal_factors) stdlib_lapack_orthogonal_factors_ql implicit none contains #:for ik,it,ii in LINALG_INT_KINDS_TYPES pure module subroutine stdlib${ii}$_sgelq( m, n, a, lda, t, tsize, work, lwork,info ) !! SGELQ computes an LQ factorization of a real M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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, lwmin, lwopt, lwreq ! 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}$, 'SGELQ ', ' ', m, n, 1_${ik}$, -1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGELQ ', ' ', m, n, 2_${ik}$, -1_${ik}$ ) else mb = 1_${ik}$ nb = n end if if( mb>min( m, n ) .or. mb<1_${ik}$ ) mb = 1_${ik}$ if( nb>n .or. nb<=m ) nb = n mintsz = m + 5_${ik}$ if ( nb>m .and. n>m ) then if( mod( n - m, nb - m )==0_${ik}$ ) then nblcks = ( n - m ) / ( nb - m ) else nblcks = ( n - m ) / ( nb - m ) + 1_${ik}$ end if else nblcks = 1_${ik}$ end if ! determine if the workspace size satisfies minimal size if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwmin = max( 1_${ik}$, n ) lwopt = max( 1_${ik}$, mb*n ) else lwmin = max( 1_${ik}$, m ) lwopt = max( 1_${ik}$, mb*m ) end if lminws = .false. if( ( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) .or. lwork<lwopt ).and. ( lwork>=lwmin ) .and. ( & tsize>=mintsz ).and. ( .not.lquery ) ) then if( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) ) then lminws = .true. mb = 1_${ik}$ nb = n end if if( lwork<lwopt ) then lminws = .true. mb = 1_${ik}$ end if end if if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwreq = max( 1_${ik}$, mb*n ) else lwreq = max( 1_${ik}$, mb*m ) 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}$, mb*m*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) & then info = -6_${ik}$ else if( ( lwork<lwreq ) .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}$ ) = mb*m*nblcks + 5_${ik}$ end if t( 2_${ik}$ ) = mb t( 3_${ik}$ ) = nb if( minw ) then work( 1_${ik}$ ) = lwmin else work( 1_${ik}$ ) = lwreq end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGELQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( min( m, n )==0_${ik}$ ) then return end if ! the lq decomposition if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then call stdlib${ii}$_sgelqt( m, n, mb, a, lda, t( 6_${ik}$ ), mb, work, info ) else call stdlib${ii}$_slaswlq( m, n, mb, nb, a, lda, t( 6_${ik}$ ), mb, work,lwork, info ) end if work( 1_${ik}$ ) = lwreq return end subroutine stdlib${ii}$_sgelq pure module subroutine stdlib${ii}$_dgelq( m, n, a, lda, t, tsize, work, lwork,info ) !! DGELQ computes an LQ factorization of a real M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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, lwmin, lwopt, lwreq ! 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}$, 'DGELQ ', ' ', m, n, 1_${ik}$, -1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGELQ ', ' ', m, n, 2_${ik}$, -1_${ik}$ ) else mb = 1_${ik}$ nb = n end if if( mb>min( m, n ) .or. mb<1_${ik}$ ) mb = 1_${ik}$ if( nb>n .or. nb<=m ) nb = n mintsz = m + 5_${ik}$ if ( nb>m .and. n>m ) then if( mod( n - m, nb - m )==0_${ik}$ ) then nblcks = ( n - m ) / ( nb - m ) else nblcks = ( n - m ) / ( nb - m ) + 1_${ik}$ end if else nblcks = 1_${ik}$ end if ! determine if the workspace size satisfies minimal size if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwmin = max( 1_${ik}$, n ) lwopt = max( 1_${ik}$, mb*n ) else lwmin = max( 1_${ik}$, m ) lwopt = max( 1_${ik}$, mb*m ) end if lminws = .false. if( ( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) .or. lwork<lwopt ).and. ( lwork>=lwmin ) .and. ( & tsize>=mintsz ).and. ( .not.lquery ) ) then if( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) ) then lminws = .true. mb = 1_${ik}$ nb = n end if if( lwork<lwopt ) then lminws = .true. mb = 1_${ik}$ end if end if if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwreq = max( 1_${ik}$, mb*n ) else lwreq = max( 1_${ik}$, mb*m ) 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}$, mb*m*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) & then info = -6_${ik}$ else if( ( lwork<lwreq ) .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}$ ) = mb*m*nblcks + 5_${ik}$ end if t( 2_${ik}$ ) = mb t( 3_${ik}$ ) = nb if( minw ) then work( 1_${ik}$ ) = lwmin else work( 1_${ik}$ ) = lwreq end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGELQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( min( m, n )==0_${ik}$ ) then return end if ! the lq decomposition if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then call stdlib${ii}$_dgelqt( m, n, mb, a, lda, t( 6_${ik}$ ), mb, work, info ) else call stdlib${ii}$_dlaswlq( m, n, mb, nb, a, lda, t( 6_${ik}$ ), mb, work,lwork, info ) end if work( 1_${ik}$ ) = lwreq return end subroutine stdlib${ii}$_dgelq #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gelq( m, n, a, lda, t, tsize, work, lwork,info ) !! DGELQ: computes an LQ factorization of a real M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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, lwmin, lwopt, lwreq ! 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}$, 'DGELQ ', ' ', m, n, 1_${ik}$, -1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGELQ ', ' ', m, n, 2_${ik}$, -1_${ik}$ ) else mb = 1_${ik}$ nb = n end if if( mb>min( m, n ) .or. mb<1_${ik}$ ) mb = 1_${ik}$ if( nb>n .or. nb<=m ) nb = n mintsz = m + 5_${ik}$ if ( nb>m .and. n>m ) then if( mod( n - m, nb - m )==0_${ik}$ ) then nblcks = ( n - m ) / ( nb - m ) else nblcks = ( n - m ) / ( nb - m ) + 1_${ik}$ end if else nblcks = 1_${ik}$ end if ! determine if the workspace size satisfies minimal size if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwmin = max( 1_${ik}$, n ) lwopt = max( 1_${ik}$, mb*n ) else lwmin = max( 1_${ik}$, m ) lwopt = max( 1_${ik}$, mb*m ) end if lminws = .false. if( ( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) .or. lwork<lwopt ).and. ( lwork>=lwmin ) .and. ( & tsize>=mintsz ).and. ( .not.lquery ) ) then if( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) ) then lminws = .true. mb = 1_${ik}$ nb = n end if if( lwork<lwopt ) then lminws = .true. mb = 1_${ik}$ end if end if if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwreq = max( 1_${ik}$, mb*n ) else lwreq = max( 1_${ik}$, mb*m ) 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}$, mb*m*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) & then info = -6_${ik}$ else if( ( lwork<lwreq ) .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}$ ) = mb*m*nblcks + 5_${ik}$ end if t( 2_${ik}$ ) = mb t( 3_${ik}$ ) = nb if( minw ) then work( 1_${ik}$ ) = lwmin else work( 1_${ik}$ ) = lwreq end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGELQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( min( m, n )==0_${ik}$ ) then return end if ! the lq decomposition if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then call stdlib${ii}$_${ri}$gelqt( m, n, mb, a, lda, t( 6_${ik}$ ), mb, work, info ) else call stdlib${ii}$_${ri}$laswlq( m, n, mb, nb, a, lda, t( 6_${ik}$ ), mb, work,lwork, info ) end if work( 1_${ik}$ ) = lwreq return end subroutine stdlib${ii}$_${ri}$gelq #:endif #:endfor pure module subroutine stdlib${ii}$_cgelq( m, n, a, lda, t, tsize, work, lwork,info ) !! CGELQ computes an LQ factorization of a complex M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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, lwmin, lwopt, lwreq ! 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}$, 'CGELQ ', ' ', m, n, 1_${ik}$, -1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGELQ ', ' ', m, n, 2_${ik}$, -1_${ik}$ ) else mb = 1_${ik}$ nb = n end if if( mb>min( m, n ) .or. mb<1_${ik}$ ) mb = 1_${ik}$ if( nb>n .or. nb<=m ) nb = n mintsz = m + 5_${ik}$ if( nb>m .and. n>m ) then if( mod( n - m, nb - m )==0_${ik}$ ) then nblcks = ( n - m ) / ( nb - m ) else nblcks = ( n - m ) / ( nb - m ) + 1_${ik}$ end if else nblcks = 1_${ik}$ end if ! determine if the workspace size satisfies minimal size if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwmin = max( 1_${ik}$, n ) lwopt = max( 1_${ik}$, mb*n ) else lwmin = max( 1_${ik}$, m ) lwopt = max( 1_${ik}$, mb*m ) end if lminws = .false. if( ( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) .or. lwork<lwopt ).and. ( lwork>=lwmin ) .and. ( & tsize>=mintsz ).and. ( .not.lquery ) ) then if( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) ) then lminws = .true. mb = 1_${ik}$ nb = n end if if( lwork<lwopt ) then lminws = .true. mb = 1_${ik}$ end if end if if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwreq = max( 1_${ik}$, mb*n ) else lwreq = max( 1_${ik}$, mb*m ) 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}$, mb*m*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) & then info = -6_${ik}$ else if( ( lwork<lwreq ) .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}$ ) = mb*m*nblcks + 5_${ik}$ end if t( 2_${ik}$ ) = mb t( 3_${ik}$ ) = nb if( minw ) then work( 1_${ik}$ ) = lwmin else work( 1_${ik}$ ) = lwreq end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGELQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( min( m, n )==0_${ik}$ ) then return end if ! the lq decomposition if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then call stdlib${ii}$_cgelqt( m, n, mb, a, lda, t( 6_${ik}$ ), mb, work, info ) else call stdlib${ii}$_claswlq( m, n, mb, nb, a, lda, t( 6_${ik}$ ), mb, work,lwork, info ) end if work( 1_${ik}$ ) = lwreq return end subroutine stdlib${ii}$_cgelq pure module subroutine stdlib${ii}$_zgelq( m, n, a, lda, t, tsize, work, lwork,info ) !! ZGELQ computes an LQ factorization of a complex M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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, lwmin, lwopt, lwreq ! 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}$, 'ZGELQ ', ' ', m, n, 1_${ik}$, -1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGELQ ', ' ', m, n, 2_${ik}$, -1_${ik}$ ) else mb = 1_${ik}$ nb = n end if if( mb>min( m, n ) .or. mb<1_${ik}$ ) mb = 1_${ik}$ if( nb>n .or. nb<=m ) nb = n mintsz = m + 5_${ik}$ if ( nb>m .and. n>m ) then if( mod( n - m, nb - m )==0_${ik}$ ) then nblcks = ( n - m ) / ( nb - m ) else nblcks = ( n - m ) / ( nb - m ) + 1_${ik}$ end if else nblcks = 1_${ik}$ end if ! determine if the workspace size satisfies minimal size if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwmin = max( 1_${ik}$, n ) lwopt = max( 1_${ik}$, mb*n ) else lwmin = max( 1_${ik}$, m ) lwopt = max( 1_${ik}$, mb*m ) end if lminws = .false. if( ( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) .or. lwork<lwopt ).and. ( lwork>=lwmin ) .and. ( & tsize>=mintsz ).and. ( .not.lquery ) ) then if( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) ) then lminws = .true. mb = 1_${ik}$ nb = n end if if( lwork<lwopt ) then lminws = .true. mb = 1_${ik}$ end if end if if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwreq = max( 1_${ik}$, mb*n ) else lwreq = max( 1_${ik}$, mb*m ) 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}$, mb*m*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) & then info = -6_${ik}$ else if( ( lwork<lwreq ) .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}$ ) = mb*m*nblcks + 5_${ik}$ end if t( 2_${ik}$ ) = mb t( 3_${ik}$ ) = nb if( minw ) then work( 1_${ik}$ ) = lwmin else work( 1_${ik}$ ) = lwreq end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGELQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( min( m, n )==0_${ik}$ ) then return end if ! the lq decomposition if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then call stdlib${ii}$_zgelqt( m, n, mb, a, lda, t( 6_${ik}$ ), mb, work, info ) else call stdlib${ii}$_zlaswlq( m, n, mb, nb, a, lda, t( 6_${ik}$ ), mb, work,lwork, info ) end if work( 1_${ik}$ ) = lwreq return end subroutine stdlib${ii}$_zgelq #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gelq( m, n, a, lda, t, tsize, work, lwork,info ) !! ZGELQ: computes an LQ factorization of a complex M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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, lwmin, lwopt, lwreq ! 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}$, 'ZGELQ ', ' ', m, n, 1_${ik}$, -1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGELQ ', ' ', m, n, 2_${ik}$, -1_${ik}$ ) else mb = 1_${ik}$ nb = n end if if( mb>min( m, n ) .or. mb<1_${ik}$ ) mb = 1_${ik}$ if( nb>n .or. nb<=m ) nb = n mintsz = m + 5_${ik}$ if ( nb>m .and. n>m ) then if( mod( n - m, nb - m )==0_${ik}$ ) then nblcks = ( n - m ) / ( nb - m ) else nblcks = ( n - m ) / ( nb - m ) + 1_${ik}$ end if else nblcks = 1_${ik}$ end if ! determine if the workspace size satisfies minimal size if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwmin = max( 1_${ik}$, n ) lwopt = max( 1_${ik}$, mb*n ) else lwmin = max( 1_${ik}$, m ) lwopt = max( 1_${ik}$, mb*m ) end if lminws = .false. if( ( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) .or. lwork<lwopt ).and. ( lwork>=lwmin ) .and. ( & tsize>=mintsz ).and. ( .not.lquery ) ) then if( tsize<max( 1_${ik}$, mb*m*nblcks + 5_${ik}$ ) ) then lminws = .true. mb = 1_${ik}$ nb = n end if if( lwork<lwopt ) then lminws = .true. mb = 1_${ik}$ end if end if if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then lwreq = max( 1_${ik}$, mb*n ) else lwreq = max( 1_${ik}$, mb*m ) 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}$, mb*m*nblcks + 5_${ik}$ ).and. ( .not.lquery ) .and. ( .not.lminws ) ) & then info = -6_${ik}$ else if( ( lwork<lwreq ) .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}$ ) = mb*m*nblcks + 5_${ik}$ end if t( 2_${ik}$ ) = mb t( 3_${ik}$ ) = nb if( minw ) then work( 1_${ik}$ ) = lwmin else work( 1_${ik}$ ) = lwreq end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGELQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( min( m, n )==0_${ik}$ ) then return end if ! the lq decomposition if( ( n<=m ) .or. ( nb<=m ) .or. ( nb>=n ) ) then call stdlib${ii}$_${ci}$gelqt( m, n, mb, a, lda, t( 6_${ik}$ ), mb, work, info ) else call stdlib${ii}$_${ci}$laswlq( m, n, mb, nb, a, lda, t( 6_${ik}$ ), mb, work,lwork, info ) end if work( 1_${ik}$ ) = lwreq return end subroutine stdlib${ii}$_${ci}$gelq #:endif #:endfor pure module subroutine stdlib${ii}$_sgemlq( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, & !! SGEMLQ 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 short wide LQ !! factorization (SGELQ) 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 * mb mn = m else lw = m * mb mn = n end if if( ( nb>k ) .and. ( mn>k ) ) then if( mod( mn - k, nb - k ) == 0_${ik}$ ) then nblcks = ( mn - k ) / ( nb - k ) else nblcks = ( mn - k ) / ( nb - 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}$, k ) ) 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}$ ) = real( lw,KIND=sp) end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGEMLQ', -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. ( nb<=k ) .or. ( nb>=max( m, n, & k ) ) ) then call stdlib${ii}$_sgemlqt( side, trans, m, n, k, mb, a, lda,t( 6_${ik}$ ), mb, c, ldc, work, info & ) else call stdlib${ii}$_slamswlq( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),mb, c, ldc, work, & lwork, info ) end if work( 1_${ik}$ ) = real( lw,KIND=sp) return end subroutine stdlib${ii}$_sgemlq pure module subroutine stdlib${ii}$_dgemlq( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, & !! DGEMLQ 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 short wide LQ !! factorization (DGELQ) 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 * mb mn = m else lw = m * mb mn = n end if if( ( nb>k ) .and. ( mn>k ) ) then if( mod( mn - k, nb - k ) == 0_${ik}$ ) then nblcks = ( mn - k ) / ( nb - k ) else nblcks = ( mn - k ) / ( nb - 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}$, k ) ) 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( 'DGEMLQ', -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. ( nb<=k ) .or. ( nb>=max( m, n, & k ) ) ) then call stdlib${ii}$_dgemlqt( side, trans, m, n, k, mb, a, lda,t( 6_${ik}$ ), mb, c, ldc, work, info & ) else call stdlib${ii}$_dlamswlq( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),mb, c, ldc, work, & lwork, info ) end if work( 1_${ik}$ ) = lw return end subroutine stdlib${ii}$_dgemlq #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gemlq( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, & !! DGEMLQ: 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 short wide LQ !! factorization (DGELQ) 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 * mb mn = m else lw = m * mb mn = n end if if( ( nb>k ) .and. ( mn>k ) ) then if( mod( mn - k, nb - k ) == 0_${ik}$ ) then nblcks = ( mn - k ) / ( nb - k ) else nblcks = ( mn - k ) / ( nb - 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}$, k ) ) 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( 'DGEMLQ', -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. ( nb<=k ) .or. ( nb>=max( m, n, & k ) ) ) then call stdlib${ii}$_${ri}$gemlqt( side, trans, m, n, k, mb, a, lda,t( 6_${ik}$ ), mb, c, ldc, work, info & ) else call stdlib${ii}$_${ri}$lamswlq( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),mb, c, ldc, work, & lwork, info ) end if work( 1_${ik}$ ) = lw return end subroutine stdlib${ii}$_${ri}$gemlq #:endif #:endfor pure module subroutine stdlib${ii}$_cgemlq( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, & !! CGEMLQ overwrites the general real 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 blocked elementary reflectors computed by short wide !! LQ factorization (CGELQ) 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 * mb mn = m else lw = m * mb mn = n end if if( ( nb>k ) .and. ( mn>k ) ) then if( mod( mn - k, nb - k ) == 0_${ik}$ ) then nblcks = ( mn - k ) / ( nb - k ) else nblcks = ( mn - k ) / ( nb - 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}$, k ) ) 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}$ ) = real( lw,KIND=sp) end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGEMLQ', -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. ( nb<=k ) .or. ( nb>=max( m, n, & k ) ) ) then call stdlib${ii}$_cgemlqt( side, trans, m, n, k, mb, a, lda,t( 6_${ik}$ ), mb, c, ldc, work, info & ) else call stdlib${ii}$_clamswlq( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),mb, c, ldc, work, & lwork, info ) end if work( 1_${ik}$ ) = real( lw,KIND=sp) return end subroutine stdlib${ii}$_cgemlq pure module subroutine stdlib${ii}$_zgemlq( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, & !! ZGEMLQ overwrites the general real 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 blocked elementary reflectors computed by short wide !! LQ factorization (ZGELQ) 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 * mb mn = m else lw = m * mb mn = n end if if( ( nb>k ) .and. ( mn>k ) ) then if( mod( mn - k, nb - k ) == 0_${ik}$ ) then nblcks = ( mn - k ) / ( nb - k ) else nblcks = ( mn - k ) / ( nb - 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}$, k ) ) 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( 'ZGEMLQ', -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. ( nb<=k ) .or. ( nb>=max( m, n, & k ) ) ) then call stdlib${ii}$_zgemlqt( side, trans, m, n, k, mb, a, lda,t( 6_${ik}$ ), mb, c, ldc, work, info & ) else call stdlib${ii}$_zlamswlq( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),mb, c, ldc, work, & lwork, info ) end if work( 1_${ik}$ ) = lw return end subroutine stdlib${ii}$_zgemlq #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gemlq( side, trans, m, n, k, a, lda, t, tsize,c, ldc, work, lwork, & !! ZGEMLQ: overwrites the general real 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 blocked elementary reflectors computed by short wide !! LQ factorization (ZGELQ) 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 * mb mn = m else lw = m * mb mn = n end if if( ( nb>k ) .and. ( mn>k ) ) then if( mod( mn - k, nb - k ) == 0_${ik}$ ) then nblcks = ( mn - k ) / ( nb - k ) else nblcks = ( mn - k ) / ( nb - 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}$, k ) ) 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( 'ZGEMLQ', -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. ( nb<=k ) .or. ( nb>=max( m, n, & k ) ) ) then call stdlib${ii}$_${ci}$gemlqt( side, trans, m, n, k, mb, a, lda,t( 6_${ik}$ ), mb, c, ldc, work, info & ) else call stdlib${ii}$_${ci}$lamswlq( side, trans, m, n, k, mb, nb, a, lda, t( 6_${ik}$ ),mb, c, ldc, work, & lwork, info ) end if work( 1_${ik}$ ) = lw return end subroutine stdlib${ii}$_${ci}$gemlq #:endif #:endfor pure module subroutine stdlib${ii}$_sgelqf( m, n, a, lda, tau, work, lwork, info ) !! SGELQF computes an LQ factorization of a real M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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 info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) lwkopt = m*nb work( 1_${ik}$ ) = lwkopt 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( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGELQF', -info ) return else if( lquery ) then return end if ! quick return if possible k = min( m, n ) if( k==0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'SGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'SGELQF', ' ', 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 lq factorization of the current block ! a(i:i+ib-1,i:n) call stdlib${ii}$_sgelq2( ib, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) if( i+ib<=m ) then ! form the triangular factor of the block reflector ! h = h(i) h(i+1) . . . h(i+ib-1) call stdlib${ii}$_slarft( 'FORWARD', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h to a(i+ib:m,i:n) from the right call stdlib${ii}$_slarfb( 'RIGHT', 'NO TRANSPOSE', 'FORWARD','ROWWISE', m-i-ib+1, n-& i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), 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}$_sgelq2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_sgelqf pure module subroutine stdlib${ii}$_dgelqf( m, n, a, lda, tau, work, lwork, info ) !! DGELQF computes an LQ factorization of a real M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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 info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) lwkopt = m*nb work( 1_${ik}$ ) = lwkopt 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( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGELQF', -info ) return else if( lquery ) then return end if ! quick return if possible k = min( m, n ) if( k==0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'DGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'DGELQF', ' ', 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 lq factorization of the current block ! a(i:i+ib-1,i:n) call stdlib${ii}$_dgelq2( ib, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) if( i+ib<=m ) then ! form the triangular factor of the block reflector ! h = h(i) h(i+1) . . . h(i+ib-1) call stdlib${ii}$_dlarft( 'FORWARD', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h to a(i+ib:m,i:n) from the right call stdlib${ii}$_dlarfb( 'RIGHT', 'NO TRANSPOSE', 'FORWARD','ROWWISE', m-i-ib+1, n-& i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), 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}$_dgelq2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_dgelqf #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gelqf( m, n, a, lda, tau, work, lwork, info ) !! DGELQF: computes an LQ factorization of a real M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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 info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) lwkopt = m*nb work( 1_${ik}$ ) = lwkopt 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( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGELQF', -info ) return else if( lquery ) then return end if ! quick return if possible k = min( m, n ) if( k==0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'DGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'DGELQF', ' ', 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 lq factorization of the current block ! a(i:i+ib-1,i:n) call stdlib${ii}$_${ri}$gelq2( ib, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) if( i+ib<=m ) 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', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h to a(i+ib:m,i:n) from the right call stdlib${ii}$_${ri}$larfb( 'RIGHT', 'NO TRANSPOSE', 'FORWARD','ROWWISE', m-i-ib+1, n-& i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), 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}$gelq2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_${ri}$gelqf #:endif #:endfor pure module subroutine stdlib${ii}$_cgelqf( m, n, a, lda, tau, work, lwork, info ) !! CGELQF computes an LQ factorization of a complex M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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 info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) lwkopt = m*nb work( 1_${ik}$ ) = lwkopt 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( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGELQF', -info ) return else if( lquery ) then return end if ! quick return if possible k = min( m, n ) if( k==0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'CGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'CGELQF', ' ', 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 lq factorization of the current block ! a(i:i+ib-1,i:n) call stdlib${ii}$_cgelq2( ib, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) if( i+ib<=m ) then ! form the triangular factor of the block reflector ! h = h(i) h(i+1) . . . h(i+ib-1) call stdlib${ii}$_clarft( 'FORWARD', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h to a(i+ib:m,i:n) from the right call stdlib${ii}$_clarfb( 'RIGHT', 'NO TRANSPOSE', 'FORWARD','ROWWISE', m-i-ib+1, n-& i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), 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}$_cgelq2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_cgelqf pure module subroutine stdlib${ii}$_zgelqf( m, n, a, lda, tau, work, lwork, info ) !! ZGELQF computes an LQ factorization of a complex M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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 info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) lwkopt = m*nb work( 1_${ik}$ ) = lwkopt 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( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGELQF', -info ) return else if( lquery ) then return end if ! quick return if possible k = min( m, n ) if( k==0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'ZGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'ZGELQF', ' ', 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 lq factorization of the current block ! a(i:i+ib-1,i:n) call stdlib${ii}$_zgelq2( ib, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) if( i+ib<=m ) then ! form the triangular factor of the block reflector ! h = h(i) h(i+1) . . . h(i+ib-1) call stdlib${ii}$_zlarft( 'FORWARD', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h to a(i+ib:m,i:n) from the right call stdlib${ii}$_zlarfb( 'RIGHT', 'NO TRANSPOSE', 'FORWARD','ROWWISE', m-i-ib+1, n-& i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), 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}$_zgelq2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_zgelqf #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gelqf( m, n, a, lda, tau, work, lwork, info ) !! ZGELQF: computes an LQ factorization of a complex M-by-N matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a N-by-N orthogonal matrix; !! L is a lower-triangular M-by-M matrix; !! 0 is a M-by-(N-M) 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 info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) lwkopt = m*nb work( 1_${ik}$ ) = lwkopt 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( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGELQF', -info ) return else if( lquery ) then return end if ! quick return if possible k = min( m, n ) if( k==0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'ZGELQF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'ZGELQF', ' ', 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 lq factorization of the current block ! a(i:i+ib-1,i:n) call stdlib${ii}$_${ci}$gelq2( ib, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) if( i+ib<=m ) 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', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h to a(i+ib:m,i:n) from the right call stdlib${ii}$_${ci}$larfb( 'RIGHT', 'NO TRANSPOSE', 'FORWARD','ROWWISE', m-i-ib+1, n-& i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), 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}$gelq2( m-i+1, n-i+1, a( i, i ), lda, tau( i ), work,iinfo ) work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_${ci}$gelqf #:endif #:endfor pure module subroutine stdlib${ii}$_sgelq2( m, n, a, lda, tau, work, info ) !! SGELQ2 computes an LQ factorization of a real m-by-n matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a n-by-n orthogonal matrix; !! L is a lower-triangular m-by-m matrix; !! 0 is a m-by-(n-m) 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( 'SGELQ2', -info ) return end if k = min( m, n ) do i = 1, k ! generate elementary reflector h(i) to annihilate a(i,i+1:n) call stdlib${ii}$_slarfg( n-i+1, a( i, i ), a( i, min( i+1, n ) ), lda,tau( i ) ) if( i<m ) then ! apply h(i) to a(i+1:m,i:n) from the right aii = a( i, i ) a( i, i ) = one call stdlib${ii}$_slarf( 'RIGHT', m-i, n-i+1, a( i, i ), lda, tau( i ),a( i+1, i ), & lda, work ) a( i, i ) = aii end if end do return end subroutine stdlib${ii}$_sgelq2 pure module subroutine stdlib${ii}$_dgelq2( m, n, a, lda, tau, work, info ) !! DGELQ2 computes an LQ factorization of a real m-by-n matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a n-by-n orthogonal matrix; !! L is a lower-triangular m-by-m matrix; !! 0 is a m-by-(n-m) 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( 'DGELQ2', -info ) return end if k = min( m, n ) do i = 1, k ! generate elementary reflector h(i) to annihilate a(i,i+1:n) call stdlib${ii}$_dlarfg( n-i+1, a( i, i ), a( i, min( i+1, n ) ), lda,tau( i ) ) if( i<m ) then ! apply h(i) to a(i+1:m,i:n) from the right aii = a( i, i ) a( i, i ) = one call stdlib${ii}$_dlarf( 'RIGHT', m-i, n-i+1, a( i, i ), lda, tau( i ),a( i+1, i ), & lda, work ) a( i, i ) = aii end if end do return end subroutine stdlib${ii}$_dgelq2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gelq2( m, n, a, lda, tau, work, info ) !! DGELQ2: computes an LQ factorization of a real m-by-n matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a n-by-n orthogonal matrix; !! L is a lower-triangular m-by-m matrix; !! 0 is a m-by-(n-m) 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( 'DGELQ2', -info ) return end if k = min( m, n ) do i = 1, k ! generate elementary reflector h(i) to annihilate a(i,i+1:n) call stdlib${ii}$_${ri}$larfg( n-i+1, a( i, i ), a( i, min( i+1, n ) ), lda,tau( i ) ) if( i<m ) then ! apply h(i) to a(i+1:m,i:n) from the right aii = a( i, i ) a( i, i ) = one call stdlib${ii}$_${ri}$larf( 'RIGHT', m-i, n-i+1, a( i, i ), lda, tau( i ),a( i+1, i ), & lda, work ) a( i, i ) = aii end if end do return end subroutine stdlib${ii}$_${ri}$gelq2 #:endif #:endfor pure module subroutine stdlib${ii}$_cgelq2( m, n, a, lda, tau, work, info ) !! CGELQ2 computes an LQ factorization of a complex m-by-n matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a n-by-n orthogonal matrix; !! L is a lower-triangular m-by-m matrix; !! 0 is a m-by-(n-m) 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( 'CGELQ2', -info ) return end if k = min( m, n ) do i = 1, k ! generate elementary reflector h(i) to annihilate a(i,i+1:n) call stdlib${ii}$_clacgv( n-i+1, a( i, i ), lda ) alpha = a( i, i ) call stdlib${ii}$_clarfg( n-i+1, alpha, a( i, min( i+1, n ) ), lda,tau( i ) ) if( i<m ) then ! apply h(i) to a(i+1:m,i:n) from the right a( i, i ) = cone call stdlib${ii}$_clarf( 'RIGHT', m-i, n-i+1, a( i, i ), lda, tau( i ),a( i+1, i ), & lda, work ) end if a( i, i ) = alpha call stdlib${ii}$_clacgv( n-i+1, a( i, i ), lda ) end do return end subroutine stdlib${ii}$_cgelq2 pure module subroutine stdlib${ii}$_zgelq2( m, n, a, lda, tau, work, info ) !! ZGELQ2 computes an LQ factorization of a complex m-by-n matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a n-by-n orthogonal matrix; !! L is a lower-triangular m-by-m matrix; !! 0 is a m-by-(n-m) 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( 'ZGELQ2', -info ) return end if k = min( m, n ) do i = 1, k ! generate elementary reflector h(i) to annihilate a(i,i+1:n) call stdlib${ii}$_zlacgv( n-i+1, a( i, i ), lda ) alpha = a( i, i ) call stdlib${ii}$_zlarfg( n-i+1, alpha, a( i, min( i+1, n ) ), lda,tau( i ) ) if( i<m ) then ! apply h(i) to a(i+1:m,i:n) from the right a( i, i ) = cone call stdlib${ii}$_zlarf( 'RIGHT', m-i, n-i+1, a( i, i ), lda, tau( i ),a( i+1, i ), & lda, work ) end if a( i, i ) = alpha call stdlib${ii}$_zlacgv( n-i+1, a( i, i ), lda ) end do return end subroutine stdlib${ii}$_zgelq2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gelq2( m, n, a, lda, tau, work, info ) !! ZGELQ2: computes an LQ factorization of a complex m-by-n matrix A: !! A = ( L 0 ) * Q !! where: !! Q is a n-by-n orthogonal matrix; !! L is a lower-triangular m-by-m matrix; !! 0 is a m-by-(n-m) 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( 'ZGELQ2', -info ) return end if k = min( m, n ) do i = 1, k ! generate elementary reflector h(i) to annihilate a(i,i+1:n) call stdlib${ii}$_${ci}$lacgv( n-i+1, a( i, i ), lda ) alpha = a( i, i ) call stdlib${ii}$_${ci}$larfg( n-i+1, alpha, a( i, min( i+1, n ) ), lda,tau( i ) ) if( i<m ) then ! apply h(i) to a(i+1:m,i:n) from the right a( i, i ) = cone call stdlib${ii}$_${ci}$larf( 'RIGHT', m-i, n-i+1, a( i, i ), lda, tau( i ),a( i+1, i ), & lda, work ) end if a( i, i ) = alpha call stdlib${ii}$_${ci}$lacgv( n-i+1, a( i, i ), lda ) end do return end subroutine stdlib${ii}$_${ci}$gelq2 #:endif #:endfor pure module subroutine stdlib${ii}$_cunglq( m, n, k, a, lda, tau, work, lwork, info ) !! CUNGLQ generates an M-by-N complex matrix Q with orthonormal rows, !! which is defined as the first M rows of a product of K elementary !! reflectors of order N !! Q = H(k)**H . . . H(2)**H H(1)**H !! as returned by CGELQF. ! -- 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}$, 'CUNGLQ', ' ', m, n, k, -1_${ik}$ ) lwkopt = max( 1_${ik}$, m )*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<m ) then info = -2_${ik}$ else if( k<0_${ik}$ .or. k>m ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -5_${ik}$ else if( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CUNGLQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( m<=0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'CUNGLQ', ' ', m, n, k, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'CUNGLQ', ' ', 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 rows are handled by the block method. ki = ( ( k-nx-1 ) / nb )*nb kk = min( k, ki+nb ) ! set a(kk+1:m,1:kk) to czero. do j = 1, kk do i = kk + 1, m 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<m )call stdlib${ii}$_cungl2( 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<=m ) then ! form the triangular factor of the block reflector ! h = h(i) h(i+1) . . . h(i+ib-1) call stdlib${ii}$_clarft( 'FORWARD', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h**h to a(i+ib:m,i:n) from the right call stdlib${ii}$_clarfb( 'RIGHT', 'CONJUGATE TRANSPOSE', 'FORWARD','ROWWISE', m-i-& ib+1, n-i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), lda,work( ib+1 ), & ldwork ) end if ! apply h**h to columns i:n of current block call stdlib${ii}$_cungl2( ib, n-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo ) ! set columns 1:i-1 of current block to czero do j = 1, i - 1 do l = i, i + ib - 1 a( l, j ) = czero end do end do end do end if work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_cunglq pure module subroutine stdlib${ii}$_zunglq( m, n, k, a, lda, tau, work, lwork, info ) !! ZUNGLQ generates an M-by-N complex matrix Q with orthonormal rows, !! which is defined as the first M rows of a product of K elementary !! reflectors of order N !! Q = H(k)**H . . . H(2)**H H(1)**H !! as returned by ZGELQF. ! -- 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}$, 'ZUNGLQ', ' ', m, n, k, -1_${ik}$ ) lwkopt = max( 1_${ik}$, m )*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<m ) then info = -2_${ik}$ else if( k<0_${ik}$ .or. k>m ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -5_${ik}$ else if( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZUNGLQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( m<=0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'ZUNGLQ', ' ', m, n, k, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'ZUNGLQ', ' ', 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 rows are handled by the block method. ki = ( ( k-nx-1 ) / nb )*nb kk = min( k, ki+nb ) ! set a(kk+1:m,1:kk) to czero. do j = 1, kk do i = kk + 1, m 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<m )call stdlib${ii}$_zungl2( 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<=m ) then ! form the triangular factor of the block reflector ! h = h(i) h(i+1) . . . h(i+ib-1) call stdlib${ii}$_zlarft( 'FORWARD', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h**h to a(i+ib:m,i:n) from the right call stdlib${ii}$_zlarfb( 'RIGHT', 'CONJUGATE TRANSPOSE', 'FORWARD','ROWWISE', m-i-& ib+1, n-i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), lda,work( ib+1 ), & ldwork ) end if ! apply h**h to columns i:n of current block call stdlib${ii}$_zungl2( ib, n-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo ) ! set columns 1:i-1 of current block to czero do j = 1, i - 1 do l = i, i + ib - 1 a( l, j ) = czero end do end do end do end if work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_zunglq #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$unglq( m, n, k, a, lda, tau, work, lwork, info ) !! ZUNGLQ: generates an M-by-N complex matrix Q with orthonormal rows, !! which is defined as the first M rows of a product of K elementary !! reflectors of order N !! Q = H(k)**H . . . H(2)**H H(1)**H !! as returned by ZGELQF. ! -- 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}$, 'ZUNGLQ', ' ', m, n, k, -1_${ik}$ ) lwkopt = max( 1_${ik}$, m )*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<m ) then info = -2_${ik}$ else if( k<0_${ik}$ .or. k>m ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -5_${ik}$ else if( lwork<max( 1_${ik}$, m ) .and. .not.lquery ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZUNGLQ', -info ) return else if( lquery ) then return end if ! quick return if possible if( m<=0_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if nbmin = 2_${ik}$ nx = 0_${ik}$ iws = m 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}$, 'ZUNGLQ', ' ', m, n, k, -1_${ik}$ ) ) if( nx<k ) then ! determine if workspace is large enough for blocked code. ldwork = m 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}$, 'ZUNGLQ', ' ', 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 rows are handled by the block method. ki = ( ( k-nx-1 ) / nb )*nb kk = min( k, ki+nb ) ! set a(kk+1:m,1:kk) to czero. do j = 1, kk do i = kk + 1, m 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<m )call stdlib${ii}$_${ci}$ungl2( 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<=m ) 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', 'ROWWISE', n-i+1, ib, a( i, i ),lda, tau( i ), & work, ldwork ) ! apply h**h to a(i+ib:m,i:n) from the right call stdlib${ii}$_${ci}$larfb( 'RIGHT', 'CONJUGATE TRANSPOSE', 'FORWARD','ROWWISE', m-i-& ib+1, n-i+1, ib, a( i, i ),lda, work, ldwork, a( i+ib, i ), lda,work( ib+1 ), & ldwork ) end if ! apply h**h to columns i:n of current block call stdlib${ii}$_${ci}$ungl2( ib, n-i+1, ib, a( i, i ), lda, tau( i ), work,iinfo ) ! set columns 1:i-1 of current block to czero do j = 1, i - 1 do l = i, i + ib - 1 a( l, j ) = czero end do end do end do end if work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_${ci}$unglq #:endif #:endfor pure module subroutine stdlib${ii}$_cungl2( m, n, k, a, lda, tau, work, info ) !! CUNGL2 generates an m-by-n complex matrix Q with orthonormal rows, !! which is defined as the first m rows of a product of k elementary !! reflectors of order n !! Q = H(k)**H . . . H(2)**H H(1)**H !! as returned by CGELQF. ! -- 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<m ) then info = -2_${ik}$ else if( k<0_${ik}$ .or. k>m ) 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( 'CUNGL2', -info ) return end if ! quick return if possible if( m<=0 )return if( k<m ) then ! initialise rows k+1:m to rows of the unit matrix do j = 1, n do l = k + 1, m a( l, j ) = czero end do if( j>k .and. j<=m )a( j, j ) = cone end do end if do i = k, 1, -1 ! apply h(i)**h to a(i:m,i:n) from the right if( i<n ) then call stdlib${ii}$_clacgv( n-i, a( i, i+1 ), lda ) if( i<m ) then a( i, i ) = cone call stdlib${ii}$_clarf( 'RIGHT', m-i, n-i+1, a( i, i ), lda,conjg( tau( i ) ), a( & i+1, i ), lda, work ) end if call stdlib${ii}$_cscal( n-i, -tau( i ), a( i, i+1 ), lda ) call stdlib${ii}$_clacgv( n-i, a( i, i+1 ), lda ) end if a( i, i ) = cone - conjg( tau( i ) ) ! set a(i,1:i-1,i) to czero do l = 1, i - 1 a( i, l ) = czero end do end do return end subroutine stdlib${ii}$_cungl2 pure module subroutine stdlib${ii}$_zungl2( m, n, k, a, lda, tau, work, info ) !! ZUNGL2 generates an m-by-n complex matrix Q with orthonormal rows, !! which is defined as the first m rows of a product of k elementary !! reflectors of order n !! Q = H(k)**H . . . H(2)**H H(1)**H !! as returned by ZGELQF. ! -- 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<m ) then info = -2_${ik}$ else if( k<0_${ik}$ .or. k>m ) 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( 'ZUNGL2', -info ) return end if ! quick return if possible if( m<=0 )return if( k<m ) then ! initialise rows k+1:m to rows of the unit matrix do j = 1, n do l = k + 1, m a( l, j ) = czero end do if( j>k .and. j<=m )a( j, j ) = cone end do end if do i = k, 1, -1 ! apply h(i)**h to a(i:m,i:n) from the right if( i<n ) then call stdlib${ii}$_zlacgv( n-i, a( i, i+1 ), lda ) if( i<m ) then a( i, i ) = cone call stdlib${ii}$_zlarf( 'RIGHT', m-i, n-i+1, a( i, i ), lda,conjg( tau( i ) ), a( & i+1, i ), lda, work ) end if call stdlib${ii}$_zscal( n-i, -tau( i ), a( i, i+1 ), lda ) call stdlib${ii}$_zlacgv( n-i, a( i, i+1 ), lda ) end if a( i, i ) = cone - conjg( tau( i ) ) ! set a(i,1:i-1) to czero do l = 1, i - 1 a( i, l ) = czero end do end do return end subroutine stdlib${ii}$_zungl2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$ungl2( m, n, k, a, lda, tau, work, info ) !! ZUNGL2: generates an m-by-n complex matrix Q with orthonormal rows, !! which is defined as the first m rows of a product of k elementary !! reflectors of order n !! Q = H(k)**H . . . H(2)**H H(1)**H !! as returned by ZGELQF. ! -- 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<m ) then info = -2_${ik}$ else if( k<0_${ik}$ .or. k>m ) 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( 'ZUNGL2', -info ) return end if ! quick return if possible if( m<=0 )return if( k<m ) then ! initialise rows k+1:m to rows of the unit matrix do j = 1, n do l = k + 1, m a( l, j ) = czero end do if( j>k .and. j<=m )a( j, j ) = cone end do end if do i = k, 1, -1 ! apply h(i)**h to a(i:m,i:n) from the right if( i<n ) then call stdlib${ii}$_${ci}$lacgv( n-i, a( i, i+1 ), lda ) if( i<m ) then a( i, i ) = cone call stdlib${ii}$_${ci}$larf( 'RIGHT', m-i, n-i+1, a( i, i ), lda,conjg( tau( i ) ), a( & i+1, i ), lda, work ) end if call stdlib${ii}$_${ci}$scal( n-i, -tau(