#:include "common.fypp" submodule(stdlib_lapack_eig_svd_lsq) stdlib_lapack_eigv_sym implicit none contains #:for ik,it,ii in LINALG_INT_KINDS_TYPES module subroutine stdlib${ii}$_ssygv( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, info ) !! SSYGV computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be symmetric and B is also !! positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, lwork, n ! Array Arguments real(sp), intent(inout) :: a(lda,*), b(ldb,*) real(sp), intent(out) :: w(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: lwkmin, lwkopt, nb, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then lwkmin = max( 1_${ik}$, 3_${ik}$*n - 1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( lwkmin, ( nb + 2_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<lwkmin .and. .not.lquery ) then info = -11_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYGV ', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_spotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_ssygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_ssyev( jobz, uplo, n, a, lda, w, work, lwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_strsm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, one,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_strmm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, one,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_ssygv module subroutine stdlib${ii}$_dsygv( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, info ) !! DSYGV computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be symmetric and B is also !! positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, lwork, n ! Array Arguments real(dp), intent(inout) :: a(lda,*), b(ldb,*) real(dp), intent(out) :: w(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: lwkmin, lwkopt, nb, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then lwkmin = max( 1_${ik}$, 3_${ik}$*n - 1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( lwkmin, ( nb + 2_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<lwkmin .and. .not.lquery ) then info = -11_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYGV ', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_dpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_dsygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_dsyev( jobz, uplo, n, a, lda, w, work, lwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_dtrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, one,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_dtrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, one,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_dsygv #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$sygv( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, info ) !! DSYGV: computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be symmetric and B is also !! positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, lwork, n ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*), b(ldb,*) real(${rk}$), intent(out) :: w(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: lwkmin, lwkopt, nb, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then lwkmin = max( 1_${ik}$, 3_${ik}$*n - 1_${ik}$ ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( lwkmin, ( nb + 2_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<lwkmin .and. .not.lquery ) then info = -11_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYGV ', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ri}$potrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ri}$sygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_${ri}$syev( jobz, uplo, n, a, lda, w, work, lwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_${ri}$trsm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, one,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_${ri}$trmm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, one,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ri}$sygv #:endif #:endfor module subroutine stdlib${ii}$_ssygvd( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, iwork, liwork,& !! SSYGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be symmetric and B is also positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(inout) :: a(lda,*), b(ldb,*) real(sp), intent(out) :: w(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: liopt, liwmin, lopt, lwmin ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 6_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n + 1_${ik}$ end if lopt = lwmin liopt = liwmin if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lopt iwork( 1_${ik}$ ) = liopt if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -13_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_spotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_ssygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_ssyevd( jobz, uplo, n, a, lda, w, work, lwork, iwork, liwork,info ) lopt = max( real( lopt,KIND=sp), real( work( 1_${ik}$ ),KIND=sp) ) liopt = max( real( liopt,KIND=sp), real( iwork( 1_${ik}$ ),KIND=sp) ) if( wantz .and. info==0_${ik}$ ) then ! backtransform eigenvectors to the original problem. if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_strsm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, one,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_strmm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, one,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lopt iwork( 1_${ik}$ ) = liopt return end subroutine stdlib${ii}$_ssygvd module subroutine stdlib${ii}$_dsygvd( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, iwork, liwork,& !! DSYGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be symmetric and B is also positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(inout) :: a(lda,*), b(ldb,*) real(dp), intent(out) :: w(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: liopt, liwmin, lopt, lwmin ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 6_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n + 1_${ik}$ end if lopt = lwmin liopt = liwmin if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lopt iwork( 1_${ik}$ ) = liopt if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -13_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_dpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_dsygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_dsyevd( jobz, uplo, n, a, lda, w, work, lwork, iwork, liwork,info ) lopt = max( real( lopt,KIND=dp), real( work( 1_${ik}$ ),KIND=dp) ) liopt = max( real( liopt,KIND=dp), real( iwork( 1_${ik}$ ),KIND=dp) ) if( wantz .and. info==0_${ik}$ ) then ! backtransform eigenvectors to the original problem. if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_dtrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, one,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_dtrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, one,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lopt iwork( 1_${ik}$ ) = liopt return end subroutine stdlib${ii}$_dsygvd #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$sygvd( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, iwork, liwork,& !! DSYGVD: computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be symmetric and B is also positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(inout) :: a(lda,*), b(ldb,*) real(${rk}$), intent(out) :: w(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: liopt, liwmin, lopt, lwmin ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 6_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n + 1_${ik}$ end if lopt = lwmin liopt = liwmin if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lopt iwork( 1_${ik}$ ) = liopt if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -13_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ri}$potrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ri}$sygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_${ri}$syevd( jobz, uplo, n, a, lda, w, work, lwork, iwork, liwork,info ) lopt = max( real( lopt,KIND=${rk}$), real( work( 1_${ik}$ ),KIND=${rk}$) ) liopt = max( real( liopt,KIND=${rk}$), real( iwork( 1_${ik}$ ),KIND=${rk}$) ) if( wantz .and. info==0_${ik}$ ) then ! backtransform eigenvectors to the original problem. if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_${ri}$trsm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, one,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_${ri}$trmm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, one,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lopt iwork( 1_${ik}$ ) = liopt return end subroutine stdlib${ii}$_${ri}$sygvd #:endif #:endfor module subroutine stdlib${ii}$_ssygvx( itype, jobz, range, uplo, n, a, lda, b, ldb,vl, vu, il, iu, abstol,& !! SSYGVX computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A !! and B are assumed to be symmetric and B is also positive definite. !! Eigenvalues and eigenvectors can be selected by specifying either a !! range of values or a range of indices for the desired eigenvalues. m, w, z, ldz, work,lwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, lda, ldb, ldz, lwork, n integer(${ik}$), intent(out) :: info, m real(sp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(sp), intent(inout) :: a(lda,*), b(ldb,*) real(sp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, lquery, upper, valeig, wantz character :: trans integer(${ik}$) :: lwkmin, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. upper = stdlib_lsame( uplo, 'U' ) wantz = stdlib_lsame( jobz, 'V' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -9_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -11_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -13_${ik}$ end if end if end if if (info==0_${ik}$) then if (ldz<1_${ik}$ .or. (wantz .and. ldz<n)) then info = -18_${ik}$ end if end if if( info==0_${ik}$ ) then lwkmin = max( 1_${ik}$, 8_${ik}$*n ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( lwkmin, ( nb + 3_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<lwkmin .and. .not.lquery ) then info = -20_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYGVX', -info ) return else if( lquery ) then return end if ! quick return if possible m = 0_${ik}$ if( n==0_${ik}$ ) then return end if ! form a cholesky factorization of b. call stdlib${ii}$_spotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_ssygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_ssyevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,m, w, z, ldz, & work, lwork, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_strsm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, one, b,ldb, z, ldz ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_strmm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, one, b,ldb, z, ldz ) end if end if ! set work(1) to optimal workspace size. work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_ssygvx module subroutine stdlib${ii}$_dsygvx( itype, jobz, range, uplo, n, a, lda, b, ldb,vl, vu, il, iu, abstol,& !! DSYGVX computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A !! and B are assumed to be symmetric and B is also positive definite. !! Eigenvalues and eigenvectors can be selected by specifying either a !! range of values or a range of indices for the desired eigenvalues. m, w, z, ldz, work,lwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, lda, ldb, ldz, lwork, n integer(${ik}$), intent(out) :: info, m real(dp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(dp), intent(inout) :: a(lda,*), b(ldb,*) real(dp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, lquery, upper, valeig, wantz character :: trans integer(${ik}$) :: lwkmin, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. upper = stdlib_lsame( uplo, 'U' ) wantz = stdlib_lsame( jobz, 'V' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -9_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -11_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -13_${ik}$ end if end if end if if (info==0_${ik}$) then if (ldz<1_${ik}$ .or. (wantz .and. ldz<n)) then info = -18_${ik}$ end if end if if( info==0_${ik}$ ) then lwkmin = max( 1_${ik}$, 8_${ik}$*n ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( lwkmin, ( nb + 3_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<lwkmin .and. .not.lquery ) then info = -20_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYGVX', -info ) return else if( lquery ) then return end if ! quick return if possible m = 0_${ik}$ if( n==0_${ik}$ ) then return end if ! form a cholesky factorization of b. call stdlib${ii}$_dpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_dsygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_dsyevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,m, w, z, ldz, & work, lwork, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_dtrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, one, b,ldb, z, ldz ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_dtrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, one, b,ldb, z, ldz ) end if end if ! set work(1) to optimal workspace size. work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_dsygvx #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$sygvx( itype, jobz, range, uplo, n, a, lda, b, ldb,vl, vu, il, iu, abstol,& !! DSYGVX: computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A !! and B are assumed to be symmetric and B is also positive definite. !! Eigenvalues and eigenvectors can be selected by specifying either a !! range of values or a range of indices for the desired eigenvalues. m, w, z, ldz, work,lwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, lda, ldb, ldz, lwork, n integer(${ik}$), intent(out) :: info, m real(${rk}$), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(${rk}$), intent(inout) :: a(lda,*), b(ldb,*) real(${rk}$), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, lquery, upper, valeig, wantz character :: trans integer(${ik}$) :: lwkmin, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. upper = stdlib_lsame( uplo, 'U' ) wantz = stdlib_lsame( jobz, 'V' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -9_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -11_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -13_${ik}$ end if end if end if if (info==0_${ik}$) then if (ldz<1_${ik}$ .or. (wantz .and. ldz<n)) then info = -18_${ik}$ end if end if if( info==0_${ik}$ ) then lwkmin = max( 1_${ik}$, 8_${ik}$*n ) nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( lwkmin, ( nb + 3_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<lwkmin .and. .not.lquery ) then info = -20_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYGVX', -info ) return else if( lquery ) then return end if ! quick return if possible m = 0_${ik}$ if( n==0_${ik}$ ) then return end if ! form a cholesky factorization of b. call stdlib${ii}$_${ri}$potrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ri}$sygst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_${ri}$syevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,m, w, z, ldz, & work, lwork, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if call stdlib${ii}$_${ri}$trsm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, one, b,ldb, z, ldz ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if call stdlib${ii}$_${ri}$trmm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, one, b,ldb, z, ldz ) end if end if ! set work(1) to optimal workspace size. work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ri}$sygvx #:endif #:endfor module subroutine stdlib${ii}$_sspgv( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,info ) !! SSPGV computes all the eigenvalues and, optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be symmetric, stored in packed format, !! and B is also positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, n ! Array Arguments real(sp), intent(inout) :: ap(*), bp(*) real(sp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: trans integer(${ik}$) :: j, neig ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSPGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_spptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_sspgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_sspev( jobz, uplo, n, ap, w, z, ldz, work, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, neig call stdlib${ii}$_stpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_stpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_sspgv module subroutine stdlib${ii}$_dspgv( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,info ) !! DSPGV computes all the eigenvalues and, optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be symmetric, stored in packed format, !! and B is also positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, n ! Array Arguments real(dp), intent(inout) :: ap(*), bp(*) real(dp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: trans integer(${ik}$) :: j, neig ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSPGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_dpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_dspgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_dspev( jobz, uplo, n, ap, w, z, ldz, work, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, neig call stdlib${ii}$_dtpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_dtpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_dspgv #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$spgv( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,info ) !! DSPGV: computes all the eigenvalues and, optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be symmetric, stored in packed format, !! and B is also positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, n ! Array Arguments real(${rk}$), intent(inout) :: ap(*), bp(*) real(${rk}$), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: trans integer(${ik}$) :: j, neig ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSPGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ri}$pptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ri}$spgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_${ri}$spev( jobz, uplo, n, ap, w, z, ldz, work, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, neig call stdlib${ii}$_${ri}$tpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_${ri}$tpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_${ri}$spgv #:endif #:endfor module subroutine stdlib${ii}$_sspgvd( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,lwork, iwork, liwork,& !! SSPGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be symmetric, stored in packed format, and B is also !! positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(inout) :: ap(*), bp(*) real(sp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: j, liwmin, lwmin, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 6_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n end if end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -13_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSPGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of bp. call stdlib${ii}$_spptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_sspgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_sspevd( jobz, uplo, n, ap, w, z, ldz, work, lwork, iwork,liwork, info ) lwmin = max( real( lwmin,KIND=sp), real( work( 1_${ik}$ ),KIND=sp) ) liwmin = max( real( liwmin,KIND=sp), real( iwork( 1_${ik}$ ),KIND=sp) ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, neig call stdlib${ii}$_stpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t *y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_stpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_sspgvd module subroutine stdlib${ii}$_dspgvd( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,lwork, iwork, liwork,& !! DSPGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be symmetric, stored in packed format, and B is also !! positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(inout) :: ap(*), bp(*) real(dp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: j, liwmin, lwmin, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 6_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n end if end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -13_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSPGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of bp. call stdlib${ii}$_dpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_dspgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_dspevd( jobz, uplo, n, ap, w, z, ldz, work, lwork, iwork,liwork, info ) lwmin = max( real( lwmin,KIND=dp), real( work( 1_${ik}$ ),KIND=dp) ) liwmin = max( real( liwmin,KIND=dp), real( iwork( 1_${ik}$ ),KIND=dp) ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, neig call stdlib${ii}$_dtpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t *y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_dtpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_dspgvd #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$spgvd( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,lwork, iwork, liwork,& !! DSPGVD: computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be symmetric, stored in packed format, and B is also !! positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(inout) :: ap(*), bp(*) real(${rk}$), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: j, liwmin, lwmin, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 6_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n end if end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -13_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSPGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of bp. call stdlib${ii}$_${ri}$pptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ri}$spgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_${ri}$spevd( jobz, uplo, n, ap, w, z, ldz, work, lwork, iwork,liwork, info ) lwmin = max( real( lwmin,KIND=${rk}$), real( work( 1_${ik}$ ),KIND=${rk}$) ) liwmin = max( real( liwmin,KIND=${rk}$), real( iwork( 1_${ik}$ ),KIND=${rk}$) ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, neig call stdlib${ii}$_${ri}$tpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t *y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_${ri}$tpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_${ri}$spgvd #:endif #:endfor module subroutine stdlib${ii}$_sspgvx( itype, jobz, range, uplo, n, ap, bp, vl, vu,il, iu, abstol, m, w, & !! SSPGVX computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A !! and B are assumed to be symmetric, stored in packed storage, and B !! is also positive definite. Eigenvalues and eigenvectors can be !! selected by specifying either a range of values or a range of indices !! for the desired eigenvalues. z, ldz, work, iwork,ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, ldz, n integer(${ik}$), intent(out) :: info, m real(sp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(sp), intent(inout) :: ap(*), bp(*) real(sp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, upper, valeig, wantz character :: trans integer(${ik}$) :: j ! Intrinsic Functions ! Executable Statements ! test the input parameters. upper = stdlib_lsame( uplo, 'U' ) wantz = stdlib_lsame( jobz, 'V' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl ) then info = -9_${ik}$ end if else if( indeig ) then if( il<1_${ik}$ ) then info = -10_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -11_${ik}$ end if end if end if if( info==0_${ik}$ ) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSPGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_spptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_sspgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_sspevx( jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m,w, z, ldz, & work, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, m call stdlib${ii}$_stpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, m call stdlib${ii}$_stpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_sspgvx module subroutine stdlib${ii}$_dspgvx( itype, jobz, range, uplo, n, ap, bp, vl, vu,il, iu, abstol, m, w, & !! DSPGVX computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A !! and B are assumed to be symmetric, stored in packed storage, and B !! is also positive definite. Eigenvalues and eigenvectors can be !! selected by specifying either a range of values or a range of indices !! for the desired eigenvalues. z, ldz, work, iwork,ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, ldz, n integer(${ik}$), intent(out) :: info, m real(dp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(dp), intent(inout) :: ap(*), bp(*) real(dp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, upper, valeig, wantz character :: trans integer(${ik}$) :: j ! Intrinsic Functions ! Executable Statements ! test the input parameters. upper = stdlib_lsame( uplo, 'U' ) wantz = stdlib_lsame( jobz, 'V' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl ) then info = -9_${ik}$ end if else if( indeig ) then if( il<1_${ik}$ ) then info = -10_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -11_${ik}$ end if end if end if if( info==0_${ik}$ ) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSPGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_dpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_dspgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_dspevx( jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m,w, z, ldz, & work, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, m call stdlib${ii}$_dtpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, m call stdlib${ii}$_dtpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_dspgvx #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$spgvx( itype, jobz, range, uplo, n, ap, bp, vl, vu,il, iu, abstol, m, w, & !! DSPGVX: computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A !! and B are assumed to be symmetric, stored in packed storage, and B !! is also positive definite. Eigenvalues and eigenvectors can be !! selected by specifying either a range of values or a range of indices !! for the desired eigenvalues. z, ldz, work, iwork,ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, ldz, n integer(${ik}$), intent(out) :: info, m real(${rk}$), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(${rk}$), intent(inout) :: ap(*), bp(*) real(${rk}$), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, upper, valeig, wantz character :: trans integer(${ik}$) :: j ! Intrinsic Functions ! Executable Statements ! test the input parameters. upper = stdlib_lsame( uplo, 'U' ) wantz = stdlib_lsame( jobz, 'V' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl ) then info = -9_${ik}$ end if else if( indeig ) then if( il<1_${ik}$ ) then info = -10_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -11_${ik}$ end if end if end if if( info==0_${ik}$ ) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSPGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ri}$pptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ri}$spgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_${ri}$spevx( jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m,w, z, ldz, & work, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**t*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'T' end if do j = 1, m call stdlib${ii}$_${ri}$tpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**t*y if( upper ) then trans = 'T' else trans = 'N' end if do j = 1, m call stdlib${ii}$_${ri}$tpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_${ri}$spgvx #:endif #:endfor pure module subroutine stdlib${ii}$_ssbgv( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w, z,ldz, work, & !! SSBGV computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric !! and banded, and B is also positive definite. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, n ! Array Arguments real(sp), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(sp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwrk ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSBGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_spbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n call stdlib${ii}$_ssbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work( indwrk ), & iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_ssbtrd( vect, uplo, n, ka, ab, ldab, w, work( inde ), z, ldz,work( indwrk )& , iinfo ) ! for eigenvalues only, call stdlib${ii}$_ssterf. for eigenvectors, call stdlib${ii}$_ssteqr. if( .not.wantz ) then call stdlib${ii}$_ssterf( n, w, work( inde ), info ) else call stdlib${ii}$_ssteqr( jobz, n, w, work( inde ), z, ldz, work( indwrk ),info ) end if return end subroutine stdlib${ii}$_ssbgv pure module subroutine stdlib${ii}$_dsbgv( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w, z,ldz, work, & !! DSBGV computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric !! and banded, and B is also positive definite. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, n ! Array Arguments real(dp), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(dp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwrk ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSBGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_dpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n call stdlib${ii}$_dsbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work( indwrk ), & iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_dsbtrd( vect, uplo, n, ka, ab, ldab, w, work( inde ), z, ldz,work( indwrk )& , iinfo ) ! for eigenvalues only, call stdlib${ii}$_dsterf. for eigenvectors, call stdlib${ii}$_ssteqr. if( .not.wantz ) then call stdlib${ii}$_dsterf( n, w, work( inde ), info ) else call stdlib${ii}$_dsteqr( jobz, n, w, work( inde ), z, ldz, work( indwrk ),info ) end if return end subroutine stdlib${ii}$_dsbgv #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$sbgv( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w, z,ldz, work, & !! DSBGV: computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric !! and banded, and B is also positive definite. info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, n ! Array Arguments real(${rk}$), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(${rk}$), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwrk ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSBGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_${ri}$pbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n call stdlib${ii}$_${ri}$sbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work( indwrk ), & iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_${ri}$sbtrd( vect, uplo, n, ka, ab, ldab, w, work( inde ), z, ldz,work( indwrk )& , iinfo ) ! for eigenvalues only, call stdlib${ii}$_${ri}$sterf. for eigenvectors, call stdlib${ii}$_dsteqr. if( .not.wantz ) then call stdlib${ii}$_${ri}$sterf( n, w, work( inde ), info ) else call stdlib${ii}$_${ri}$steqr( jobz, n, w, work( inde ), z, ldz, work( indwrk ),info ) end if return end subroutine stdlib${ii}$_${ri}$sbgv #:endif #:endfor pure module subroutine stdlib${ii}$_ssbgvd( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w,z, ldz, work, & !! SSBGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of the !! form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric and !! banded, and B is also positive definite. If eigenvectors are !! desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. lwork, iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(sp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwk2, indwrk, liwmin, llwrk2, lwmin ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n end if if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -14_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSBGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_spbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n indwk2 = indwrk + n*n llwrk2 = lwork - indwk2 + 1_${ik}$ call stdlib${ii}$_ssbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_ssbtrd( vect, uplo, n, ka, ab, ldab, w, work( inde ), z, ldz,work( indwrk )& , iinfo ) ! for eigenvalues only, call stdlib${ii}$_ssterf. for eigenvectors, call stdlib${ii}$_sstedc. if( .not.wantz ) then call stdlib${ii}$_ssterf( n, w, work( inde ), info ) else call stdlib${ii}$_sstedc( 'I', n, w, work( inde ), work( indwrk ), n,work( indwk2 ), & llwrk2, iwork, liwork, info ) call stdlib${ii}$_sgemm( 'N', 'N', n, n, n, one, z, ldz, work( indwrk ), n,zero, work( & indwk2 ), n ) call stdlib${ii}$_slacpy( 'A', n, n, work( indwk2 ), n, z, ldz ) end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_ssbgvd pure module subroutine stdlib${ii}$_dsbgvd( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w,z, ldz, work, & !! DSBGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of the !! form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric and !! banded, and B is also positive definite. If eigenvectors are !! desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. lwork, iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(dp), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwk2, indwrk, liwmin, llwrk2, lwmin ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n end if if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -14_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSBGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_dpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n indwk2 = indwrk + n*n llwrk2 = lwork - indwk2 + 1_${ik}$ call stdlib${ii}$_dsbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_dsbtrd( vect, uplo, n, ka, ab, ldab, w, work( inde ), z, ldz,work( indwrk )& , iinfo ) ! for eigenvalues only, call stdlib${ii}$_dsterf. for eigenvectors, call stdlib${ii}$_sstedc. if( .not.wantz ) then call stdlib${ii}$_dsterf( n, w, work( inde ), info ) else call stdlib${ii}$_dstedc( 'I', n, w, work( inde ), work( indwrk ), n,work( indwk2 ), & llwrk2, iwork, liwork, info ) call stdlib${ii}$_dgemm( 'N', 'N', n, n, n, one, z, ldz, work( indwrk ), n,zero, work( & indwk2 ), n ) call stdlib${ii}$_dlacpy( 'A', n, n, work( indwk2 ), n, z, ldz ) end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_dsbgvd #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$sbgvd( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w,z, ldz, work, & !! DSBGVD: computes all the eigenvalues, and optionally, the eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of the !! form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric and !! banded, and B is also positive definite. If eigenvectors are !! desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. lwork, iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, liwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(${rk}$), intent(out) :: w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwk2, indwrk, liwmin, llwrk2, lwmin ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then liwmin = 1_${ik}$ lwmin = 1_${ik}$ else if( wantz ) then liwmin = 3_${ik}$ + 5_${ik}$*n lwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ else liwmin = 1_${ik}$ lwmin = 2_${ik}$*n end if if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -14_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSBGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_${ri}$pbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n indwk2 = indwrk + n*n llwrk2 = lwork - indwk2 + 1_${ik}$ call stdlib${ii}$_${ri}$sbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_${ri}$sbtrd( vect, uplo, n, ka, ab, ldab, w, work( inde ), z, ldz,work( indwrk )& , iinfo ) ! for eigenvalues only, call stdlib${ii}$_${ri}$sterf. for eigenvectors, call stdlib${ii}$_dstedc. if( .not.wantz ) then call stdlib${ii}$_${ri}$sterf( n, w, work( inde ), info ) else call stdlib${ii}$_${ri}$stedc( 'I', n, w, work( inde ), work( indwrk ), n,work( indwk2 ), & llwrk2, iwork, liwork, info ) call stdlib${ii}$_${ri}$gemm( 'N', 'N', n, n, n, one, z, ldz, work( indwrk ), n,zero, work( & indwk2 ), n ) call stdlib${ii}$_${ri}$lacpy( 'A', n, n, work( indwk2 ), n, z, ldz ) end if work( 1_${ik}$ ) = lwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_${ri}$sbgvd #:endif #:endfor pure module subroutine stdlib${ii}$_ssbgvx( jobz, range, uplo, n, ka, kb, ab, ldab, bb,ldbb, q, ldq, vl, & !! SSBGVX computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric !! and banded, and B is also positive definite. Eigenvalues and !! eigenvectors can be selected by specifying either all eigenvalues, !! a range of values or a range of indices for the desired eigenvalues. vu, il, iu, abstol, m, w, z,ldz, work, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, iu, ka, kb, ldab, ldbb, ldq, ldz, n integer(${ik}$), intent(out) :: info, m real(sp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(sp), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(sp), intent(out) :: q(ldq,*), w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, test, upper, valeig, wantz character :: order, vect integer(${ik}$) :: i, iinfo, indd, inde, indee, indibl, indisp, indiwo, indwrk, itmp1, j, & jj, nsplit real(sp) :: tmp1 ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ka<0_${ik}$ ) then info = -5_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -6_${ik}$ else if( ldab<ka+1 ) then info = -8_${ik}$ else if( ldbb<kb+1 ) then info = -10_${ik}$ else if( ldq<1_${ik}$ .or. ( wantz .and. ldq<n ) ) then info = -12_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -14_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -15_${ik}$ else if ( iu<min( n, il ) .or. iu>n ) then info = -16_${ik}$ end if end if end if if( info==0_${ik}$) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -21_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSBGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_spbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. call stdlib${ii}$_ssbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,work, iinfo ) ! reduce symmetric band matrix to tridiagonal form. indd = 1_${ik}$ inde = indd + n indwrk = inde + n if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_ssbtrd( vect, uplo, n, ka, ab, ldab, work( indd ),work( inde ), q, ldq, & work( indwrk ), iinfo ) ! if all eigenvalues are desired and abstol is less than or equal ! to zero, then call stdlib${ii}$_ssterf or stdlib${ii}$_ssteqr. if this fails for some ! eigenvalue, then try stdlib${ii}$_sstebz. test = .false. if( indeig ) then if( il==1_${ik}$ .and. iu==n ) then test = .true. end if end if if( ( alleig .or. test ) .and. ( abstol<=zero ) ) then call stdlib${ii}$_scopy( n, work( indd ), 1_${ik}$, w, 1_${ik}$ ) indee = indwrk + 2_${ik}$*n call stdlib${ii}$_scopy( n-1, work( inde ), 1_${ik}$, work( indee ), 1_${ik}$ ) if( .not.wantz ) then call stdlib${ii}$_ssterf( n, w, work( indee ), info ) else call stdlib${ii}$_slacpy( 'A', n, n, q, ldq, z, ldz ) call stdlib${ii}$_ssteqr( jobz, n, w, work( indee ), z, ldz,work( indwrk ), info ) if( info==0_${ik}$ ) then do i = 1, n ifail( i ) = 0_${ik}$ end do end if end if if( info==0_${ik}$ ) then m = n go to 30 end if info = 0_${ik}$ end if ! otherwise, call stdlib${ii}$_sstebz and, if eigenvectors are desired, ! call stdlib${ii}$_sstein. if( wantz ) then order = 'B' else order = 'E' end if indibl = 1_${ik}$ indisp = indibl + n indiwo = indisp + n call stdlib${ii}$_sstebz( range, order, n, vl, vu, il, iu, abstol,work( indd ), work( inde ),& m, nsplit, w,iwork( indibl ), iwork( indisp ), work( indwrk ),iwork( indiwo ), info ) if( wantz ) then call stdlib${ii}$_sstein( n, work( indd ), work( inde ), m, w,iwork( indibl ), iwork( & indisp ), z, ldz,work( indwrk ), iwork( indiwo ), ifail, info ) ! apply transformation matrix used in reduction to tridiagonal ! form to eigenvectors returned by stdlib${ii}$_sstein. do j = 1, m call stdlib${ii}$_scopy( n, z( 1_${ik}$, j ), 1_${ik}$, work( 1_${ik}$ ), 1_${ik}$ ) call stdlib${ii}$_sgemv( 'N', n, n, one, q, ldq, work, 1_${ik}$, zero,z( 1_${ik}$, j ), 1_${ik}$ ) end do end if 30 continue ! if eigenvalues are not in order, then sort them, along with ! eigenvectors. if( wantz ) then do j = 1, m - 1 i = 0_${ik}$ tmp1 = w( j ) do jj = j + 1, m if( w( jj )<tmp1 ) then i = jj tmp1 = w( jj ) end if end do if( i/=0_${ik}$ ) then itmp1 = iwork( indibl+i-1 ) w( i ) = w( j ) iwork( indibl+i-1 ) = iwork( indibl+j-1 ) w( j ) = tmp1 iwork( indibl+j-1 ) = itmp1 call stdlib${ii}$_sswap( n, z( 1_${ik}$, i ), 1_${ik}$, z( 1_${ik}$, j ), 1_${ik}$ ) if( info/=0_${ik}$ ) then itmp1 = ifail( i ) ifail( i ) = ifail( j ) ifail( j ) = itmp1 end if end if end do end if return end subroutine stdlib${ii}$_ssbgvx pure module subroutine stdlib${ii}$_dsbgvx( jobz, range, uplo, n, ka, kb, ab, ldab, bb,ldbb, q, ldq, vl, & !! DSBGVX computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric !! and banded, and B is also positive definite. Eigenvalues and !! eigenvectors can be selected by specifying either all eigenvalues, !! a range of values or a range of indices for the desired eigenvalues. vu, il, iu, abstol, m, w, z,ldz, work, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, iu, ka, kb, ldab, ldbb, ldq, ldz, n integer(${ik}$), intent(out) :: info, m real(dp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(dp), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(dp), intent(out) :: q(ldq,*), w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, test, upper, valeig, wantz character :: order, vect integer(${ik}$) :: i, iinfo, indd, inde, indee, indibl, indisp, indiwo, indwrk, itmp1, j, & jj, nsplit real(dp) :: tmp1 ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ka<0_${ik}$ ) then info = -5_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -6_${ik}$ else if( ldab<ka+1 ) then info = -8_${ik}$ else if( ldbb<kb+1 ) then info = -10_${ik}$ else if( ldq<1_${ik}$ .or. ( wantz .and. ldq<n ) ) then info = -12_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -14_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -15_${ik}$ else if ( iu<min( n, il ) .or. iu>n ) then info = -16_${ik}$ end if end if end if if( info==0_${ik}$) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -21_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSBGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_dpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. call stdlib${ii}$_dsbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,work, iinfo ) ! reduce symmetric band matrix to tridiagonal form. indd = 1_${ik}$ inde = indd + n indwrk = inde + n if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_dsbtrd( vect, uplo, n, ka, ab, ldab, work( indd ),work( inde ), q, ldq, & work( indwrk ), iinfo ) ! if all eigenvalues are desired and abstol is less than or equal ! to zero, then call stdlib${ii}$_dsterf or stdlib${ii}$_ssteqr. if this fails for some ! eigenvalue, then try stdlib${ii}$_dstebz. test = .false. if( indeig ) then if( il==1_${ik}$ .and. iu==n ) then test = .true. end if end if if( ( alleig .or. test ) .and. ( abstol<=zero ) ) then call stdlib${ii}$_dcopy( n, work( indd ), 1_${ik}$, w, 1_${ik}$ ) indee = indwrk + 2_${ik}$*n call stdlib${ii}$_dcopy( n-1, work( inde ), 1_${ik}$, work( indee ), 1_${ik}$ ) if( .not.wantz ) then call stdlib${ii}$_dsterf( n, w, work( indee ), info ) else call stdlib${ii}$_dlacpy( 'A', n, n, q, ldq, z, ldz ) call stdlib${ii}$_dsteqr( jobz, n, w, work( indee ), z, ldz,work( indwrk ), info ) if( info==0_${ik}$ ) then do i = 1, n ifail( i ) = 0_${ik}$ end do end if end if if( info==0_${ik}$ ) then m = n go to 30 end if info = 0_${ik}$ end if ! otherwise, call stdlib${ii}$_dstebz and, if eigenvectors are desired, ! call stdlib${ii}$_dstein. if( wantz ) then order = 'B' else order = 'E' end if indibl = 1_${ik}$ indisp = indibl + n indiwo = indisp + n call stdlib${ii}$_dstebz( range, order, n, vl, vu, il, iu, abstol,work( indd ), work( inde ),& m, nsplit, w,iwork( indibl ), iwork( indisp ), work( indwrk ),iwork( indiwo ), info ) if( wantz ) then call stdlib${ii}$_dstein( n, work( indd ), work( inde ), m, w,iwork( indibl ), iwork( & indisp ), z, ldz,work( indwrk ), iwork( indiwo ), ifail, info ) ! apply transformation matrix used in reduction to tridiagonal ! form to eigenvectors returned by stdlib${ii}$_dstein. do j = 1, m call stdlib${ii}$_dcopy( n, z( 1_${ik}$, j ), 1_${ik}$, work( 1_${ik}$ ), 1_${ik}$ ) call stdlib${ii}$_dgemv( 'N', n, n, one, q, ldq, work, 1_${ik}$, zero,z( 1_${ik}$, j ), 1_${ik}$ ) end do end if 30 continue ! if eigenvalues are not in order, then sort them, along with ! eigenvectors. if( wantz ) then do j = 1, m - 1 i = 0_${ik}$ tmp1 = w( j ) do jj = j + 1, m if( w( jj )<tmp1 ) then i = jj tmp1 = w( jj ) end if end do if( i/=0_${ik}$ ) then itmp1 = iwork( indibl+i-1 ) w( i ) = w( j ) iwork( indibl+i-1 ) = iwork( indibl+j-1 ) w( j ) = tmp1 iwork( indibl+j-1 ) = itmp1 call stdlib${ii}$_dswap( n, z( 1_${ik}$, i ), 1_${ik}$, z( 1_${ik}$, j ), 1_${ik}$ ) if( info/=0_${ik}$ ) then itmp1 = ifail( i ) ifail( i ) = ifail( j ) ifail( j ) = itmp1 end if end if end do end if return end subroutine stdlib${ii}$_dsbgvx #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$sbgvx( jobz, range, uplo, n, ka, kb, ab, ldab, bb,ldbb, q, ldq, vl, & !! DSBGVX: computes selected eigenvalues, and optionally, eigenvectors !! of a real generalized symmetric-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be symmetric !! and banded, and B is also positive definite. Eigenvalues and !! eigenvectors can be selected by specifying either all eigenvalues, !! a range of values or a range of indices for the desired eigenvalues. vu, il, iu, abstol, m, w, z,ldz, work, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, iu, ka, kb, ldab, ldbb, ldq, ldz, n integer(${ik}$), intent(out) :: info, m real(${rk}$), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(${rk}$), intent(inout) :: ab(ldab,*), bb(ldbb,*) real(${rk}$), intent(out) :: q(ldq,*), w(*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, test, upper, valeig, wantz character :: order, vect integer(${ik}$) :: i, iinfo, indd, inde, indee, indibl, indisp, indiwo, indwrk, itmp1, j, & jj, nsplit real(${rk}$) :: tmp1 ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ka<0_${ik}$ ) then info = -5_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -6_${ik}$ else if( ldab<ka+1 ) then info = -8_${ik}$ else if( ldbb<kb+1 ) then info = -10_${ik}$ else if( ldq<1_${ik}$ .or. ( wantz .and. ldq<n ) ) then info = -12_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -14_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -15_${ik}$ else if ( iu<min( n, il ) .or. iu>n ) then info = -16_${ik}$ end if end if end if if( info==0_${ik}$) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -21_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSBGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_${ri}$pbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. call stdlib${ii}$_${ri}$sbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,work, iinfo ) ! reduce symmetric band matrix to tridiagonal form. indd = 1_${ik}$ inde = indd + n indwrk = inde + n if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_${ri}$sbtrd( vect, uplo, n, ka, ab, ldab, work( indd ),work( inde ), q, ldq, & work( indwrk ), iinfo ) ! if all eigenvalues are desired and abstol is less than or equal ! to zero, then call stdlib${ii}$_${ri}$sterf or stdlib${ii}$_dsteqr. if this fails for some ! eigenvalue, then try stdlib${ii}$_${ri}$stebz. test = .false. if( indeig ) then if( il==1_${ik}$ .and. iu==n ) then test = .true. end if end if if( ( alleig .or. test ) .and. ( abstol<=zero ) ) then call stdlib${ii}$_${ri}$copy( n, work( indd ), 1_${ik}$, w, 1_${ik}$ ) indee = indwrk + 2_${ik}$*n call stdlib${ii}$_${ri}$copy( n-1, work( inde ), 1_${ik}$, work( indee ), 1_${ik}$ ) if( .not.wantz ) then call stdlib${ii}$_${ri}$sterf( n, w, work( indee ), info ) else call stdlib${ii}$_${ri}$lacpy( 'A', n, n, q, ldq, z, ldz ) call stdlib${ii}$_${ri}$steqr( jobz, n, w, work( indee ), z, ldz,work( indwrk ), info ) if( info==0_${ik}$ ) then do i = 1, n ifail( i ) = 0_${ik}$ end do end if end if if( info==0_${ik}$ ) then m = n go to 30 end if info = 0_${ik}$ end if ! otherwise, call stdlib${ii}$_${ri}$stebz and, if eigenvectors are desired, ! call stdlib${ii}$_${ri}$stein. if( wantz ) then order = 'B' else order = 'E' end if indibl = 1_${ik}$ indisp = indibl + n indiwo = indisp + n call stdlib${ii}$_${ri}$stebz( range, order, n, vl, vu, il, iu, abstol,work( indd ), work( inde ),& m, nsplit, w,iwork( indibl ), iwork( indisp ), work( indwrk ),iwork( indiwo ), info ) if( wantz ) then call stdlib${ii}$_${ri}$stein( n, work( indd ), work( inde ), m, w,iwork( indibl ), iwork( & indisp ), z, ldz,work( indwrk ), iwork( indiwo ), ifail, info ) ! apply transformation matrix used in reduction to tridiagonal ! form to eigenvectors returned by stdlib${ii}$_${ri}$stein. do j = 1, m call stdlib${ii}$_${ri}$copy( n, z( 1_${ik}$, j ), 1_${ik}$, work( 1_${ik}$ ), 1_${ik}$ ) call stdlib${ii}$_${ri}$gemv( 'N', n, n, one, q, ldq, work, 1_${ik}$, zero,z( 1_${ik}$, j ), 1_${ik}$ ) end do end if 30 continue ! if eigenvalues are not in order, then sort them, along with ! eigenvectors. if( wantz ) then do j = 1, m - 1 i = 0_${ik}$ tmp1 = w( j ) do jj = j + 1, m if( w( jj )<tmp1 ) then i = jj tmp1 = w( jj ) end if end do if( i/=0_${ik}$ ) then itmp1 = iwork( indibl+i-1 ) w( i ) = w( j ) iwork( indibl+i-1 ) = iwork( indibl+j-1 ) w( j ) = tmp1 iwork( indibl+j-1 ) = itmp1 call stdlib${ii}$_${ri}$swap( n, z( 1_${ik}$, i ), 1_${ik}$, z( 1_${ik}$, j ), 1_${ik}$ ) if( info/=0_${ik}$ ) then itmp1 = ifail( i ) ifail( i ) = ifail( j ) ifail( j ) = itmp1 end if end if end do end if return end subroutine stdlib${ii}$_${ri}$sbgvx #:endif #:endfor pure module subroutine stdlib${ii}$_ssytrd( uplo, n, a, lda, d, e, tau, work, lwork, info ) !! SSYTRD reduces a real symmetric matrix A to real symmetric !! tridiagonal form T by an orthogonal similarity transformation: !! Q**T * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(sp), intent(inout) :: a(lda,*) real(sp), intent(out) :: d(*), e(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, iws, j, kk, ldwork, lwkopt, nb, nbmin, nx ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<1_${ik}$ .and. .not.lquery ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then ! determine the block size. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYTRD', -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 nx = n iws = 1_${ik}$ if( nb>1_${ik}$ .and. nb<n ) then ! determine when to cross over from blocked to unblocked code ! (last block is always handled by unblocked code). nx = max( nb, stdlib${ii}$_ilaenv( 3_${ik}$, 'SSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) if( nx<n ) 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: determine the ! minimum value of nb, and reduce nb or force use of ! unblocked code by setting nx = n. nb = max( lwork / ldwork, 1_${ik}$ ) nbmin = stdlib${ii}$_ilaenv( 2_${ik}$, 'SSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) if( nb<nbmin )nx = n end if else nx = n end if else nb = 1_${ik}$ end if if( upper ) then ! reduce the upper triangle of a. ! columns 1:kk are handled by the unblocked method. kk = n - ( ( n-nx+nb-1 ) / nb )*nb do i = n - nb + 1, kk + 1, -nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_slatrd( uplo, i+nb-1, nb, a, lda, e, tau, work,ldwork ) ! update the unreduced submatrix a(1:i-1,1:i-1), using an ! update of the form: a := a - v*w**t - w*v**t call stdlib${ii}$_ssyr2k( uplo, 'NO TRANSPOSE', i-1, nb, -one, a( 1_${ik}$, i ),lda, work, & ldwork, one, a, lda ) ! copy superdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j-1, j ) = e( j-1 ) d( j ) = a( j, j ) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_ssytd2( uplo, kk, a, lda, d, e, tau, iinfo ) else ! reduce the lower triangle of a do i = 1, n - nx, nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_slatrd( uplo, n-i+1, nb, a( i, i ), lda, e( i ),tau( i ), work, & ldwork ) ! update the unreduced submatrix a(i+ib:n,i+ib:n), using ! an update of the form: a := a - v*w**t - w*v**t call stdlib${ii}$_ssyr2k( uplo, 'NO TRANSPOSE', n-i-nb+1, nb, -one,a( i+nb, i ), lda, & work( nb+1 ), ldwork, one,a( i+nb, i+nb ), lda ) ! copy subdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j+1, j ) = e( j ) d( j ) = a( j, j ) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_ssytd2( uplo, n-i+1, a( i, i ), lda, d( i ), e( i ),tau( i ), iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_ssytrd pure module subroutine stdlib${ii}$_dsytrd( uplo, n, a, lda, d, e, tau, work, lwork, info ) !! DSYTRD reduces a real symmetric matrix A to real symmetric !! tridiagonal form T by an orthogonal similarity transformation: !! Q**T * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(dp), intent(inout) :: a(lda,*) real(dp), intent(out) :: d(*), e(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, iws, j, kk, ldwork, lwkopt, nb, nbmin, nx ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<1_${ik}$ .and. .not.lquery ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then ! determine the block size. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTRD', -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 nx = n iws = 1_${ik}$ if( nb>1_${ik}$ .and. nb<n ) then ! determine when to cross over from blocked to unblocked code ! (last block is always handled by unblocked code). nx = max( nb, stdlib${ii}$_ilaenv( 3_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) if( nx<n ) 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: determine the ! minimum value of nb, and reduce nb or force use of ! unblocked code by setting nx = n. nb = max( lwork / ldwork, 1_${ik}$ ) nbmin = stdlib${ii}$_ilaenv( 2_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) if( nb<nbmin )nx = n end if else nx = n end if else nb = 1_${ik}$ end if if( upper ) then ! reduce the upper triangle of a. ! columns 1:kk are handled by the unblocked method. kk = n - ( ( n-nx+nb-1 ) / nb )*nb do i = n - nb + 1, kk + 1, -nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_dlatrd( uplo, i+nb-1, nb, a, lda, e, tau, work,ldwork ) ! update the unreduced submatrix a(1:i-1,1:i-1), using an ! update of the form: a := a - v*w**t - w*v**t call stdlib${ii}$_dsyr2k( uplo, 'NO TRANSPOSE', i-1, nb, -one, a( 1_${ik}$, i ),lda, work, & ldwork, one, a, lda ) ! copy superdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j-1, j ) = e( j-1 ) d( j ) = a( j, j ) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_dsytd2( uplo, kk, a, lda, d, e, tau, iinfo ) else ! reduce the lower triangle of a do i = 1, n - nx, nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_dlatrd( uplo, n-i+1, nb, a( i, i ), lda, e( i ),tau( i ), work, & ldwork ) ! update the unreduced submatrix a(i+ib:n,i+ib:n), using ! an update of the form: a := a - v*w**t - w*v**t call stdlib${ii}$_dsyr2k( uplo, 'NO TRANSPOSE', n-i-nb+1, nb, -one,a( i+nb, i ), lda, & work( nb+1 ), ldwork, one,a( i+nb, i+nb ), lda ) ! copy subdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j+1, j ) = e( j ) d( j ) = a( j, j ) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_dsytd2( uplo, n-i+1, a( i, i ), lda, d( i ), e( i ),tau( i ), iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_dsytrd #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$sytrd( uplo, n, a, lda, d, e, tau, work, lwork, info ) !! DSYTRD: reduces a real symmetric matrix A to real symmetric !! tridiagonal form T by an orthogonal similarity transformation: !! Q**T * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(out) :: d(*), e(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, iws, j, kk, ldwork, lwkopt, nb, nbmin, nx ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<1_${ik}$ .and. .not.lquery ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then ! determine the block size. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTRD', -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 nx = n iws = 1_${ik}$ if( nb>1_${ik}$ .and. nb<n ) then ! determine when to cross over from blocked to unblocked code ! (last block is always handled by unblocked code). nx = max( nb, stdlib${ii}$_ilaenv( 3_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) if( nx<n ) 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: determine the ! minimum value of nb, and reduce nb or force use of ! unblocked code by setting nx = n. nb = max( lwork / ldwork, 1_${ik}$ ) nbmin = stdlib${ii}$_ilaenv( 2_${ik}$, 'DSYTRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) if( nb<nbmin )nx = n end if else nx = n end if else nb = 1_${ik}$ end if if( upper ) then ! reduce the upper triangle of a. ! columns 1:kk are handled by the unblocked method. kk = n - ( ( n-nx+nb-1 ) / nb )*nb do i = n - nb + 1, kk + 1, -nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_${ri}$latrd( uplo, i+nb-1, nb, a, lda, e, tau, work,ldwork ) ! update the unreduced submatrix a(1:i-1,1:i-1), using an ! update of the form: a := a - v*w**t - w*v**t call stdlib${ii}$_${ri}$syr2k( uplo, 'NO TRANSPOSE', i-1, nb, -one, a( 1_${ik}$, i ),lda, work, & ldwork, one, a, lda ) ! copy superdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j-1, j ) = e( j-1 ) d( j ) = a( j, j ) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_${ri}$sytd2( uplo, kk, a, lda, d, e, tau, iinfo ) else ! reduce the lower triangle of a do i = 1, n - nx, nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_${ri}$latrd( uplo, n-i+1, nb, a( i, i ), lda, e( i ),tau( i ), work, & ldwork ) ! update the unreduced submatrix a(i+ib:n,i+ib:n), using ! an update of the form: a := a - v*w**t - w*v**t call stdlib${ii}$_${ri}$syr2k( uplo, 'NO TRANSPOSE', n-i-nb+1, nb, -one,a( i+nb, i ), lda, & work( nb+1 ), ldwork, one,a( i+nb, i+nb ), lda ) ! copy subdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j+1, j ) = e( j ) d( j ) = a( j, j ) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_${ri}$sytd2( uplo, n-i+1, a( i, i ), lda, d( i ), e( i ),tau( i ), iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ri}$sytrd #:endif #:endfor pure module subroutine stdlib${ii}$_ssytd2( uplo, n, a, lda, d, e, tau, info ) !! SSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal !! form T by an orthogonal similarity transformation: Q**T * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments real(sp), intent(inout) :: a(lda,*) real(sp), intent(out) :: d(*), e(*), tau(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i real(sp) :: alpha, taui ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYTD2', -info ) return end if ! quick return if possible if( n<=0 )return if( upper ) then ! reduce the upper triangle of a do i = n - 1, 1, -1 ! generate elementary reflector h(i) = i - tau * v * v**t ! to annihilate a(1:i-1,i+1) call stdlib${ii}$_slarfg( i, a( i, i+1 ), a( 1_${ik}$, i+1 ), 1_${ik}$, taui ) e( i ) = a( i, i+1 ) if( taui/=zero ) then ! apply h(i) from both sides to a(1:i,1:i) a( i, i+1 ) = one ! compute x := tau * a * v storing x in tau(1:i) call stdlib${ii}$_ssymv( uplo, i, taui, a, lda, a( 1_${ik}$, i+1 ), 1_${ik}$, zero,tau, 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**t * v) * v alpha = -half*taui*stdlib${ii}$_sdot( i, tau, 1_${ik}$, a( 1_${ik}$, i+1 ), 1_${ik}$ ) call stdlib${ii}$_saxpy( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**t - w * v**t call stdlib${ii}$_ssyr2( uplo, i, -one, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$, a,lda ) a( i, i+1 ) = e( i ) end if d( i+1 ) = a( i+1, i+1 ) tau( i ) = taui end do d( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ ) else ! reduce the lower triangle of a do i = 1, n - 1 ! generate elementary reflector h(i) = i - tau * v * v**t ! to annihilate a(i+2:n,i) call stdlib${ii}$_slarfg( n-i, a( i+1, i ), a( min( i+2, n ), i ), 1_${ik}$,taui ) e( i ) = a( i+1, i ) if( taui/=zero ) then ! apply h(i) from both sides to a(i+1:n,i+1:n) a( i+1, i ) = one ! compute x := tau * a * v storing y in tau(i:n-1) call stdlib${ii}$_ssymv( uplo, n-i, taui, a( i+1, i+1 ), lda,a( i+1, i ), 1_${ik}$, zero, & tau( i ), 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**t * v) * v alpha = -half*taui*stdlib${ii}$_sdot( n-i, tau( i ), 1_${ik}$, a( i+1, i ),1_${ik}$ ) call stdlib${ii}$_saxpy( n-i, alpha, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**t - w * v**t call stdlib${ii}$_ssyr2( uplo, n-i, -one, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$,a( i+1, i+1 ),& lda ) a( i+1, i ) = e( i ) end if d( i ) = a( i, i ) tau( i ) = taui end do d( n ) = a( n, n ) end if return end subroutine stdlib${ii}$_ssytd2 pure module subroutine stdlib${ii}$_dsytd2( uplo, n, a, lda, d, e, tau, info ) !! DSYTD2 reduces a real symmetric matrix A to symmetric tridiagonal !! form T by an orthogonal similarity transformation: Q**T * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments real(dp), intent(inout) :: a(lda,*) real(dp), intent(out) :: d(*), e(*), tau(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i real(dp) :: alpha, taui ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTD2', -info ) return end if ! quick return if possible if( n<=0 )return if( upper ) then ! reduce the upper triangle of a do i = n - 1, 1, -1 ! generate elementary reflector h(i) = i - tau * v * v**t ! to annihilate a(1:i-1,i+1) call stdlib${ii}$_dlarfg( i, a( i, i+1 ), a( 1_${ik}$, i+1 ), 1_${ik}$, taui ) e( i ) = a( i, i+1 ) if( taui/=zero ) then ! apply h(i) from both sides to a(1:i,1:i) a( i, i+1 ) = one ! compute x := tau * a * v storing x in tau(1:i) call stdlib${ii}$_dsymv( uplo, i, taui, a, lda, a( 1_${ik}$, i+1 ), 1_${ik}$, zero,tau, 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**t * v) * v alpha = -half*taui*stdlib${ii}$_ddot( i, tau, 1_${ik}$, a( 1_${ik}$, i+1 ), 1_${ik}$ ) call stdlib${ii}$_daxpy( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**t - w * v**t call stdlib${ii}$_dsyr2( uplo, i, -one, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$, a,lda ) a( i, i+1 ) = e( i ) end if d( i+1 ) = a( i+1, i+1 ) tau( i ) = taui end do d( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ ) else ! reduce the lower triangle of a do i = 1, n - 1 ! generate elementary reflector h(i) = i - tau * v * v**t ! to annihilate a(i+2:n,i) call stdlib${ii}$_dlarfg( n-i, a( i+1, i ), a( min( i+2, n ), i ), 1_${ik}$,taui ) e( i ) = a( i+1, i ) if( taui/=zero ) then ! apply h(i) from both sides to a(i+1:n,i+1:n) a( i+1, i ) = one ! compute x := tau * a * v storing y in tau(i:n-1) call stdlib${ii}$_dsymv( uplo, n-i, taui, a( i+1, i+1 ), lda,a( i+1, i ), 1_${ik}$, zero, & tau( i ), 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**t * v) * v alpha = -half*taui*stdlib${ii}$_ddot( n-i, tau( i ), 1_${ik}$, a( i+1, i ),1_${ik}$ ) call stdlib${ii}$_daxpy( n-i, alpha, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**t - w * v**t call stdlib${ii}$_dsyr2( uplo, n-i, -one, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$,a( i+1, i+1 ),& lda ) a( i+1, i ) = e( i ) end if d( i ) = a( i, i ) tau( i ) = taui end do d( n ) = a( n, n ) end if return end subroutine stdlib${ii}$_dsytd2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$sytd2( uplo, n, a, lda, d, e, tau, info ) !! DSYTD2: reduces a real symmetric matrix A to symmetric tridiagonal !! form T by an orthogonal similarity transformation: Q**T * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(out) :: d(*), e(*), tau(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i real(${rk}$) :: alpha, taui ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTD2', -info ) return end if ! quick return if possible if( n<=0 )return if( upper ) then ! reduce the upper triangle of a do i = n - 1, 1, -1 ! generate elementary reflector h(i) = i - tau * v * v**t ! to annihilate a(1:i-1,i+1) call stdlib${ii}$_${ri}$larfg( i, a( i, i+1 ), a( 1_${ik}$, i+1 ), 1_${ik}$, taui ) e( i ) = a( i, i+1 ) if( taui/=zero ) then ! apply h(i) from both sides to a(1:i,1:i) a( i, i+1 ) = one ! compute x := tau * a * v storing x in tau(1:i) call stdlib${ii}$_${ri}$symv( uplo, i, taui, a, lda, a( 1_${ik}$, i+1 ), 1_${ik}$, zero,tau, 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**t * v) * v alpha = -half*taui*stdlib${ii}$_${ri}$dot( i, tau, 1_${ik}$, a( 1_${ik}$, i+1 ), 1_${ik}$ ) call stdlib${ii}$_${ri}$axpy( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**t - w * v**t call stdlib${ii}$_${ri}$syr2( uplo, i, -one, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$, a,lda ) a( i, i+1 ) = e( i ) end if d( i+1 ) = a( i+1, i+1 ) tau( i ) = taui end do d( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ ) else ! reduce the lower triangle of a do i = 1, n - 1 ! generate elementary reflector h(i) = i - tau * v * v**t ! to annihilate a(i+2:n,i) call stdlib${ii}$_${ri}$larfg( n-i, a( i+1, i ), a( min( i+2, n ), i ), 1_${ik}$,taui ) e( i ) = a( i+1, i ) if( taui/=zero ) then ! apply h(i) from both sides to a(i+1:n,i+1:n) a( i+1, i ) = one ! compute x := tau * a * v storing y in tau(i:n-1) call stdlib${ii}$_${ri}$symv( uplo, n-i, taui, a( i+1, i+1 ), lda,a( i+1, i ), 1_${ik}$, zero, & tau( i ), 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**t * v) * v alpha = -half*taui*stdlib${ii}$_${ri}$dot( n-i, tau( i ), 1_${ik}$, a( i+1, i ),1_${ik}$ ) call stdlib${ii}$_${ri}$axpy( n-i, alpha, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**t - w * v**t call stdlib${ii}$_${ri}$syr2( uplo, n-i, -one, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$,a( i+1, i+1 ),& lda ) a( i+1, i ) = e( i ) end if d( i ) = a( i, i ) tau( i ) = taui end do d( n ) = a( n, n ) end if return end subroutine stdlib${ii}$_${ri}$sytd2 #:endif #:endfor pure module subroutine stdlib${ii}$_sorgtr( uplo, n, a, lda, tau, work, lwork, info ) !! SORGTR generates a real orthogonal matrix Q which is defined as the !! product of n-1 elementary reflectors of order N, as returned by !! SSYTRD: !! if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), !! if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(sp), intent(inout) :: a(lda,*) real(sp), intent(in) :: tau(*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, j, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ lquery = ( lwork==-1_${ik}$ ) upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<max( 1_${ik}$, n-1 ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info==0_${ik}$ ) then if ( upper ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SORGQL', ' ', n-1, n-1, n-1, -1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SORGQR', ' ', n-1, n-1, n-1, -1_${ik}$ ) end if lwkopt = max( 1_${ik}$, n-1 )*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SORGTR', -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 if( upper ) then ! q was determined by a call to stdlib${ii}$_ssytrd with uplo = 'u' ! shift the vectors which define the elementary reflectors one ! column to the left, and set the last row and column of q to ! those of the unit matrix do j = 1, n - 1 do i = 1, j - 1 a( i, j ) = a( i, j+1 ) end do a( n, j ) = zero end do do i = 1, n - 1 a( i, n ) = zero end do a( n, n ) = one ! generate q(1:n-1,1:n-1) call stdlib${ii}$_sorgql( n-1, n-1, n-1, a, lda, tau, work, lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_ssytrd with uplo = 'l'. ! shift the vectors which define the elementary reflectors one ! column to the right, and set the first row and column of q to ! those of the unit matrix do j = n, 2, -1 a( 1_${ik}$, j ) = zero do i = j + 1, n a( i, j ) = a( i, j-1 ) end do end do a( 1_${ik}$, 1_${ik}$ ) = one do i = 2, n a( i, 1_${ik}$ ) = zero end do if( n>1_${ik}$ ) then ! generate q(2:n,2:n) call stdlib${ii}$_sorgqr( n-1, n-1, n-1, a( 2_${ik}$, 2_${ik}$ ), lda, tau, work,lwork, iinfo ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_sorgtr pure module subroutine stdlib${ii}$_dorgtr( uplo, n, a, lda, tau, work, lwork, info ) !! DORGTR generates a real orthogonal matrix Q which is defined as the !! product of n-1 elementary reflectors of order N, as returned by !! DSYTRD: !! if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), !! if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(dp), intent(inout) :: a(lda,*) real(dp), intent(in) :: tau(*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, j, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ lquery = ( lwork==-1_${ik}$ ) upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<max( 1_${ik}$, n-1 ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORGQL', ' ', n-1, n-1, n-1, -1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORGQR', ' ', n-1, n-1, n-1, -1_${ik}$ ) end if lwkopt = max( 1_${ik}$, n-1 )*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DORGTR', -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 if( upper ) then ! q was determined by a call to stdlib${ii}$_dsytrd with uplo = 'u' ! shift the vectors which define the elementary reflectors one ! column to the left, and set the last row and column of q to ! those of the unit matrix do j = 1, n - 1 do i = 1, j - 1 a( i, j ) = a( i, j+1 ) end do a( n, j ) = zero end do do i = 1, n - 1 a( i, n ) = zero end do a( n, n ) = one ! generate q(1:n-1,1:n-1) call stdlib${ii}$_dorgql( n-1, n-1, n-1, a, lda, tau, work, lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_dsytrd with uplo = 'l'. ! shift the vectors which define the elementary reflectors one ! column to the right, and set the first row and column of q to ! those of the unit matrix do j = n, 2, -1 a( 1_${ik}$, j ) = zero do i = j + 1, n a( i, j ) = a( i, j-1 ) end do end do a( 1_${ik}$, 1_${ik}$ ) = one do i = 2, n a( i, 1_${ik}$ ) = zero end do if( n>1_${ik}$ ) then ! generate q(2:n,2:n) call stdlib${ii}$_dorgqr( n-1, n-1, n-1, a( 2_${ik}$, 2_${ik}$ ), lda, tau, work,lwork, iinfo ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_dorgtr #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$orgtr( uplo, n, a, lda, tau, work, lwork, info ) !! DORGTR: generates a real orthogonal matrix Q which is defined as the !! product of n-1 elementary reflectors of order N, as returned by !! DSYTRD: !! if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), !! if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(in) :: tau(*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, j, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ lquery = ( lwork==-1_${ik}$ ) upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<max( 1_${ik}$, n-1 ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORGQL', ' ', n-1, n-1, n-1, -1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORGQR', ' ', n-1, n-1, n-1, -1_${ik}$ ) end if lwkopt = max( 1_${ik}$, n-1 )*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DORGTR', -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 if( upper ) then ! q was determined by a call to stdlib${ii}$_${ri}$sytrd with uplo = 'u' ! shift the vectors which define the elementary reflectors one ! column to the left, and set the last row and column of q to ! those of the unit matrix do j = 1, n - 1 do i = 1, j - 1 a( i, j ) = a( i, j+1 ) end do a( n, j ) = zero end do do i = 1, n - 1 a( i, n ) = zero end do a( n, n ) = one ! generate q(1:n-1,1:n-1) call stdlib${ii}$_${ri}$orgql( n-1, n-1, n-1, a, lda, tau, work, lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_${ri}$sytrd with uplo = 'l'. ! shift the vectors which define the elementary reflectors one ! column to the right, and set the first row and column of q to ! those of the unit matrix do j = n, 2, -1 a( 1_${ik}$, j ) = zero do i = j + 1, n a( i, j ) = a( i, j-1 ) end do end do a( 1_${ik}$, 1_${ik}$ ) = one do i = 2, n a( i, 1_${ik}$ ) = zero end do if( n>1_${ik}$ ) then ! generate q(2:n,2:n) call stdlib${ii}$_${ri}$orgqr( n-1, n-1, n-1, a( 2_${ik}$, 2_${ik}$ ), lda, tau, work,lwork, iinfo ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ri}$orgtr #:endif #:endfor pure module subroutine stdlib${ii}$_sormtr( side, uplo, trans, m, n, a, lda, tau, c, ldc,work, lwork, & !! SORMTR 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 of order nq, with nq = m if !! SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of !! nq-1 elementary reflectors, as returned by SSYTRD: !! if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); !! if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). 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, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldc, lwork, m, n ! Array Arguments real(sp), intent(inout) :: a(lda,*), c(ldc,*) real(sp), intent(in) :: tau(*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: left, lquery, upper integer(${ik}$) :: i1, i2, iinfo, lwkopt, mi, ni, nb, nq, nw ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ left = stdlib_lsame( side, 'L' ) upper = stdlib_lsame( uplo, 'U' ) 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.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -2_${ik}$ else if( .not.stdlib_lsame( trans, 'N' ) .and. .not.stdlib_lsame( trans, 'T' ) )& then info = -3_${ik}$ else if( m<0_${ik}$ ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, nq ) ) then info = -7_${ik}$ else if( ldc<max( 1_${ik}$, m ) ) then info = -10_${ik}$ else if( lwork<nw .and. .not.lquery ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SORMQL', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SORMQL', side // trans, m, n-1, n-1,-1_${ik}$ ) end if else if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SORMQR', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SORMQR', side // trans, m, n-1, n-1,-1_${ik}$ ) end if end if lwkopt = nw*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SORMTR', -info ) return else if( lquery ) then return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ .or. nq==1_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if if( left ) then mi = m - 1_${ik}$ ni = n else mi = m ni = n - 1_${ik}$ end if if( upper ) then ! q was determined by a call to stdlib${ii}$_ssytrd with uplo = 'u' call stdlib${ii}$_sormql( side, trans, mi, ni, nq-1, a( 1_${ik}$, 2_${ik}$ ), lda, tau, c,ldc, work, & lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_ssytrd with uplo = 'l' if( left ) then i1 = 2_${ik}$ i2 = 1_${ik}$ else i1 = 1_${ik}$ i2 = 2_${ik}$ end if call stdlib${ii}$_sormqr( side, trans, mi, ni, nq-1, a( 2_${ik}$, 1_${ik}$ ), lda, tau,c( i1, i2 ), ldc,& work, lwork, iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_sormtr pure module subroutine stdlib${ii}$_dormtr( side, uplo, trans, m, n, a, lda, tau, c, ldc,work, lwork, & !! DORMTR 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 of order nq, with nq = m if !! SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of !! nq-1 elementary reflectors, as returned by DSYTRD: !! if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); !! if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). 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, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldc, lwork, m, n ! Array Arguments real(dp), intent(inout) :: a(lda,*), c(ldc,*) real(dp), intent(in) :: tau(*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: left, lquery, upper integer(${ik}$) :: i1, i2, iinfo, lwkopt, mi, nb, ni, nq, nw ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ left = stdlib_lsame( side, 'L' ) upper = stdlib_lsame( uplo, 'U' ) 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.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -2_${ik}$ else if( .not.stdlib_lsame( trans, 'N' ) .and. .not.stdlib_lsame( trans, 'T' ) )& then info = -3_${ik}$ else if( m<0_${ik}$ ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, nq ) ) then info = -7_${ik}$ else if( ldc<max( 1_${ik}$, m ) ) then info = -10_${ik}$ else if( lwork<nw .and. .not.lquery ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQL', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQL', side // trans, m, n-1, n-1,-1_${ik}$ ) end if else if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQR', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQR', side // trans, m, n-1, n-1,-1_${ik}$ ) end if end if lwkopt = nw*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DORMTR', -info ) return else if( lquery ) then return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ .or. nq==1_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if if( left ) then mi = m - 1_${ik}$ ni = n else mi = m ni = n - 1_${ik}$ end if if( upper ) then ! q was determined by a call to stdlib${ii}$_dsytrd with uplo = 'u' call stdlib${ii}$_dormql( side, trans, mi, ni, nq-1, a( 1_${ik}$, 2_${ik}$ ), lda, tau, c,ldc, work, & lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_dsytrd with uplo = 'l' if( left ) then i1 = 2_${ik}$ i2 = 1_${ik}$ else i1 = 1_${ik}$ i2 = 2_${ik}$ end if call stdlib${ii}$_dormqr( side, trans, mi, ni, nq-1, a( 2_${ik}$, 1_${ik}$ ), lda, tau,c( i1, i2 ), ldc,& work, lwork, iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_dormtr #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$ormtr( side, uplo, trans, m, n, a, lda, tau, c, ldc,work, lwork, & !! DORMTR: 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 of order nq, with nq = m if !! SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of !! nq-1 elementary reflectors, as returned by DSYTRD: !! if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); !! if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). 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, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldc, lwork, m, n ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*), c(ldc,*) real(${rk}$), intent(in) :: tau(*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: left, lquery, upper integer(${ik}$) :: i1, i2, iinfo, lwkopt, mi, nb, ni, nq, nw ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ left = stdlib_lsame( side, 'L' ) upper = stdlib_lsame( uplo, 'U' ) 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.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -2_${ik}$ else if( .not.stdlib_lsame( trans, 'N' ) .and. .not.stdlib_lsame( trans, 'T' ) )& then info = -3_${ik}$ else if( m<0_${ik}$ ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, nq ) ) then info = -7_${ik}$ else if( ldc<max( 1_${ik}$, m ) ) then info = -10_${ik}$ else if( lwork<nw .and. .not.lquery ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQL', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQL', side // trans, m, n-1, n-1,-1_${ik}$ ) end if else if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQR', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DORMQR', side // trans, m, n-1, n-1,-1_${ik}$ ) end if end if lwkopt = nw*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DORMTR', -info ) return else if( lquery ) then return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ .or. nq==1_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if if( left ) then mi = m - 1_${ik}$ ni = n else mi = m ni = n - 1_${ik}$ end if if( upper ) then ! q was determined by a call to stdlib${ii}$_${ri}$sytrd with uplo = 'u' call stdlib${ii}$_${ri}$ormql( side, trans, mi, ni, nq-1, a( 1_${ik}$, 2_${ik}$ ), lda, tau, c,ldc, work, & lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_${ri}$sytrd with uplo = 'l' if( left ) then i1 = 2_${ik}$ i2 = 1_${ik}$ else i1 = 1_${ik}$ i2 = 2_${ik}$ end if call stdlib${ii}$_${ri}$ormqr( side, trans, mi, ni, nq-1, a( 2_${ik}$, 1_${ik}$ ), lda, tau,c( i1, i2 ), ldc,& work, lwork, iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ri}$ormtr #:endif #:endfor pure module subroutine stdlib${ii}$_ssb2st_kernels( uplo, wantz, ttype,st, ed, sweep, n, nb, ib,a, lda, & !! SSB2ST_KERNELS is an internal routine used by the SSYTRD_SB2ST !! subroutine. v, tau, ldvt, work) ! -- 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) :: uplo logical(lk), intent(in) :: wantz integer(${ik}$), intent(in) :: ttype, st, ed, sweep, n, nb, ib, lda, ldvt ! Array Arguments real(sp), intent(inout) :: a(lda,*) real(sp), intent(out) :: v(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i, j1, j2, lm, ln, vpos, taupos, dpos, ofdpos, ajeter real(sp) :: ctmp ! Intrinsic Functions ! Executable Statements ajeter = ib + ldvt upper = stdlib_lsame( uplo, 'U' ) if( upper ) then dpos = 2_${ik}$ * nb + 1_${ik}$ ofdpos = 2_${ik}$ * nb else dpos = 1_${ik}$ ofdpos = 2_${ik}$ endif ! upper case if( upper ) then if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = ( a( ofdpos-i, st+i ) ) a( ofdpos-i, st+i ) = zero end do ctmp = ( a( ofdpos, st ) ) call stdlib${ii}$_slarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$,tau( taupos ) ) a( ofdpos, st ) = ctmp lm = ed - st + 1_${ik}$ call stdlib${ii}$_slarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_slarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_slarfx( 'LEFT', ln, lm, v( vpos ),( tau( taupos ) ),a( dpos-nb,& j1 ), lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = one do i = 1, lm-1 v( vpos+i ) =( a( dpos-nb-i, j1+i ) ) a( dpos-nb-i, j1+i ) = zero end do ctmp = ( a( dpos-nb, j1 ) ) call stdlib${ii}$_slarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$, tau( taupos ) ) a( dpos-nb, j1 ) = ctmp call stdlib${ii}$_slarfx( 'RIGHT', ln-1, lm, v( vpos ),tau( taupos ),a( dpos-nb+& 1_${ik}$, j1 ), lda-1, work) endif endif ! lower case else if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = a( ofdpos+i, st-1 ) a( ofdpos+i, st-1 ) = zero end do call stdlib${ii}$_slarfg( lm, a( ofdpos, st-1 ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) lm = ed - st + 1_${ik}$ call stdlib${ii}$_slarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_slarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_slarfx( 'RIGHT', lm, ln, v( vpos ),tau( taupos ), a( dpos+nb, & st ),lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = a( dpos+nb+i, st ) a( dpos+nb+i, st ) = zero end do call stdlib${ii}$_slarfg( lm, a( dpos+nb, st ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) call stdlib${ii}$_slarfx( 'LEFT', lm, ln-1, v( vpos ),( tau( taupos ) ),a( dpos+& nb-1, st+1 ), lda-1, work) endif endif endif return end subroutine stdlib${ii}$_ssb2st_kernels pure module subroutine stdlib${ii}$_dsb2st_kernels( uplo, wantz, ttype,st, ed, sweep, n, nb, ib,a, lda, & !! DSB2ST_KERNELS is an internal routine used by the DSYTRD_SB2ST !! subroutine. v, tau, ldvt, work) ! -- 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) :: uplo logical(lk), intent(in) :: wantz integer(${ik}$), intent(in) :: ttype, st, ed, sweep, n, nb, ib, lda, ldvt ! Array Arguments real(dp), intent(inout) :: a(lda,*) real(dp), intent(out) :: v(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i, j1, j2, lm, ln, vpos, taupos, dpos, ofdpos, ajeter real(dp) :: ctmp ! Intrinsic Functions ! Executable Statements ajeter = ib + ldvt upper = stdlib_lsame( uplo, 'U' ) if( upper ) then dpos = 2_${ik}$ * nb + 1_${ik}$ ofdpos = 2_${ik}$ * nb else dpos = 1_${ik}$ ofdpos = 2_${ik}$ endif ! upper case if( upper ) then if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = ( a( ofdpos-i, st+i ) ) a( ofdpos-i, st+i ) = zero end do ctmp = ( a( ofdpos, st ) ) call stdlib${ii}$_dlarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$,tau( taupos ) ) a( ofdpos, st ) = ctmp lm = ed - st + 1_${ik}$ call stdlib${ii}$_dlarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_dlarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_dlarfx( 'LEFT', ln, lm, v( vpos ),( tau( taupos ) ),a( dpos-nb,& j1 ), lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = one do i = 1, lm-1 v( vpos+i ) =( a( dpos-nb-i, j1+i ) ) a( dpos-nb-i, j1+i ) = zero end do ctmp = ( a( dpos-nb, j1 ) ) call stdlib${ii}$_dlarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$, tau( taupos ) ) a( dpos-nb, j1 ) = ctmp call stdlib${ii}$_dlarfx( 'RIGHT', ln-1, lm, v( vpos ),tau( taupos ),a( dpos-nb+& 1_${ik}$, j1 ), lda-1, work) endif endif ! lower case else if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = a( ofdpos+i, st-1 ) a( ofdpos+i, st-1 ) = zero end do call stdlib${ii}$_dlarfg( lm, a( ofdpos, st-1 ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) lm = ed - st + 1_${ik}$ call stdlib${ii}$_dlarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_dlarfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_dlarfx( 'RIGHT', lm, ln, v( vpos ),tau( taupos ), a( dpos+nb, & st ),lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = a( dpos+nb+i, st ) a( dpos+nb+i, st ) = zero end do call stdlib${ii}$_dlarfg( lm, a( dpos+nb, st ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) call stdlib${ii}$_dlarfx( 'LEFT', lm, ln-1, v( vpos ),( tau( taupos ) ),a( dpos+& nb-1, st+1 ), lda-1, work) endif endif endif return end subroutine stdlib${ii}$_dsb2st_kernels #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$sb2st_kernels( uplo, wantz, ttype,st, ed, sweep, n, nb, ib,a, lda, & !! DSB2ST_KERNELS: is an internal routine used by the DSYTRD_SB2ST !! subroutine. v, tau, ldvt, work) ! -- 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) :: uplo logical(lk), intent(in) :: wantz integer(${ik}$), intent(in) :: ttype, st, ed, sweep, n, nb, ib, lda, ldvt ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(out) :: v(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i, j1, j2, lm, ln, vpos, taupos, dpos, ofdpos, ajeter real(${rk}$) :: ctmp ! Intrinsic Functions ! Executable Statements ajeter = ib + ldvt upper = stdlib_lsame( uplo, 'U' ) if( upper ) then dpos = 2_${ik}$ * nb + 1_${ik}$ ofdpos = 2_${ik}$ * nb else dpos = 1_${ik}$ ofdpos = 2_${ik}$ endif ! upper case if( upper ) then if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = ( a( ofdpos-i, st+i ) ) a( ofdpos-i, st+i ) = zero end do ctmp = ( a( ofdpos, st ) ) call stdlib${ii}$_${ri}$larfg( lm, ctmp, v( vpos+1 ), 1_${ik}$,tau( taupos ) ) a( ofdpos, st ) = ctmp lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ri}$larfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ri}$larfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_${ri}$larfx( 'LEFT', ln, lm, v( vpos ),( tau( taupos ) ),a( dpos-nb,& j1 ), lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = one do i = 1, lm-1 v( vpos+i ) =( a( dpos-nb-i, j1+i ) ) a( dpos-nb-i, j1+i ) = zero end do ctmp = ( a( dpos-nb, j1 ) ) call stdlib${ii}$_${ri}$larfg( lm, ctmp, v( vpos+1 ), 1_${ik}$, tau( taupos ) ) a( dpos-nb, j1 ) = ctmp call stdlib${ii}$_${ri}$larfx( 'RIGHT', ln-1, lm, v( vpos ),tau( taupos ),a( dpos-nb+& 1_${ik}$, j1 ), lda-1, work) endif endif ! lower case else if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = a( ofdpos+i, st-1 ) a( ofdpos+i, st-1 ) = zero end do call stdlib${ii}$_${ri}$larfg( lm, a( ofdpos, st-1 ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ri}$larfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ri}$larfy( uplo, lm, v( vpos ), 1_${ik}$,( tau( taupos ) ),a( dpos, st ), & lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_${ri}$larfx( 'RIGHT', lm, ln, v( vpos ),tau( taupos ), a( dpos+nb, & st ),lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = one do i = 1, lm-1 v( vpos+i ) = a( dpos+nb+i, st ) a( dpos+nb+i, st ) = zero end do call stdlib${ii}$_${ri}$larfg( lm, a( dpos+nb, st ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) call stdlib${ii}$_${ri}$larfx( 'LEFT', lm, ln-1, v( vpos ),( tau( taupos ) ),a( dpos+& nb-1, st+1 ), lda-1, work) endif endif endif return end subroutine stdlib${ii}$_${ri}$sb2st_kernels #:endif #:endfor module subroutine stdlib${ii}$_chegv( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, rwork, info ) !! CHEGV computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be Hermitian and B is also !! positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, lwork, n ! Array Arguments real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: a(lda,*), b(ldb,*) complex(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: lwkopt, nb, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork== -1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( 1_${ik}$, ( nb + 1_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<max( 1_${ik}$, 2_${ik}$*n-1 ) .and. .not.lquery ) then info = -11_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHEGV ', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_cpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_chegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_cheev( jobz, uplo, n, a, lda, w, work, lwork, rwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_ctrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, cone,b, ldb, a, lda & ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h*y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_ctrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, cone,b, ldb, a, lda & ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_chegv module subroutine stdlib${ii}$_zhegv( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, rwork, info ) !! ZHEGV computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be Hermitian and B is also !! positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, lwork, n ! Array Arguments real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: a(lda,*), b(ldb,*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: lwkopt, nb, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( 1_${ik}$, ( nb + 1_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<max( 1_${ik}$, 2_${ik}$*n - 1_${ik}$ ) .and. .not.lquery ) then info = -11_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHEGV ', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_zpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_zhegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_zheev( jobz, uplo, n, a, lda, w, work, lwork, rwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_ztrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, cone,b, ldb, a, lda & ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_ztrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, cone,b, ldb, a, lda & ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_zhegv #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hegv( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, rwork, info ) !! ZHEGV: computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be Hermitian and B is also !! positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, lwork, n ! Array Arguments real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: a(lda,*), b(ldb,*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: lwkopt, nb, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( 1_${ik}$, ( nb + 1_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<max( 1_${ik}$, 2_${ik}$*n - 1_${ik}$ ) .and. .not.lquery ) then info = -11_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHEGV ', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ci}$potrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ci}$hegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_${ci}$heev( jobz, uplo, n, a, lda, w, work, lwork, rwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_${ci}$trsm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, cone,b, ldb, a, lda & ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_${ci}$trmm( 'LEFT', uplo, trans, 'NON-UNIT', n, neig, cone,b, ldb, a, lda & ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ci}$hegv #:endif #:endfor module subroutine stdlib${ii}$_chegvd( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, rwork, lrwork,& !! CHEGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian and B is also positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: a(lda,*), b(ldb,*) complex(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: liopt, liwmin, lopt, lropt, lrwmin, lwmin ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then lwmin = 1_${ik}$ lrwmin = 1_${ik}$ liwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n + n*n lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n*n liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n + 1_${ik}$ lrwmin = n liwmin = 1_${ik}$ end if lopt = lwmin lropt = lrwmin liopt = liwmin if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lopt rwork( 1_${ik}$ ) = lropt iwork( 1_${ik}$ ) = liopt if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -13_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -15_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHEGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_cpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_chegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_cheevd( jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork,iwork, liwork,& info ) lopt = max( real( lopt,KIND=sp), real( work( 1_${ik}$ ),KIND=sp) ) lropt = max( real( lropt,KIND=sp), real( rwork( 1_${ik}$ ),KIND=sp) ) liopt = max( real( liopt,KIND=sp), real( iwork( 1_${ik}$ ),KIND=sp) ) if( wantz .and. info==0_${ik}$ ) then ! backtransform eigenvectors to the original problem. if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_ctrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, cone,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_ctrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, cone,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lopt rwork( 1_${ik}$ ) = lropt iwork( 1_${ik}$ ) = liopt return end subroutine stdlib${ii}$_chegvd module subroutine stdlib${ii}$_zhegvd( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, rwork, lrwork,& !! ZHEGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian and B is also positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: a(lda,*), b(ldb,*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: liopt, liwmin, lopt, lropt, lrwmin, lwmin ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then lwmin = 1_${ik}$ lrwmin = 1_${ik}$ liwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n + n*n lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n*n liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n + 1_${ik}$ lrwmin = n liwmin = 1_${ik}$ end if lopt = lwmin lropt = lrwmin liopt = liwmin if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lopt rwork( 1_${ik}$ ) = lropt iwork( 1_${ik}$ ) = liopt if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -13_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -15_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHEGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_zpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_zhegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_zheevd( jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork,iwork, liwork,& info ) lopt = max( real( lopt,KIND=dp), real( work( 1_${ik}$ ),KIND=dp) ) lropt = max( real( lropt,KIND=dp), real( rwork( 1_${ik}$ ),KIND=dp) ) liopt = max( real( liopt,KIND=dp), real( iwork( 1_${ik}$ ),KIND=dp) ) if( wantz .and. info==0_${ik}$ ) then ! backtransform eigenvectors to the original problem. if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_ztrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, cone,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_ztrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, cone,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lopt rwork( 1_${ik}$ ) = lropt iwork( 1_${ik}$ ) = liopt return end subroutine stdlib${ii}$_zhegvd #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hegvd( itype, jobz, uplo, n, a, lda, b, ldb, w, work,lwork, rwork, lrwork,& !! ZHEGVD: computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian and B is also positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, lda, ldb, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: a(lda,*), b(ldb,*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: liopt, liwmin, lopt, lropt, lrwmin, lwmin ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then lwmin = 1_${ik}$ lrwmin = 1_${ik}$ liwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n + n*n lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n*n liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n + 1_${ik}$ lrwmin = n liwmin = 1_${ik}$ end if lopt = lwmin lropt = lrwmin liopt = liwmin if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -6_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -8_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lopt rwork( 1_${ik}$ ) = lropt iwork( 1_${ik}$ ) = liopt if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -13_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -15_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHEGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ci}$potrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ci}$hegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_${ci}$heevd( jobz, uplo, n, a, lda, w, work, lwork, rwork, lrwork,iwork, liwork,& info ) lopt = max( real( lopt,KIND=${ck}$), real( work( 1_${ik}$ ),KIND=${ck}$) ) lropt = max( real( lropt,KIND=${ck}$), real( rwork( 1_${ik}$ ),KIND=${ck}$) ) liopt = max( real( liopt,KIND=${ck}$), real( iwork( 1_${ik}$ ),KIND=${ck}$) ) if( wantz .and. info==0_${ik}$ ) then ! backtransform eigenvectors to the original problem. if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_${ci}$trsm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, cone,b, ldb, a, lda ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_${ci}$trmm( 'LEFT', uplo, trans, 'NON-UNIT', n, n, cone,b, ldb, a, lda ) end if end if work( 1_${ik}$ ) = lopt rwork( 1_${ik}$ ) = lropt iwork( 1_${ik}$ ) = liopt return end subroutine stdlib${ii}$_${ci}$hegvd #:endif #:endfor module subroutine stdlib${ii}$_chegvx( itype, jobz, range, uplo, n, a, lda, b, ldb,vl, vu, il, iu, abstol,& !! CHEGVX computes selected eigenvalues, and optionally, eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian and B is also positive definite. !! Eigenvalues and eigenvectors can be selected by specifying either a !! range of values or a range of indices for the desired eigenvalues. m, w, z, ldz, work,lwork, rwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, lda, ldb, ldz, lwork, n integer(${ik}$), intent(out) :: info, m real(sp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: a(lda,*), b(ldb,*) complex(sp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, lquery, upper, valeig, wantz character :: trans integer(${ik}$) :: lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -9_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -11_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -13_${ik}$ end if end if end if if (info==0_${ik}$) then if (ldz<1_${ik}$ .or. (wantz .and. ldz<n)) then info = -18_${ik}$ end if end if if( info==0_${ik}$ ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( 1_${ik}$, ( nb + 1_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<max( 1_${ik}$, 2_${ik}$*n ) .and. .not.lquery ) then info = -20_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHEGVX', -info ) return else if( lquery ) then return end if ! quick return if possible m = 0_${ik}$ if( n==0_${ik}$ ) then return end if ! form a cholesky factorization of b. call stdlib${ii}$_cpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_chegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_cheevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,m, w, z, ldz, & work, lwork, rwork, iwork, ifail,info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_ctrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, cone, b,ldb, z, ldz ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h*y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_ctrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, cone, b,ldb, z, ldz ) end if end if ! set work(1) to optimal complex workspace size. work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_chegvx module subroutine stdlib${ii}$_zhegvx( itype, jobz, range, uplo, n, a, lda, b, ldb,vl, vu, il, iu, abstol,& !! ZHEGVX computes selected eigenvalues, and optionally, eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian and B is also positive definite. !! Eigenvalues and eigenvectors can be selected by specifying either a !! range of values or a range of indices for the desired eigenvalues. m, w, z, ldz, work,lwork, rwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, lda, ldb, ldz, lwork, n integer(${ik}$), intent(out) :: info, m real(dp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: a(lda,*), b(ldb,*) complex(dp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, lquery, upper, valeig, wantz character :: trans integer(${ik}$) :: lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -9_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -11_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -13_${ik}$ end if end if end if if (info==0_${ik}$) then if (ldz<1_${ik}$ .or. (wantz .and. ldz<n)) then info = -18_${ik}$ end if end if if( info==0_${ik}$ ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( 1_${ik}$, ( nb + 1_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<max( 1_${ik}$, 2_${ik}$*n ) .and. .not.lquery ) then info = -20_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHEGVX', -info ) return else if( lquery ) then return end if ! quick return if possible m = 0_${ik}$ if( n==0_${ik}$ ) then return end if ! form a cholesky factorization of b. call stdlib${ii}$_zpotrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_zhegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_zheevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,m, w, z, ldz, & work, lwork, rwork, iwork, ifail,info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_ztrsm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, cone, b,ldb, z, ldz ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_ztrmm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, cone, b,ldb, z, ldz ) end if end if ! set work(1) to optimal complex workspace size. work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_zhegvx #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hegvx( itype, jobz, range, uplo, n, a, lda, b, ldb,vl, vu, il, iu, abstol,& !! ZHEGVX: computes selected eigenvalues, and optionally, eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian and B is also positive definite. !! Eigenvalues and eigenvectors can be selected by specifying either a !! range of values or a range of indices for the desired eigenvalues. m, w, z, ldz, work,lwork, rwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, lda, ldb, ldz, lwork, n integer(${ik}$), intent(out) :: info, m real(${ck}$), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: a(lda,*), b(ldb,*) complex(${ck}$), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, lquery, upper, valeig, wantz character :: trans integer(${ik}$) :: lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) lquery = ( lwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -9_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -11_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -13_${ik}$ end if end if end if if (info==0_${ik}$) then if (ldz<1_${ik}$ .or. (wantz .and. ldz<n)) then info = -18_${ik}$ end if end if if( info==0_${ik}$ ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = max( 1_${ik}$, ( nb + 1_${ik}$ )*n ) work( 1_${ik}$ ) = lwkopt if( lwork<max( 1_${ik}$, 2_${ik}$*n ) .and. .not.lquery ) then info = -20_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHEGVX', -info ) return else if( lquery ) then return end if ! quick return if possible m = 0_${ik}$ if( n==0_${ik}$ ) then return end if ! form a cholesky factorization of b. call stdlib${ii}$_${ci}$potrf( uplo, n, b, ldb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ci}$hegst( itype, uplo, n, a, lda, b, ldb, info ) call stdlib${ii}$_${ci}$heevx( jobz, range, uplo, n, a, lda, vl, vu, il, iu, abstol,m, w, z, ldz, & work, lwork, rwork, iwork, ifail,info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if call stdlib${ii}$_${ci}$trsm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, cone, b,ldb, z, ldz ) else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if call stdlib${ii}$_${ci}$trmm( 'LEFT', uplo, trans, 'NON-UNIT', n, m, cone, b,ldb, z, ldz ) end if end if ! set work(1) to optimal complex workspace size. work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ci}$hegvx #:endif #:endfor module subroutine stdlib${ii}$_chpgv( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,rwork, info ) !! CHPGV computes all the eigenvalues and, optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be Hermitian, stored in packed format, !! and B is also positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, n ! Array Arguments real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: ap(*), bp(*) complex(sp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: trans integer(${ik}$) :: j, neig ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHPGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_cpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_chpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_chpev( jobz, uplo, n, ap, w, z, ldz, work, rwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, neig call stdlib${ii}$_ctpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h*y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_ctpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_chpgv module subroutine stdlib${ii}$_zhpgv( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,rwork, info ) !! ZHPGV computes all the eigenvalues and, optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be Hermitian, stored in packed format, !! and B is also positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, n ! Array Arguments real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: ap(*), bp(*) complex(dp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: trans integer(${ik}$) :: j, neig ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHPGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_zpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_zhpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_zhpev( jobz, uplo, n, ap, w, z, ldz, work, rwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, neig call stdlib${ii}$_ztpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_ztpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_zhpgv #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hpgv( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,rwork, info ) !! ZHPGV: computes all the eigenvalues and, optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. !! Here A and B are assumed to be Hermitian, stored in packed format, !! and B is also positive definite. ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, n ! Array Arguments real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: ap(*), bp(*) complex(${ck}$), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: trans integer(${ik}$) :: j, neig ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHPGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ci}$pptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ci}$hpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_${ci}$hpev( jobz, uplo, n, ap, w, z, ldz, work, rwork, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, neig call stdlib${ii}$_${ci}$tpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_${ci}$tpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_${ci}$hpgv #:endif #:endfor module subroutine stdlib${ii}$_chpgvd( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,lwork, rwork, lrwork,& !! CHPGVD computes all the eigenvalues and, optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian, stored in packed format, and B is also !! positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: ap(*), bp(*) complex(sp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: j, liwmin, lrwmin, lwmin, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then if( n<=1_${ik}$ ) then lwmin = 1_${ik}$ liwmin = 1_${ik}$ lrwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n lrwmin = n liwmin = 1_${ik}$ end if end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -13_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -15_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHPGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_cpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_chpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_chpevd( jobz, uplo, n, ap, w, z, ldz, work, lwork, rwork,lrwork, iwork, & liwork, info ) lwmin = max( real( lwmin,KIND=sp), real( work( 1_${ik}$ ),KIND=sp) ) lrwmin = max( real( lrwmin,KIND=sp), real( rwork( 1_${ik}$ ),KIND=sp) ) liwmin = max( real( liwmin,KIND=sp), real( iwork( 1_${ik}$ ),KIND=sp) ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, neig call stdlib${ii}$_ctpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_ctpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_chpgvd module subroutine stdlib${ii}$_zhpgvd( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,lwork, rwork, lrwork,& !! ZHPGVD computes all the eigenvalues and, optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian, stored in packed format, and B is also !! positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: ap(*), bp(*) complex(dp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: j, liwmin, lrwmin, lwmin, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then if( n<=1_${ik}$ ) then lwmin = 1_${ik}$ liwmin = 1_${ik}$ lrwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n lrwmin = n liwmin = 1_${ik}$ end if end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -13_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -15_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHPGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_zpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_zhpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_zhpevd( jobz, uplo, n, ap, w, z, ldz, work, lwork, rwork,lrwork, iwork, & liwork, info ) lwmin = max( real( lwmin,KIND=dp), real( work( 1_${ik}$ ),KIND=dp) ) lrwmin = max( real( lrwmin,KIND=dp), real( rwork( 1_${ik}$ ),KIND=dp) ) liwmin = max( real( liwmin,KIND=dp), real( iwork( 1_${ik}$ ),KIND=dp) ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, neig call stdlib${ii}$_ztpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_ztpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_zhpgvd #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hpgvd( itype, jobz, uplo, n, ap, bp, w, z, ldz, work,lwork, rwork, lrwork,& !! ZHPGVD: computes all the eigenvalues and, optionally, the eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian, stored in packed format, and B is also !! positive definite. !! If eigenvectors are desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. iwork, liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: itype, ldz, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: ap(*), bp(*) complex(${ck}$), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: trans integer(${ik}$) :: j, liwmin, lrwmin, lwmin, neig ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then if( n<=1_${ik}$ ) then lwmin = 1_${ik}$ liwmin = 1_${ik}$ lrwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n lrwmin = n liwmin = 1_${ik}$ end if end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -11_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -13_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -15_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHPGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ci}$pptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ci}$hpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_${ci}$hpevd( jobz, uplo, n, ap, w, z, ldz, work, lwork, rwork,lrwork, iwork, & liwork, info ) lwmin = max( real( lwmin,KIND=${ck}$), real( work( 1_${ik}$ ),KIND=${ck}$) ) lrwmin = max( real( lrwmin,KIND=${ck}$), real( rwork( 1_${ik}$ ),KIND=${ck}$) ) liwmin = max( real( liwmin,KIND=${ck}$), real( iwork( 1_${ik}$ ),KIND=${ck}$) ) if( wantz ) then ! backtransform eigenvectors to the original problem. neig = n if( info>0_${ik}$ )neig = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, neig call stdlib${ii}$_${ci}$tpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, neig call stdlib${ii}$_${ci}$tpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_${ci}$hpgvd #:endif #:endfor module subroutine stdlib${ii}$_chpgvx( itype, jobz, range, uplo, n, ap, bp, vl, vu,il, iu, abstol, m, w, & !! CHPGVX computes selected eigenvalues and, optionally, eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian, stored in packed format, and B is also !! positive definite. Eigenvalues and eigenvectors can be selected by !! specifying either a range of values or a range of indices for the !! desired eigenvalues. z, ldz, work, rwork,iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, ldz, n integer(${ik}$), intent(out) :: info, m real(sp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: ap(*), bp(*) complex(sp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, upper, valeig, wantz character :: trans integer(${ik}$) :: j ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl ) then info = -9_${ik}$ end if else if( indeig ) then if( il<1_${ik}$ ) then info = -10_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -11_${ik}$ end if end if end if if( info==0_${ik}$ ) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHPGVX', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_cpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_chpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_chpevx( jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m,w, z, ldz, & work, rwork, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h*y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, m call stdlib${ii}$_ctpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h*y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, m call stdlib${ii}$_ctpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_chpgvx module subroutine stdlib${ii}$_zhpgvx( itype, jobz, range, uplo, n, ap, bp, vl, vu,il, iu, abstol, m, w, & !! ZHPGVX computes selected eigenvalues and, optionally, eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian, stored in packed format, and B is also !! positive definite. Eigenvalues and eigenvectors can be selected by !! specifying either a range of values or a range of indices for the !! desired eigenvalues. z, ldz, work, rwork,iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, ldz, n integer(${ik}$), intent(out) :: info, m real(dp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: ap(*), bp(*) complex(dp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, upper, valeig, wantz character :: trans integer(${ik}$) :: j ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl ) then info = -9_${ik}$ end if else if( indeig ) then if( il<1_${ik}$ ) then info = -10_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -11_${ik}$ end if end if end if if( info==0_${ik}$ ) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHPGVX', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_zpptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_zhpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_zhpevx( jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m,w, z, ldz, & work, rwork, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, m call stdlib${ii}$_ztpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, m call stdlib${ii}$_ztpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_zhpgvx #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hpgvx( itype, jobz, range, uplo, n, ap, bp, vl, vu,il, iu, abstol, m, w, & !! ZHPGVX: computes selected eigenvalues and, optionally, eigenvectors !! of a complex generalized Hermitian-definite eigenproblem, of the form !! A*x=(lambda)*B*x, A*Bx=(lambda)*x, or B*A*x=(lambda)*x. Here A and !! B are assumed to be Hermitian, stored in packed format, and B is also !! positive definite. Eigenvalues and eigenvectors can be selected by !! specifying either a range of values or a range of indices for the !! desired eigenvalues. z, ldz, work, rwork,iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, itype, iu, ldz, n integer(${ik}$), intent(out) :: info, m real(${ck}$), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: ap(*), bp(*) complex(${ck}$), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, upper, valeig, wantz character :: trans integer(${ik}$) :: j ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( itype<1_${ik}$ .or. itype>3_${ik}$ ) then info = -1_${ik}$ else if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -2_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -3_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl ) then info = -9_${ik}$ end if else if( indeig ) then if( il<1_${ik}$ ) then info = -10_${ik}$ else if( iu<min( n, il ) .or. iu>n ) then info = -11_${ik}$ end if end if end if if( info==0_${ik}$ ) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -16_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHPGVX', -info ) return end if ! quick return if possible if( n==0 )return ! form a cholesky factorization of b. call stdlib${ii}$_${ci}$pptrf( uplo, n, bp, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem and solve. call stdlib${ii}$_${ci}$hpgst( itype, uplo, n, ap, bp, info ) call stdlib${ii}$_${ci}$hpevx( jobz, range, uplo, n, ap, vl, vu, il, iu, abstol, m,w, z, ldz, & work, rwork, iwork, ifail, info ) if( wantz ) then ! backtransform eigenvectors to the original problem. if( info>0_${ik}$ )m = info - 1_${ik}$ if( itype==1_${ik}$ .or. itype==2_${ik}$ ) then ! for a*x=(lambda)*b*x and a*b*x=(lambda)*x; ! backtransform eigenvectors: x = inv(l)**h *y or inv(u)*y if( upper ) then trans = 'N' else trans = 'C' end if do j = 1, m call stdlib${ii}$_${ci}$tpsv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do else if( itype==3_${ik}$ ) then ! for b*a*x=(lambda)*x; ! backtransform eigenvectors: x = l*y or u**h *y if( upper ) then trans = 'C' else trans = 'N' end if do j = 1, m call stdlib${ii}$_${ci}$tpmv( uplo, trans, 'NON-UNIT', n, bp, z( 1_${ik}$, j ),1_${ik}$ ) end do end if end if return end subroutine stdlib${ii}$_${ci}$hpgvx #:endif #:endfor pure module subroutine stdlib${ii}$_chbgv( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w, z,ldz, work, & !! CHBGV computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. rwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, n ! Array Arguments real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(sp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwrk ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHBGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_cpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n call stdlib${ii}$_chbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, rwork( & indwrk ), iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_chbtrd( vect, uplo, n, ka, ab, ldab, w, rwork( inde ), z,ldz, work, iinfo ) ! for eigenvalues only, call stdlib${ii}$_ssterf. for eigenvectors, call stdlib${ii}$_csteqr. if( .not.wantz ) then call stdlib${ii}$_ssterf( n, w, rwork( inde ), info ) else call stdlib${ii}$_csteqr( jobz, n, w, rwork( inde ), z, ldz,rwork( indwrk ), info ) end if return end subroutine stdlib${ii}$_chbgv pure module subroutine stdlib${ii}$_zhbgv( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w, z,ldz, work, & !! ZHBGV computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. rwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, n ! Array Arguments real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(dp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwrk ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHBGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_zpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n call stdlib${ii}$_zhbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, rwork( & indwrk ), iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_zhbtrd( vect, uplo, n, ka, ab, ldab, w, rwork( inde ), z,ldz, work, iinfo ) ! for eigenvalues only, call stdlib${ii}$_dsterf. for eigenvectors, call stdlib${ii}$_zsteqr. if( .not.wantz ) then call stdlib${ii}$_dsterf( n, w, rwork( inde ), info ) else call stdlib${ii}$_zsteqr( jobz, n, w, rwork( inde ), z, ldz,rwork( indwrk ), info ) end if return end subroutine stdlib${ii}$_zhbgv #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$hbgv( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w, z,ldz, work, & !! ZHBGV: computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. rwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, n ! Array Arguments real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(${ck}$), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwrk ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHBGV ', -info ) return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_${ci}$pbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n call stdlib${ii}$_${ci}$hbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, rwork( & indwrk ), iinfo ) ! reduce to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_${ci}$hbtrd( vect, uplo, n, ka, ab, ldab, w, rwork( inde ), z,ldz, work, iinfo ) ! for eigenvalues only, call stdlib${ii}$_${c2ri(ci)}$sterf. for eigenvectors, call stdlib${ii}$_${ci}$steqr. if( .not.wantz ) then call stdlib${ii}$_${c2ri(ci)}$sterf( n, w, rwork( inde ), info ) else call stdlib${ii}$_${ci}$steqr( jobz, n, w, rwork( inde ), z, ldz,rwork( indwrk ), info ) end if return end subroutine stdlib${ii}$_${ci}$hbgv #:endif #:endfor pure module subroutine stdlib${ii}$_chbgvd( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w,z, ldz, work, & !! CHBGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. If eigenvectors are !! desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. lwork, rwork, lrwork, iwork,liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(sp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwk2, indwrk, liwmin, llrwk, llwk2, lrwmin, & lwmin ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then lwmin = 1_${ik}$+n lrwmin = 1_${ik}$+n liwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n**2_${ik}$ lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n lrwmin = n liwmin = 1_${ik}$ end if if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -14_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -16_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -18_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHBGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_cpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n indwk2 = 1_${ik}$ + n*n llwk2 = lwork - indwk2 + 2_${ik}$ llrwk = lrwork - indwrk + 2_${ik}$ call stdlib${ii}$_chbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, rwork, & iinfo ) ! reduce hermitian band matrix to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_chbtrd( vect, uplo, n, ka, ab, ldab, w, rwork( inde ), z,ldz, work, iinfo ) ! for eigenvalues only, call stdlib${ii}$_ssterf. for eigenvectors, call stdlib${ii}$_cstedc. if( .not.wantz ) then call stdlib${ii}$_ssterf( n, w, rwork( inde ), info ) else call stdlib${ii}$_cstedc( 'I', n, w, rwork( inde ), work, n, work( indwk2 ),llwk2, rwork( & indwrk ), llrwk, iwork, liwork,info ) call stdlib${ii}$_cgemm( 'N', 'N', n, n, n, cone, z, ldz, work, n, czero,work( indwk2 ), & n ) call stdlib${ii}$_clacpy( 'A', n, n, work( indwk2 ), n, z, ldz ) end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_chbgvd pure module subroutine stdlib${ii}$_zhbgvd( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w,z, ldz, work, & !! ZHBGVD computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. If eigenvectors are !! desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. lwork, rwork, lrwork, iwork,liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(dp), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwk2, indwrk, liwmin, llrwk, llwk2, lrwmin, & lwmin ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then lwmin = 1_${ik}$+n lrwmin = 1_${ik}$+n liwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n**2_${ik}$ lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n lrwmin = n liwmin = 1_${ik}$ end if if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -14_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -16_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -18_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHBGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_zpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n indwk2 = 1_${ik}$ + n*n llwk2 = lwork - indwk2 + 2_${ik}$ llrwk = lrwork - indwrk + 2_${ik}$ call stdlib${ii}$_zhbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, rwork, & iinfo ) ! reduce hermitian band matrix to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_zhbtrd( vect, uplo, n, ka, ab, ldab, w, rwork( inde ), z,ldz, work, iinfo ) ! for eigenvalues only, call stdlib${ii}$_dsterf. for eigenvectors, call stdlib${ii}$_zstedc. if( .not.wantz ) then call stdlib${ii}$_dsterf( n, w, rwork( inde ), info ) else call stdlib${ii}$_zstedc( 'I', n, w, rwork( inde ), work, n, work( indwk2 ),llwk2, rwork( & indwrk ), llrwk, iwork, liwork,info ) call stdlib${ii}$_zgemm( 'N', 'N', n, n, n, cone, z, ldz, work, n, czero,work( indwk2 ), & n ) call stdlib${ii}$_zlacpy( 'A', n, n, work( indwk2 ), n, z, ldz ) end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_zhbgvd #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$hbgvd( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, w,z, ldz, work, & !! ZHBGVD: computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. If eigenvectors are !! desired, it uses a divide and conquer algorithm. !! The divide and conquer algorithm makes very mild assumptions about !! floating point arithmetic. It will work on machines with a guard !! digit in add/subtract, or on those binary machines without guard !! digits which subtract like the Cray X-MP, Cray Y-MP, Cray C-90, or !! Cray-2. It could conceivably fail on hexadecimal or decimal machines !! without guard digits, but we know of none. lwork, rwork, lrwork, iwork,liwork, info ) ! -- lapack driver 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) :: jobz, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ka, kb, ldab, ldbb, ldz, liwork, lrwork, lwork, n ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(${ck}$), intent(out) :: work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper, wantz character :: vect integer(${ik}$) :: iinfo, inde, indwk2, indwrk, liwmin, llrwk, llwk2, lrwmin, & lwmin ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ .or. lrwork==-1_${ik}$ .or. liwork==-1_${ik}$ ) info = 0_${ik}$ if( n<=1_${ik}$ ) then lwmin = 1_${ik}$+n lrwmin = 1_${ik}$+n liwmin = 1_${ik}$ else if( wantz ) then lwmin = 2_${ik}$*n**2_${ik}$ lrwmin = 1_${ik}$ + 5_${ik}$*n + 2_${ik}$*n**2_${ik}$ liwmin = 3_${ik}$ + 5_${ik}$*n else lwmin = n lrwmin = n liwmin = 1_${ik}$ end if if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -2_${ik}$ else if( n<0_${ik}$ ) then info = -3_${ik}$ else if( ka<0_${ik}$ ) then info = -4_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -5_${ik}$ else if( ldab<ka+1 ) then info = -7_${ik}$ else if( ldbb<kb+1 ) then info = -9_${ik}$ else if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin if( lwork<lwmin .and. .not.lquery ) then info = -14_${ik}$ else if( lrwork<lrwmin .and. .not.lquery ) then info = -16_${ik}$ else if( liwork<liwmin .and. .not.lquery ) then info = -18_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHBGVD', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_${ci}$pbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. inde = 1_${ik}$ indwrk = inde + n indwk2 = 1_${ik}$ + n*n llwk2 = lwork - indwk2 + 2_${ik}$ llrwk = lrwork - indwrk + 2_${ik}$ call stdlib${ii}$_${ci}$hbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, z, ldz,work, rwork, & iinfo ) ! reduce hermitian band matrix to tridiagonal form. if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_${ci}$hbtrd( vect, uplo, n, ka, ab, ldab, w, rwork( inde ), z,ldz, work, iinfo ) ! for eigenvalues only, call stdlib${ii}$_${c2ri(ci)}$sterf. for eigenvectors, call stdlib${ii}$_${ci}$stedc. if( .not.wantz ) then call stdlib${ii}$_${c2ri(ci)}$sterf( n, w, rwork( inde ), info ) else call stdlib${ii}$_${ci}$stedc( 'I', n, w, rwork( inde ), work, n, work( indwk2 ),llwk2, rwork( & indwrk ), llrwk, iwork, liwork,info ) call stdlib${ii}$_${ci}$gemm( 'N', 'N', n, n, n, cone, z, ldz, work, n, czero,work( indwk2 ), & n ) call stdlib${ii}$_${ci}$lacpy( 'A', n, n, work( indwk2 ), n, z, ldz ) end if work( 1_${ik}$ ) = lwmin rwork( 1_${ik}$ ) = lrwmin iwork( 1_${ik}$ ) = liwmin return end subroutine stdlib${ii}$_${ci}$hbgvd #:endif #:endfor pure module subroutine stdlib${ii}$_chbgvx( jobz, range, uplo, n, ka, kb, ab, ldab, bb,ldbb, q, ldq, vl, & !! CHBGVX computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. Eigenvalues and !! eigenvectors can be selected by specifying either all eigenvalues, !! a range of values or a range of indices for the desired eigenvalues. vu, il, iu, abstol, m, w, z,ldz, work, rwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, iu, ka, kb, ldab, ldbb, ldq, ldz, n integer(${ik}$), intent(out) :: info, m real(sp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(sp), intent(out) :: rwork(*), w(*) complex(sp), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(sp), intent(out) :: q(ldq,*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, test, upper, valeig, wantz character :: order, vect integer(${ik}$) :: i, iinfo, indd, inde, indee, indibl, indisp, indiwk, indrwk, indwrk, & itmp1, j, jj, nsplit real(sp) :: tmp1 ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ka<0_${ik}$ ) then info = -5_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -6_${ik}$ else if( ldab<ka+1 ) then info = -8_${ik}$ else if( ldbb<kb+1 ) then info = -10_${ik}$ else if( ldq<1_${ik}$ .or. ( wantz .and. ldq<n ) ) then info = -12_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -14_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -15_${ik}$ else if ( iu<min( n, il ) .or. iu>n ) then info = -16_${ik}$ end if end if end if if( info==0_${ik}$) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -21_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHBGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_cpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. call stdlib${ii}$_chbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,work, rwork, & iinfo ) ! solve the standard eigenvalue problem. ! reduce hermitian band matrix to tridiagonal form. indd = 1_${ik}$ inde = indd + n indrwk = inde + n indwrk = 1_${ik}$ if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_chbtrd( vect, uplo, n, ka, ab, ldab, rwork( indd ),rwork( inde ), q, ldq, & work( indwrk ), iinfo ) ! if all eigenvalues are desired and abstol is less than or equal ! to zero, then call stdlib${ii}$_ssterf or stdlib${ii}$_csteqr. if this fails for some ! eigenvalue, then try stdlib${ii}$_sstebz. test = .false. if( indeig ) then if( il==1_${ik}$ .and. iu==n ) then test = .true. end if end if if( ( alleig .or. test ) .and. ( abstol<=zero ) ) then call stdlib${ii}$_scopy( n, rwork( indd ), 1_${ik}$, w, 1_${ik}$ ) indee = indrwk + 2_${ik}$*n call stdlib${ii}$_scopy( n-1, rwork( inde ), 1_${ik}$, rwork( indee ), 1_${ik}$ ) if( .not.wantz ) then call stdlib${ii}$_ssterf( n, w, rwork( indee ), info ) else call stdlib${ii}$_clacpy( 'A', n, n, q, ldq, z, ldz ) call stdlib${ii}$_csteqr( jobz, n, w, rwork( indee ), z, ldz,rwork( indrwk ), info ) if( info==0_${ik}$ ) then do i = 1, n ifail( i ) = 0_${ik}$ end do end if end if if( info==0_${ik}$ ) then m = n go to 30 end if info = 0_${ik}$ end if ! otherwise, call stdlib${ii}$_sstebz and, if eigenvectors are desired, ! call stdlib${ii}$_cstein. if( wantz ) then order = 'B' else order = 'E' end if indibl = 1_${ik}$ indisp = indibl + n indiwk = indisp + n call stdlib${ii}$_sstebz( range, order, n, vl, vu, il, iu, abstol,rwork( indd ), rwork( inde & ), m, nsplit, w,iwork( indibl ), iwork( indisp ), rwork( indrwk ),iwork( indiwk ), & info ) if( wantz ) then call stdlib${ii}$_cstein( n, rwork( indd ), rwork( inde ), m, w,iwork( indibl ), iwork( & indisp ), z, ldz,rwork( indrwk ), iwork( indiwk ), ifail, info ) ! apply unitary matrix used in reduction to tridiagonal ! form to eigenvectors returned by stdlib${ii}$_cstein. do j = 1, m call stdlib${ii}$_ccopy( n, z( 1_${ik}$, j ), 1_${ik}$, work( 1_${ik}$ ), 1_${ik}$ ) call stdlib${ii}$_cgemv( 'N', n, n, cone, q, ldq, work, 1_${ik}$, czero,z( 1_${ik}$, j ), 1_${ik}$ ) end do end if 30 continue ! if eigenvalues are not in order, then sort them, along with ! eigenvectors. if( wantz ) then do j = 1, m - 1 i = 0_${ik}$ tmp1 = w( j ) do jj = j + 1, m if( w( jj )<tmp1 ) then i = jj tmp1 = w( jj ) end if end do if( i/=0_${ik}$ ) then itmp1 = iwork( indibl+i-1 ) w( i ) = w( j ) iwork( indibl+i-1 ) = iwork( indibl+j-1 ) w( j ) = tmp1 iwork( indibl+j-1 ) = itmp1 call stdlib${ii}$_cswap( n, z( 1_${ik}$, i ), 1_${ik}$, z( 1_${ik}$, j ), 1_${ik}$ ) if( info/=0_${ik}$ ) then itmp1 = ifail( i ) ifail( i ) = ifail( j ) ifail( j ) = itmp1 end if end if end do end if return end subroutine stdlib${ii}$_chbgvx pure module subroutine stdlib${ii}$_zhbgvx( jobz, range, uplo, n, ka, kb, ab, ldab, bb,ldbb, q, ldq, vl, & !! ZHBGVX computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. Eigenvalues and !! eigenvectors can be selected by specifying either all eigenvalues, !! a range of values or a range of indices for the desired eigenvalues. vu, il, iu, abstol, m, w, z,ldz, work, rwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, iu, ka, kb, ldab, ldbb, ldq, ldz, n integer(${ik}$), intent(out) :: info, m real(dp), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(dp), intent(out) :: rwork(*), w(*) complex(dp), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(dp), intent(out) :: q(ldq,*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, test, upper, valeig, wantz character :: order, vect integer(${ik}$) :: i, iinfo, indd, inde, indee, indibl, indisp, indiwk, indrwk, indwrk, & itmp1, j, jj, nsplit real(dp) :: tmp1 ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ka<0_${ik}$ ) then info = -5_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -6_${ik}$ else if( ldab<ka+1 ) then info = -8_${ik}$ else if( ldbb<kb+1 ) then info = -10_${ik}$ else if( ldq<1_${ik}$ .or. ( wantz .and. ldq<n ) ) then info = -12_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -14_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -15_${ik}$ else if ( iu<min( n, il ) .or. iu>n ) then info = -16_${ik}$ end if end if end if if( info==0_${ik}$) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -21_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHBGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_zpbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. call stdlib${ii}$_zhbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,work, rwork, & iinfo ) ! solve the standard eigenvalue problem. ! reduce hermitian band matrix to tridiagonal form. indd = 1_${ik}$ inde = indd + n indrwk = inde + n indwrk = 1_${ik}$ if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_zhbtrd( vect, uplo, n, ka, ab, ldab, rwork( indd ),rwork( inde ), q, ldq, & work( indwrk ), iinfo ) ! if all eigenvalues are desired and abstol is less than or equal ! to zero, then call stdlib${ii}$_dsterf or stdlib${ii}$_zsteqr. if this fails for some ! eigenvalue, then try stdlib${ii}$_dstebz. test = .false. if( indeig ) then if( il==1_${ik}$ .and. iu==n ) then test = .true. end if end if if( ( alleig .or. test ) .and. ( abstol<=zero ) ) then call stdlib${ii}$_dcopy( n, rwork( indd ), 1_${ik}$, w, 1_${ik}$ ) indee = indrwk + 2_${ik}$*n call stdlib${ii}$_dcopy( n-1, rwork( inde ), 1_${ik}$, rwork( indee ), 1_${ik}$ ) if( .not.wantz ) then call stdlib${ii}$_dsterf( n, w, rwork( indee ), info ) else call stdlib${ii}$_zlacpy( 'A', n, n, q, ldq, z, ldz ) call stdlib${ii}$_zsteqr( jobz, n, w, rwork( indee ), z, ldz,rwork( indrwk ), info ) if( info==0_${ik}$ ) then do i = 1, n ifail( i ) = 0_${ik}$ end do end if end if if( info==0_${ik}$ ) then m = n go to 30 end if info = 0_${ik}$ end if ! otherwise, call stdlib${ii}$_dstebz and, if eigenvectors are desired, ! call stdlib${ii}$_zstein. if( wantz ) then order = 'B' else order = 'E' end if indibl = 1_${ik}$ indisp = indibl + n indiwk = indisp + n call stdlib${ii}$_dstebz( range, order, n, vl, vu, il, iu, abstol,rwork( indd ), rwork( inde & ), m, nsplit, w,iwork( indibl ), iwork( indisp ), rwork( indrwk ),iwork( indiwk ), & info ) if( wantz ) then call stdlib${ii}$_zstein( n, rwork( indd ), rwork( inde ), m, w,iwork( indibl ), iwork( & indisp ), z, ldz,rwork( indrwk ), iwork( indiwk ), ifail, info ) ! apply unitary matrix used in reduction to tridiagonal ! form to eigenvectors returned by stdlib${ii}$_zstein. do j = 1, m call stdlib${ii}$_zcopy( n, z( 1_${ik}$, j ), 1_${ik}$, work( 1_${ik}$ ), 1_${ik}$ ) call stdlib${ii}$_zgemv( 'N', n, n, cone, q, ldq, work, 1_${ik}$, czero,z( 1_${ik}$, j ), 1_${ik}$ ) end do end if 30 continue ! if eigenvalues are not in order, then sort them, along with ! eigenvectors. if( wantz ) then do j = 1, m - 1 i = 0_${ik}$ tmp1 = w( j ) do jj = j + 1, m if( w( jj )<tmp1 ) then i = jj tmp1 = w( jj ) end if end do if( i/=0_${ik}$ ) then itmp1 = iwork( indibl+i-1 ) w( i ) = w( j ) iwork( indibl+i-1 ) = iwork( indibl+j-1 ) w( j ) = tmp1 iwork( indibl+j-1 ) = itmp1 call stdlib${ii}$_zswap( n, z( 1_${ik}$, i ), 1_${ik}$, z( 1_${ik}$, j ), 1_${ik}$ ) if( info/=0_${ik}$ ) then itmp1 = ifail( i ) ifail( i ) = ifail( j ) ifail( j ) = itmp1 end if end if end do end if return end subroutine stdlib${ii}$_zhbgvx #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$hbgvx( jobz, range, uplo, n, ka, kb, ab, ldab, bb,ldbb, q, ldq, vl, & !! ZHBGVX: computes all the eigenvalues, and optionally, the eigenvectors !! of a complex generalized Hermitian-definite banded eigenproblem, of !! the form A*x=(lambda)*B*x. Here A and B are assumed to be Hermitian !! and banded, and B is also positive definite. Eigenvalues and !! eigenvectors can be selected by specifying either all eigenvalues, !! a range of values or a range of indices for the desired eigenvalues. vu, il, iu, abstol, m, w, z,ldz, work, rwork, iwork, ifail, info ) ! -- lapack driver 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) :: jobz, range, uplo integer(${ik}$), intent(in) :: il, iu, ka, kb, ldab, ldbb, ldq, ldz, n integer(${ik}$), intent(out) :: info, m real(${ck}$), intent(in) :: abstol, vl, vu ! Array Arguments integer(${ik}$), intent(out) :: ifail(*), iwork(*) real(${ck}$), intent(out) :: rwork(*), w(*) complex(${ck}$), intent(inout) :: ab(ldab,*), bb(ldbb,*) complex(${ck}$), intent(out) :: q(ldq,*), work(*), z(ldz,*) ! ===================================================================== ! Local Scalars logical(lk) :: alleig, indeig, test, upper, valeig, wantz character :: order, vect integer(${ik}$) :: i, iinfo, indd, inde, indee, indibl, indisp, indiwk, indrwk, indwrk, & itmp1, j, jj, nsplit real(${ck}$) :: tmp1 ! Intrinsic Functions ! Executable Statements ! test the input parameters. wantz = stdlib_lsame( jobz, 'V' ) upper = stdlib_lsame( uplo, 'U' ) alleig = stdlib_lsame( range, 'A' ) valeig = stdlib_lsame( range, 'V' ) indeig = stdlib_lsame( range, 'I' ) info = 0_${ik}$ if( .not.( wantz .or. stdlib_lsame( jobz, 'N' ) ) ) then info = -1_${ik}$ else if( .not.( alleig .or. valeig .or. indeig ) ) then info = -2_${ik}$ else if( .not.( upper .or. stdlib_lsame( uplo, 'L' ) ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( ka<0_${ik}$ ) then info = -5_${ik}$ else if( kb<0_${ik}$ .or. kb>ka ) then info = -6_${ik}$ else if( ldab<ka+1 ) then info = -8_${ik}$ else if( ldbb<kb+1 ) then info = -10_${ik}$ else if( ldq<1_${ik}$ .or. ( wantz .and. ldq<n ) ) then info = -12_${ik}$ else if( valeig ) then if( n>0_${ik}$ .and. vu<=vl )info = -14_${ik}$ else if( indeig ) then if( il<1_${ik}$ .or. il>max( 1_${ik}$, n ) ) then info = -15_${ik}$ else if ( iu<min( n, il ) .or. iu>n ) then info = -16_${ik}$ end if end if end if if( info==0_${ik}$) then if( ldz<1_${ik}$ .or. ( wantz .and. ldz<n ) ) then info = -21_${ik}$ end if end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHBGVX', -info ) return end if ! quick return if possible m = 0_${ik}$ if( n==0 )return ! form a split cholesky factorization of b. call stdlib${ii}$_${ci}$pbstf( uplo, n, kb, bb, ldbb, info ) if( info/=0_${ik}$ ) then info = n + info return end if ! transform problem to standard eigenvalue problem. call stdlib${ii}$_${ci}$hbgst( jobz, uplo, n, ka, kb, ab, ldab, bb, ldbb, q, ldq,work, rwork, & iinfo ) ! solve the standard eigenvalue problem. ! reduce hermitian band matrix to tridiagonal form. indd = 1_${ik}$ inde = indd + n indrwk = inde + n indwrk = 1_${ik}$ if( wantz ) then vect = 'U' else vect = 'N' end if call stdlib${ii}$_${ci}$hbtrd( vect, uplo, n, ka, ab, ldab, rwork( indd ),rwork( inde ), q, ldq, & work( indwrk ), iinfo ) ! if all eigenvalues are desired and abstol is less than or equal ! to zero, then call stdlib${ii}$_${c2ri(ci)}$sterf or stdlib${ii}$_${ci}$steqr. if this fails for some ! eigenvalue, then try stdlib${ii}$_${c2ri(ci)}$stebz. test = .false. if( indeig ) then if( il==1_${ik}$ .and. iu==n ) then test = .true. end if end if if( ( alleig .or. test ) .and. ( abstol<=zero ) ) then call stdlib${ii}$_${c2ri(ci)}$copy( n, rwork( indd ), 1_${ik}$, w, 1_${ik}$ ) indee = indrwk + 2_${ik}$*n call stdlib${ii}$_${c2ri(ci)}$copy( n-1, rwork( inde ), 1_${ik}$, rwork( indee ), 1_${ik}$ ) if( .not.wantz ) then call stdlib${ii}$_${c2ri(ci)}$sterf( n, w, rwork( indee ), info ) else call stdlib${ii}$_${ci}$lacpy( 'A', n, n, q, ldq, z, ldz ) call stdlib${ii}$_${ci}$steqr( jobz, n, w, rwork( indee ), z, ldz,rwork( indrwk ), info ) if( info==0_${ik}$ ) then do i = 1, n ifail( i ) = 0_${ik}$ end do end if end if if( info==0_${ik}$ ) then m = n go to 30 end if info = 0_${ik}$ end if ! otherwise, call stdlib${ii}$_${c2ri(ci)}$stebz and, if eigenvectors are desired, ! call stdlib${ii}$_${ci}$stein. if( wantz ) then order = 'B' else order = 'E' end if indibl = 1_${ik}$ indisp = indibl + n indiwk = indisp + n call stdlib${ii}$_${c2ri(ci)}$stebz( range, order, n, vl, vu, il, iu, abstol,rwork( indd ), rwork( inde & ), m, nsplit, w,iwork( indibl ), iwork( indisp ), rwork( indrwk ),iwork( indiwk ), & info ) if( wantz ) then call stdlib${ii}$_${ci}$stein( n, rwork( indd ), rwork( inde ), m, w,iwork( indibl ), iwork( & indisp ), z, ldz,rwork( indrwk ), iwork( indiwk ), ifail, info ) ! apply unitary matrix used in reduction to tridiagonal ! form to eigenvectors returned by stdlib${ii}$_${ci}$stein. do j = 1, m call stdlib${ii}$_${ci}$copy( n, z( 1_${ik}$, j ), 1_${ik}$, work( 1_${ik}$ ), 1_${ik}$ ) call stdlib${ii}$_${ci}$gemv( 'N', n, n, cone, q, ldq, work, 1_${ik}$, czero,z( 1_${ik}$, j ), 1_${ik}$ ) end do end if 30 continue ! if eigenvalues are not in order, then sort them, along with ! eigenvectors. if( wantz ) then do j = 1, m - 1 i = 0_${ik}$ tmp1 = w( j ) do jj = j + 1, m if( w( jj )<tmp1 ) then i = jj tmp1 = w( jj ) end if end do if( i/=0_${ik}$ ) then itmp1 = iwork( indibl+i-1 ) w( i ) = w( j ) iwork( indibl+i-1 ) = iwork( indibl+j-1 ) w( j ) = tmp1 iwork( indibl+j-1 ) = itmp1 call stdlib${ii}$_${ci}$swap( n, z( 1_${ik}$, i ), 1_${ik}$, z( 1_${ik}$, j ), 1_${ik}$ ) if( info/=0_${ik}$ ) then itmp1 = ifail( i ) ifail( i ) = ifail( j ) ifail( j ) = itmp1 end if end if end do end if return end subroutine stdlib${ii}$_${ci}$hbgvx #:endif #:endfor pure module subroutine stdlib${ii}$_chetrd( uplo, n, a, lda, d, e, tau, work, lwork, info ) !! CHETRD reduces a complex Hermitian matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(sp), intent(out) :: d(*), e(*) complex(sp), intent(inout) :: a(lda,*) complex(sp), intent(out) :: tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, iws, j, kk, ldwork, lwkopt, nb, nbmin, nx ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<1_${ik}$ .and. .not.lquery ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then ! determine the block size. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHETRD', -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 nx = n iws = 1_${ik}$ if( nb>1_${ik}$ .and. nb<n ) then ! determine when to cross over from blocked to unblocked code ! (last block is always handled by unblocked code). nx = max( nb, stdlib${ii}$_ilaenv( 3_${ik}$, 'CHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) if( nx<n ) 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: determine the ! minimum value of nb, and reduce nb or force use of ! unblocked code by setting nx = n. nb = max( lwork / ldwork, 1_${ik}$ ) nbmin = stdlib${ii}$_ilaenv( 2_${ik}$, 'CHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) if( nb<nbmin )nx = n end if else nx = n end if else nb = 1_${ik}$ end if if( upper ) then ! reduce the upper triangle of a. ! columns 1:kk are handled by the unblocked method. kk = n - ( ( n-nx+nb-1 ) / nb )*nb do i = n - nb + 1, kk + 1, -nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_clatrd( uplo, i+nb-1, nb, a, lda, e, tau, work,ldwork ) ! update the unreduced submatrix a(1:i-1,1:i-1), using an ! update of the form: a := a - v*w**h - w*v**h call stdlib${ii}$_cher2k( uplo, 'NO TRANSPOSE', i-1, nb, -cone,a( 1_${ik}$, i ), lda, work, & ldwork, one, a, lda ) ! copy superdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j-1, j ) = e( j-1 ) d( j ) = real( a( j, j ),KIND=sp) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_chetd2( uplo, kk, a, lda, d, e, tau, iinfo ) else ! reduce the lower triangle of a do i = 1, n - nx, nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_clatrd( uplo, n-i+1, nb, a( i, i ), lda, e( i ),tau( i ), work, & ldwork ) ! update the unreduced submatrix a(i+nb:n,i+nb:n), using ! an update of the form: a := a - v*w**h - w*v**h call stdlib${ii}$_cher2k( uplo, 'NO TRANSPOSE', n-i-nb+1, nb, -cone,a( i+nb, i ), lda, & work( nb+1 ), ldwork, one,a( i+nb, i+nb ), lda ) ! copy subdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j+1, j ) = e( j ) d( j ) = real( a( j, j ),KIND=sp) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_chetd2( uplo, n-i+1, a( i, i ), lda, d( i ), e( i ),tau( i ), iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_chetrd pure module subroutine stdlib${ii}$_zhetrd( uplo, n, a, lda, d, e, tau, work, lwork, info ) !! ZHETRD reduces a complex Hermitian matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(dp), intent(out) :: d(*), e(*) complex(dp), intent(inout) :: a(lda,*) complex(dp), intent(out) :: tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, iws, j, kk, ldwork, lwkopt, nb, nbmin, nx ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<1_${ik}$ .and. .not.lquery ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then ! determine the block size. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETRD', -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 nx = n iws = 1_${ik}$ if( nb>1_${ik}$ .and. nb<n ) then ! determine when to cross over from blocked to unblocked code ! (last block is always handled by unblocked code). nx = max( nb, stdlib${ii}$_ilaenv( 3_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) if( nx<n ) 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: determine the ! minimum value of nb, and reduce nb or force use of ! unblocked code by setting nx = n. nb = max( lwork / ldwork, 1_${ik}$ ) nbmin = stdlib${ii}$_ilaenv( 2_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) if( nb<nbmin )nx = n end if else nx = n end if else nb = 1_${ik}$ end if if( upper ) then ! reduce the upper triangle of a. ! columns 1:kk are handled by the unblocked method. kk = n - ( ( n-nx+nb-1 ) / nb )*nb do i = n - nb + 1, kk + 1, -nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_zlatrd( uplo, i+nb-1, nb, a, lda, e, tau, work,ldwork ) ! update the unreduced submatrix a(1:i-1,1:i-1), using an ! update of the form: a := a - v*w**h - w*v**h call stdlib${ii}$_zher2k( uplo, 'NO TRANSPOSE', i-1, nb, -cone,a( 1_${ik}$, i ), lda, work, & ldwork, one, a, lda ) ! copy superdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j-1, j ) = e( j-1 ) d( j ) = real( a( j, j ),KIND=dp) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_zhetd2( uplo, kk, a, lda, d, e, tau, iinfo ) else ! reduce the lower triangle of a do i = 1, n - nx, nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_zlatrd( uplo, n-i+1, nb, a( i, i ), lda, e( i ),tau( i ), work, & ldwork ) ! update the unreduced submatrix a(i+nb:n,i+nb:n), using ! an update of the form: a := a - v*w**h - w*v**h call stdlib${ii}$_zher2k( uplo, 'NO TRANSPOSE', n-i-nb+1, nb, -cone,a( i+nb, i ), lda, & work( nb+1 ), ldwork, one,a( i+nb, i+nb ), lda ) ! copy subdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j+1, j ) = e( j ) d( j ) = real( a( j, j ),KIND=dp) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_zhetd2( uplo, n-i+1, a( i, i ), lda, d( i ), e( i ),tau( i ), iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_zhetrd #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$hetrd( uplo, n, a, lda, d, e, tau, work, lwork, info ) !! ZHETRD: reduces a complex Hermitian matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments real(${ck}$), intent(out) :: d(*), e(*) complex(${ck}$), intent(inout) :: a(lda,*) complex(${ck}$), intent(out) :: tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, iws, j, kk, ldwork, lwkopt, nb, nbmin, nx ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<1_${ik}$ .and. .not.lquery ) then info = -9_${ik}$ end if if( info==0_${ik}$ ) then ! determine the block size. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETRD', -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 nx = n iws = 1_${ik}$ if( nb>1_${ik}$ .and. nb<n ) then ! determine when to cross over from blocked to unblocked code ! (last block is always handled by unblocked code). nx = max( nb, stdlib${ii}$_ilaenv( 3_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) if( nx<n ) 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: determine the ! minimum value of nb, and reduce nb or force use of ! unblocked code by setting nx = n. nb = max( lwork / ldwork, 1_${ik}$ ) nbmin = stdlib${ii}$_ilaenv( 2_${ik}$, 'ZHETRD', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) if( nb<nbmin )nx = n end if else nx = n end if else nb = 1_${ik}$ end if if( upper ) then ! reduce the upper triangle of a. ! columns 1:kk are handled by the unblocked method. kk = n - ( ( n-nx+nb-1 ) / nb )*nb do i = n - nb + 1, kk + 1, -nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_${ci}$latrd( uplo, i+nb-1, nb, a, lda, e, tau, work,ldwork ) ! update the unreduced submatrix a(1:i-1,1:i-1), using an ! update of the form: a := a - v*w**h - w*v**h call stdlib${ii}$_${ci}$her2k( uplo, 'NO TRANSPOSE', i-1, nb, -cone,a( 1_${ik}$, i ), lda, work, & ldwork, one, a, lda ) ! copy superdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j-1, j ) = e( j-1 ) d( j ) = real( a( j, j ),KIND=${ck}$) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_${ci}$hetd2( uplo, kk, a, lda, d, e, tau, iinfo ) else ! reduce the lower triangle of a do i = 1, n - nx, nb ! reduce columns i:i+nb-1 to tridiagonal form and form the ! matrix w which is needed to update the unreduced part of ! the matrix call stdlib${ii}$_${ci}$latrd( uplo, n-i+1, nb, a( i, i ), lda, e( i ),tau( i ), work, & ldwork ) ! update the unreduced submatrix a(i+nb:n,i+nb:n), using ! an update of the form: a := a - v*w**h - w*v**h call stdlib${ii}$_${ci}$her2k( uplo, 'NO TRANSPOSE', n-i-nb+1, nb, -cone,a( i+nb, i ), lda, & work( nb+1 ), ldwork, one,a( i+nb, i+nb ), lda ) ! copy subdiagonal elements back into a, and diagonal ! elements into d do j = i, i + nb - 1 a( j+1, j ) = e( j ) d( j ) = real( a( j, j ),KIND=${ck}$) end do end do ! use unblocked code to reduce the last or only block call stdlib${ii}$_${ci}$hetd2( uplo, n-i+1, a( i, i ), lda, d( i ), e( i ),tau( i ), iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ci}$hetrd #:endif #:endfor pure module subroutine stdlib${ii}$_chetd2( uplo, n, a, lda, d, e, tau, info ) !! CHETD2 reduces a complex Hermitian matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments real(sp), intent(out) :: d(*), e(*) complex(sp), intent(inout) :: a(lda,*) complex(sp), intent(out) :: tau(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i complex(sp) :: alpha, taui ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHETD2', -info ) return end if ! quick return if possible if( n<=0 )return if( upper ) then ! reduce the upper triangle of a a( n, n ) = real( a( n, n ),KIND=sp) do i = n - 1, 1, -1 ! generate elementary reflector h(i) = i - tau * v * v**h ! to annihilate a(1:i-1,i+1) alpha = a( i, i+1 ) call stdlib${ii}$_clarfg( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, taui ) e( i ) = real( alpha,KIND=sp) if( taui/=czero ) then ! apply h(i) from both sides to a(1:i,1:i) a( i, i+1 ) = cone ! compute x := tau * a * v storing x in tau(1:i) call stdlib${ii}$_chemv( uplo, i, taui, a, lda, a( 1_${ik}$, i+1 ), 1_${ik}$, czero,tau, 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**h * v) * v alpha = -chalf*taui*stdlib${ii}$_cdotc( i, tau, 1_${ik}$, a( 1_${ik}$, i+1 ), 1_${ik}$ ) call stdlib${ii}$_caxpy( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**h - w * v**h call stdlib${ii}$_cher2( uplo, i, -cone, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$, a,lda ) else a( i, i ) = real( a( i, i ),KIND=sp) end if a( i, i+1 ) = e( i ) d( i+1 ) = real( a( i+1, i+1 ),KIND=sp) tau( i ) = taui end do d( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=sp) else ! reduce the lower triangle of a a( 1_${ik}$, 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=sp) do i = 1, n - 1 ! generate elementary reflector h(i) = i - tau * v * v**h ! to annihilate a(i+2:n,i) alpha = a( i+1, i ) call stdlib${ii}$_clarfg( n-i, alpha, a( min( i+2, n ), i ), 1_${ik}$, taui ) e( i ) = real( alpha,KIND=sp) if( taui/=czero ) then ! apply h(i) from both sides to a(i+1:n,i+1:n) a( i+1, i ) = cone ! compute x := tau * a * v storing y in tau(i:n-1) call stdlib${ii}$_chemv( uplo, n-i, taui, a( i+1, i+1 ), lda,a( i+1, i ), 1_${ik}$, czero, & tau( i ), 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**h * v) * v alpha = -chalf*taui*stdlib${ii}$_cdotc( n-i, tau( i ), 1_${ik}$, a( i+1, i ),1_${ik}$ ) call stdlib${ii}$_caxpy( n-i, alpha, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**h - w * v**h call stdlib${ii}$_cher2( uplo, n-i, -cone, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$,a( i+1, i+1 )& , lda ) else a( i+1, i+1 ) = real( a( i+1, i+1 ),KIND=sp) end if a( i+1, i ) = e( i ) d( i ) = real( a( i, i ),KIND=sp) tau( i ) = taui end do d( n ) = real( a( n, n ),KIND=sp) end if return end subroutine stdlib${ii}$_chetd2 pure module subroutine stdlib${ii}$_zhetd2( uplo, n, a, lda, d, e, tau, info ) !! ZHETD2 reduces a complex Hermitian matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments real(dp), intent(out) :: d(*), e(*) complex(dp), intent(inout) :: a(lda,*) complex(dp), intent(out) :: tau(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i complex(dp) :: alpha, taui ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U') if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETD2', -info ) return end if ! quick return if possible if( n<=0 )return if( upper ) then ! reduce the upper triangle of a a( n, n ) = real( a( n, n ),KIND=dp) do i = n - 1, 1, -1 ! generate elementary reflector h(i) = i - tau * v * v**h ! to annihilate a(1:i-1,i+1) alpha = a( i, i+1 ) call stdlib${ii}$_zlarfg( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, taui ) e( i ) = real( alpha,KIND=dp) if( taui/=czero ) then ! apply h(i) from both sides to a(1:i,1:i) a( i, i+1 ) = cone ! compute x := tau * a * v storing x in tau(1:i) call stdlib${ii}$_zhemv( uplo, i, taui, a, lda, a( 1_${ik}$, i+1 ), 1_${ik}$, czero,tau, 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**h * v) * v alpha = -chalf*taui*stdlib${ii}$_zdotc( i, tau, 1_${ik}$, a( 1_${ik}$, i+1 ), 1_${ik}$ ) call stdlib${ii}$_zaxpy( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**h - w * v**h call stdlib${ii}$_zher2( uplo, i, -cone, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$, a,lda ) else a( i, i ) = real( a( i, i ),KIND=dp) end if a( i, i+1 ) = e( i ) d( i+1 ) = real( a( i+1, i+1 ),KIND=dp) tau( i ) = taui end do d( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=dp) else ! reduce the lower triangle of a a( 1_${ik}$, 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=dp) do i = 1, n - 1 ! generate elementary reflector h(i) = i - tau * v * v**h ! to annihilate a(i+2:n,i) alpha = a( i+1, i ) call stdlib${ii}$_zlarfg( n-i, alpha, a( min( i+2, n ), i ), 1_${ik}$, taui ) e( i ) = real( alpha,KIND=dp) if( taui/=czero ) then ! apply h(i) from both sides to a(i+1:n,i+1:n) a( i+1, i ) = cone ! compute x := tau * a * v storing y in tau(i:n-1) call stdlib${ii}$_zhemv( uplo, n-i, taui, a( i+1, i+1 ), lda,a( i+1, i ), 1_${ik}$, czero, & tau( i ), 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**h * v) * v alpha = -chalf*taui*stdlib${ii}$_zdotc( n-i, tau( i ), 1_${ik}$, a( i+1, i ),1_${ik}$ ) call stdlib${ii}$_zaxpy( n-i, alpha, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**h - w * v**h call stdlib${ii}$_zher2( uplo, n-i, -cone, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$,a( i+1, i+1 )& , lda ) else a( i+1, i+1 ) = real( a( i+1, i+1 ),KIND=dp) end if a( i+1, i ) = e( i ) d( i ) = real( a( i, i ),KIND=dp) tau( i ) = taui end do d( n ) = real( a( n, n ),KIND=dp) end if return end subroutine stdlib${ii}$_zhetd2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$hetd2( uplo, n, a, lda, d, e, tau, info ) !! ZHETD2: reduces a complex Hermitian matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments real(${ck}$), intent(out) :: d(*), e(*) complex(${ck}$), intent(inout) :: a(lda,*) complex(${ck}$), intent(out) :: tau(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i complex(${ck}$) :: alpha, taui ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U') if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETD2', -info ) return end if ! quick return if possible if( n<=0 )return if( upper ) then ! reduce the upper triangle of a a( n, n ) = real( a( n, n ),KIND=${ck}$) do i = n - 1, 1, -1 ! generate elementary reflector h(i) = i - tau * v * v**h ! to annihilate a(1:i-1,i+1) alpha = a( i, i+1 ) call stdlib${ii}$_${ci}$larfg( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, taui ) e( i ) = real( alpha,KIND=${ck}$) if( taui/=czero ) then ! apply h(i) from both sides to a(1:i,1:i) a( i, i+1 ) = cone ! compute x := tau * a * v storing x in tau(1:i) call stdlib${ii}$_${ci}$hemv( uplo, i, taui, a, lda, a( 1_${ik}$, i+1 ), 1_${ik}$, czero,tau, 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**h * v) * v alpha = -chalf*taui*stdlib${ii}$_${ci}$dotc( i, tau, 1_${ik}$, a( 1_${ik}$, i+1 ), 1_${ik}$ ) call stdlib${ii}$_${ci}$axpy( i, alpha, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**h - w * v**h call stdlib${ii}$_${ci}$her2( uplo, i, -cone, a( 1_${ik}$, i+1 ), 1_${ik}$, tau, 1_${ik}$, a,lda ) else a( i, i ) = real( a( i, i ),KIND=${ck}$) end if a( i, i+1 ) = e( i ) d( i+1 ) = real( a( i+1, i+1 ),KIND=${ck}$) tau( i ) = taui end do d( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=${ck}$) else ! reduce the lower triangle of a a( 1_${ik}$, 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=${ck}$) do i = 1, n - 1 ! generate elementary reflector h(i) = i - tau * v * v**h ! to annihilate a(i+2:n,i) alpha = a( i+1, i ) call stdlib${ii}$_${ci}$larfg( n-i, alpha, a( min( i+2, n ), i ), 1_${ik}$, taui ) e( i ) = real( alpha,KIND=${ck}$) if( taui/=czero ) then ! apply h(i) from both sides to a(i+1:n,i+1:n) a( i+1, i ) = cone ! compute x := tau * a * v storing y in tau(i:n-1) call stdlib${ii}$_${ci}$hemv( uplo, n-i, taui, a( i+1, i+1 ), lda,a( i+1, i ), 1_${ik}$, czero, & tau( i ), 1_${ik}$ ) ! compute w := x - 1/2 * tau * (x**h * v) * v alpha = -chalf*taui*stdlib${ii}$_${ci}$dotc( n-i, tau( i ), 1_${ik}$, a( i+1, i ),1_${ik}$ ) call stdlib${ii}$_${ci}$axpy( n-i, alpha, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$ ) ! apply the transformation as a rank-2 update: ! a := a - v * w**h - w * v**h call stdlib${ii}$_${ci}$her2( uplo, n-i, -cone, a( i+1, i ), 1_${ik}$, tau( i ), 1_${ik}$,a( i+1, i+1 )& , lda ) else a( i+1, i+1 ) = real( a( i+1, i+1 ),KIND=${ck}$) end if a( i+1, i ) = e( i ) d( i ) = real( a( i, i ),KIND=${ck}$) tau( i ) = taui end do d( n ) = real( a( n, n ),KIND=${ck}$) end if return end subroutine stdlib${ii}$_${ci}$hetd2 #:endif #:endfor pure module subroutine stdlib${ii}$_cungtr( uplo, n, a, lda, tau, work, lwork, info ) !! CUNGTR generates a complex unitary matrix Q which is defined as the !! product of n-1 elementary reflectors of order N, as returned by !! CHETRD: !! if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), !! if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments complex(sp), intent(inout) :: a(lda,*) complex(sp), intent(in) :: tau(*) complex(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, j, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ lquery = ( lwork==-1_${ik}$ ) upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<max( 1_${ik}$, n-1 ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info==0_${ik}$ ) then if ( upper ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNGQL', ' ', n-1, n-1, n-1, -1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNGQR', ' ', n-1, n-1, n-1, -1_${ik}$ ) end if lwkopt = max( 1_${ik}$, n-1 )*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CUNGTR', -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 if( upper ) then ! q was determined by a call to stdlib${ii}$_chetrd with uplo = 'u' ! shift the vectors which define the elementary reflectors cone ! column to the left, and set the last row and column of q to ! those of the unit matrix do j = 1, n - 1 do i = 1, j - 1 a( i, j ) = a( i, j+1 ) end do a( n, j ) = czero end do do i = 1, n - 1 a( i, n ) = czero end do a( n, n ) = cone ! generate q(1:n-1,1:n-1) call stdlib${ii}$_cungql( n-1, n-1, n-1, a, lda, tau, work, lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_chetrd with uplo = 'l'. ! shift the vectors which define the elementary reflectors cone ! column to the right, and set the first row and column of q to ! those of the unit matrix do j = n, 2, -1 a( 1_${ik}$, j ) = czero do i = j + 1, n a( i, j ) = a( i, j-1 ) end do end do a( 1_${ik}$, 1_${ik}$ ) = cone do i = 2, n a( i, 1_${ik}$ ) = czero end do if( n>1_${ik}$ ) then ! generate q(2:n,2:n) call stdlib${ii}$_cungqr( n-1, n-1, n-1, a( 2_${ik}$, 2_${ik}$ ), lda, tau, work,lwork, iinfo ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_cungtr pure module subroutine stdlib${ii}$_zungtr( uplo, n, a, lda, tau, work, lwork, info ) !! ZUNGTR generates a complex unitary matrix Q which is defined as the !! product of n-1 elementary reflectors of order N, as returned by !! ZHETRD: !! if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), !! if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments complex(dp), intent(inout) :: a(lda,*) complex(dp), intent(in) :: tau(*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, j, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ lquery = ( lwork==-1_${ik}$ ) upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<max( 1_${ik}$, n-1 ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNGQL', ' ', n-1, n-1, n-1, -1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNGQR', ' ', n-1, n-1, n-1, -1_${ik}$ ) end if lwkopt = max( 1_${ik}$, n-1 )*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZUNGTR', -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 if( upper ) then ! q was determined by a call to stdlib${ii}$_zhetrd with uplo = 'u' ! shift the vectors which define the elementary reflectors cone ! column to the left, and set the last row and column of q to ! those of the unit matrix do j = 1, n - 1 do i = 1, j - 1 a( i, j ) = a( i, j+1 ) end do a( n, j ) = czero end do do i = 1, n - 1 a( i, n ) = czero end do a( n, n ) = cone ! generate q(1:n-1,1:n-1) call stdlib${ii}$_zungql( n-1, n-1, n-1, a, lda, tau, work, lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_zhetrd with uplo = 'l'. ! shift the vectors which define the elementary reflectors cone ! column to the right, and set the first row and column of q to ! those of the unit matrix do j = n, 2, -1 a( 1_${ik}$, j ) = czero do i = j + 1, n a( i, j ) = a( i, j-1 ) end do end do a( 1_${ik}$, 1_${ik}$ ) = cone do i = 2, n a( i, 1_${ik}$ ) = czero end do if( n>1_${ik}$ ) then ! generate q(2:n,2:n) call stdlib${ii}$_zungqr( n-1, n-1, n-1, a( 2_${ik}$, 2_${ik}$ ), lda, tau, work,lwork, iinfo ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_zungtr #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$ungtr( uplo, n, a, lda, tau, work, lwork, info ) !! ZUNGTR: generates a complex unitary matrix Q which is defined as the !! product of n-1 elementary reflectors of order N, as returned by !! ZHETRD: !! if UPLO = 'U', Q = H(n-1) . . . H(2) H(1), !! if UPLO = 'L', Q = H(1) H(2) . . . H(n-1). ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, lwork, n ! Array Arguments complex(${ck}$), intent(inout) :: a(lda,*) complex(${ck}$), intent(in) :: tau(*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, iinfo, j, lwkopt, nb ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ lquery = ( lwork==-1_${ik}$ ) upper = stdlib_lsame( uplo, 'U' ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -4_${ik}$ else if( lwork<max( 1_${ik}$, n-1 ) .and. .not.lquery ) then info = -7_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNGQL', ' ', n-1, n-1, n-1, -1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNGQR', ' ', n-1, n-1, n-1, -1_${ik}$ ) end if lwkopt = max( 1_${ik}$, n-1 )*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZUNGTR', -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 if( upper ) then ! q was determined by a call to stdlib${ii}$_${ci}$hetrd with uplo = 'u' ! shift the vectors which define the elementary reflectors cone ! column to the left, and set the last row and column of q to ! those of the unit matrix do j = 1, n - 1 do i = 1, j - 1 a( i, j ) = a( i, j+1 ) end do a( n, j ) = czero end do do i = 1, n - 1 a( i, n ) = czero end do a( n, n ) = cone ! generate q(1:n-1,1:n-1) call stdlib${ii}$_${ci}$ungql( n-1, n-1, n-1, a, lda, tau, work, lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_${ci}$hetrd with uplo = 'l'. ! shift the vectors which define the elementary reflectors cone ! column to the right, and set the first row and column of q to ! those of the unit matrix do j = n, 2, -1 a( 1_${ik}$, j ) = czero do i = j + 1, n a( i, j ) = a( i, j-1 ) end do end do a( 1_${ik}$, 1_${ik}$ ) = cone do i = 2, n a( i, 1_${ik}$ ) = czero end do if( n>1_${ik}$ ) then ! generate q(2:n,2:n) call stdlib${ii}$_${ci}$ungqr( n-1, n-1, n-1, a( 2_${ik}$, 2_${ik}$ ), lda, tau, work,lwork, iinfo ) end if end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ci}$ungtr #:endif #:endfor pure module subroutine stdlib${ii}$_cunmtr( side, uplo, trans, m, n, a, lda, tau, c, ldc,work, lwork, & !! CUNMTR 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 of order nq, with nq = m if !! SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of !! nq-1 elementary reflectors, as returned by CHETRD: !! if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); !! if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). 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, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: 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(*) ! ===================================================================== ! Local Scalars logical(lk) :: left, lquery, upper integer(${ik}$) :: i1, i2, iinfo, lwkopt, mi, nb, ni, nq, nw ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ left = stdlib_lsame( side, 'L' ) upper = stdlib_lsame( uplo, 'U' ) 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.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -2_${ik}$ else if( .not.stdlib_lsame( trans, 'N' ) .and. .not.stdlib_lsame( trans, 'C' ) )& then info = -3_${ik}$ else if( m<0_${ik}$ ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, nq ) ) then info = -7_${ik}$ else if( ldc<max( 1_${ik}$, m ) ) then info = -10_${ik}$ else if( lwork<nw .and. .not.lquery ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNMQL', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNMQL', side // trans, m, n-1, n-1,-1_${ik}$ ) end if else if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNMQR', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CUNMQR', side // trans, m, n-1, n-1,-1_${ik}$ ) end if end if lwkopt = nw*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CUNMTR', -info ) return else if( lquery ) then return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ .or. nq==1_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if if( left ) then mi = m - 1_${ik}$ ni = n else mi = m ni = n - 1_${ik}$ end if if( upper ) then ! q was determined by a call to stdlib${ii}$_chetrd with uplo = 'u' call stdlib${ii}$_cunmql( side, trans, mi, ni, nq-1, a( 1_${ik}$, 2_${ik}$ ), lda, tau, c,ldc, work, & lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_chetrd with uplo = 'l' if( left ) then i1 = 2_${ik}$ i2 = 1_${ik}$ else i1 = 1_${ik}$ i2 = 2_${ik}$ end if call stdlib${ii}$_cunmqr( side, trans, mi, ni, nq-1, a( 2_${ik}$, 1_${ik}$ ), lda, tau,c( i1, i2 ), ldc,& work, lwork, iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_cunmtr pure module subroutine stdlib${ii}$_zunmtr( side, uplo, trans, m, n, a, lda, tau, c, ldc,work, lwork, & !! ZUNMTR 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 of order nq, with nq = m if !! SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of !! nq-1 elementary reflectors, as returned by ZHETRD: !! if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); !! if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). 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, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldc, lwork, m, n ! Array Arguments complex(dp), intent(inout) :: a(lda,*), c(ldc,*) complex(dp), intent(in) :: tau(*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: left, lquery, upper integer(${ik}$) :: i1, i2, iinfo, lwkopt, mi, nb, ni, nq, nw ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ left = stdlib_lsame( side, 'L' ) upper = stdlib_lsame( uplo, 'U' ) 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.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -2_${ik}$ else if( .not.stdlib_lsame( trans, 'N' ) .and. .not.stdlib_lsame( trans, 'C' ) )& then info = -3_${ik}$ else if( m<0_${ik}$ ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, nq ) ) then info = -7_${ik}$ else if( ldc<max( 1_${ik}$, m ) ) then info = -10_${ik}$ else if( lwork<nw .and. .not.lquery ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQL', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQL', side // trans, m, n-1, n-1,-1_${ik}$ ) end if else if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQR', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQR', side // trans, m, n-1, n-1,-1_${ik}$ ) end if end if lwkopt = nw*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZUNMTR', -info ) return else if( lquery ) then return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ .or. nq==1_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if if( left ) then mi = m - 1_${ik}$ ni = n else mi = m ni = n - 1_${ik}$ end if if( upper ) then ! q was determined by a call to stdlib${ii}$_zhetrd with uplo = 'u' call stdlib${ii}$_zunmql( side, trans, mi, ni, nq-1, a( 1_${ik}$, 2_${ik}$ ), lda, tau, c,ldc, work, & lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_zhetrd with uplo = 'l' if( left ) then i1 = 2_${ik}$ i2 = 1_${ik}$ else i1 = 1_${ik}$ i2 = 2_${ik}$ end if call stdlib${ii}$_zunmqr( side, trans, mi, ni, nq-1, a( 2_${ik}$, 1_${ik}$ ), lda, tau,c( i1, i2 ), ldc,& work, lwork, iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_zunmtr #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$unmtr( side, uplo, trans, m, n, a, lda, tau, c, ldc,work, lwork, & !! ZUNMTR: 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 of order nq, with nq = m if !! SIDE = 'L' and nq = n if SIDE = 'R'. Q is defined as the product of !! nq-1 elementary reflectors, as returned by ZHETRD: !! if UPLO = 'U', Q = H(nq-1) . . . H(2) H(1); !! if UPLO = 'L', Q = H(1) H(2) . . . H(nq-1). 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, uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldc, lwork, m, n ! Array Arguments complex(${ck}$), intent(inout) :: a(lda,*), c(ldc,*) complex(${ck}$), intent(in) :: tau(*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: left, lquery, upper integer(${ik}$) :: i1, i2, iinfo, lwkopt, mi, nb, ni, nq, nw ! Intrinsic Functions ! Executable Statements ! test the input arguments info = 0_${ik}$ left = stdlib_lsame( side, 'L' ) upper = stdlib_lsame( uplo, 'U' ) 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.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -2_${ik}$ else if( .not.stdlib_lsame( trans, 'N' ) .and. .not.stdlib_lsame( trans, 'C' ) )& then info = -3_${ik}$ else if( m<0_${ik}$ ) then info = -4_${ik}$ else if( n<0_${ik}$ ) then info = -5_${ik}$ else if( lda<max( 1_${ik}$, nq ) ) then info = -7_${ik}$ else if( ldc<max( 1_${ik}$, m ) ) then info = -10_${ik}$ else if( lwork<nw .and. .not.lquery ) then info = -12_${ik}$ end if if( info==0_${ik}$ ) then if( upper ) then if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQL', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQL', side // trans, m, n-1, n-1,-1_${ik}$ ) end if else if( left ) then nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQR', side // trans, m-1, n, m-1,-1_${ik}$ ) else nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZUNMQR', side // trans, m, n-1, n-1,-1_${ik}$ ) end if end if lwkopt = nw*nb work( 1_${ik}$ ) = lwkopt end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZUNMTR', -info ) return else if( lquery ) then return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ .or. nq==1_${ik}$ ) then work( 1_${ik}$ ) = 1_${ik}$ return end if if( left ) then mi = m - 1_${ik}$ ni = n else mi = m ni = n - 1_${ik}$ end if if( upper ) then ! q was determined by a call to stdlib${ii}$_${ci}$hetrd with uplo = 'u' call stdlib${ii}$_${ci}$unmql( side, trans, mi, ni, nq-1, a( 1_${ik}$, 2_${ik}$ ), lda, tau, c,ldc, work, & lwork, iinfo ) else ! q was determined by a call to stdlib${ii}$_${ci}$hetrd with uplo = 'l' if( left ) then i1 = 2_${ik}$ i2 = 1_${ik}$ else i1 = 1_${ik}$ i2 = 2_${ik}$ end if call stdlib${ii}$_${ci}$unmqr( side, trans, mi, ni, nq-1, a( 2_${ik}$, 1_${ik}$ ), lda, tau,c( i1, i2 ), ldc,& work, lwork, iinfo ) end if work( 1_${ik}$ ) = lwkopt return end subroutine stdlib${ii}$_${ci}$unmtr #:endif #:endfor module subroutine stdlib${ii}$_chetrd_he2hb( uplo, n, kd, a, lda, ab, ldab, tau,work, lwork, info ) !! CHETRD_HE2HB reduces a complex Hermitian matrix A to complex Hermitian !! band-diagonal form AB by a unitary similarity transformation: !! Q**H * A * Q = AB. ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldab, lwork, n, kd ! Array Arguments complex(sp), intent(inout) :: a(lda,*) complex(sp), intent(out) :: ab(ldab,*), tau(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, j, iinfo, lwmin, pn, pk, llk, ldt, ldw, lds2, lds1, ls2, ls1, lw, lt,& tpos, wpos, s2pos, s1pos ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required ! and test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'CHETRD_HE2HB', '', n, kd, -1_${ik}$, -1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kd<0_${ik}$ ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -5_${ik}$ else if( ldab<max( 1_${ik}$, kd+1 ) ) then info = -7_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHETRD_HE2HB', -info ) return else if( lquery ) then work( 1_${ik}$ ) = lwmin return end if ! quick return if possible ! copy the upper/lower portion of a into ab if( n<=kd+1 ) then if( upper ) then do i = 1, n llk = min( kd+1, i ) call stdlib${ii}$_ccopy( llk, a( i-llk+1, i ), 1_${ik}$,ab( kd+1-llk+1, i ), 1_${ik}$ ) end do else do i = 1, n llk = min( kd+1, n-i+1 ) call stdlib${ii}$_ccopy( llk, a( i, i ), 1_${ik}$, ab( 1_${ik}$, i ), 1_${ik}$ ) end do endif work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine the pointer position for the workspace ldt = kd lds1 = kd lt = ldt*kd lw = n*kd ls1 = lds1*kd ls2 = lwmin - lt - lw - ls1 ! ls2 = n*max(kd,factoptnb) tpos = 1_${ik}$ wpos = tpos + lt s1pos = wpos + lw s2pos = s1pos + ls1 if( upper ) then ldw = kd lds2 = kd else ldw = n lds2 = n endif ! set the workspace of the triangular matrix t to czero once such a ! way every time t is generated the upper/lower portion will be always czero call stdlib${ii}$_claset( "A", ldt, kd, czero, czero, work( tpos ), ldt ) if( upper ) then do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the lq factorization of the current block call stdlib${ii}$_cgelqf( kd, pn, a( i, i+kd ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_ccopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do call stdlib${ii}$_claset( 'LOWER', pk, pk, czero, cone,a( i, i+kd ), lda ) ! form the matrix t call stdlib${ii}$_clarft( 'FORWARD', 'ROWWISE', pn, pk,a( i, i+kd ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_cgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pn, pk,cone, work( tpos ), & ldt,a( i, i+kd ), lda,czero, work( s2pos ), lds2 ) call stdlib${ii}$_chemm( 'RIGHT', uplo, pk, pn,cone, a( i+kd, i+kd ), lda,work( & s2pos ), lds2,czero, work( wpos ), ldw ) call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'CONJUGATE', pk, pk, pn,cone, work( wpos ), & ldw,work( s2pos ), lds2,czero, work( s1pos ), lds1 ) call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pk, pn, pk,-chalf, work( & s1pos ), lds1,a( i, i+kd ), lda,cone, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v'*w - w'*v call stdlib${ii}$_cher2k( uplo, 'CONJUGATE', pn, pk,-cone, a( i, i+kd ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) end do ! copy the upper band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_ccopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do else ! reduce the lower triangle of a to lower band matrix loop_40: do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the qr factorization of the current block call stdlib${ii}$_cgeqrf( pn, kd, a( i+kd, i ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_ccopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do call stdlib${ii}$_claset( 'UPPER', pk, pk, czero, cone,a( i+kd, i ), lda ) ! form the matrix t call stdlib${ii}$_clarft( 'FORWARD', 'COLUMNWISE', pn, pk,a( i+kd, i ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,cone, a( i+kd, i )& , lda,work( tpos ), ldt,czero, work( s2pos ), lds2 ) call stdlib${ii}$_chemm( 'LEFT', uplo, pn, pk,cone, a( i+kd, i+kd ), lda,work( s2pos )& , lds2,czero, work( wpos ), ldw ) call stdlib${ii}$_cgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pk, pn,cone, work( s2pos ), & lds2,work( wpos ), ldw,czero, work( s1pos ), lds1 ) call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,-chalf, a( i+kd, & i ), lda,work( s1pos ), lds1,cone, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v*w' - w*v' call stdlib${ii}$_cher2k( uplo, 'NO TRANSPOSE', pn, pk,-cone, a( i+kd, i ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) ! ================================================================== ! restore a for comparison and checking to be removed ! do 45 j = i, i+pk-1 ! llk = min( kd, n-j ) + 1 ! call stdlib${ii}$_ccopy( llk, ab( 1, j ), 1, a( j, j ), 1 ) 45 continue ! ================================================================== end do loop_40 ! copy the lower band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_ccopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do end if work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_chetrd_he2hb module subroutine stdlib${ii}$_zhetrd_he2hb( uplo, n, kd, a, lda, ab, ldab, tau,work, lwork, info ) !! ZHETRD_HE2HB reduces a complex Hermitian matrix A to complex Hermitian !! band-diagonal form AB by a unitary similarity transformation: !! Q**H * A * Q = AB. ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldab, lwork, n, kd ! Array Arguments complex(dp), intent(inout) :: a(lda,*) complex(dp), intent(out) :: ab(ldab,*), tau(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, j, iinfo, lwmin, pn, pk, llk, ldt, ldw, lds2, lds1, ls2, ls1, lw, lt,& tpos, wpos, s2pos, s1pos ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required ! and test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'ZHETRD_HE2HB', '', n, kd, -1_${ik}$, -1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kd<0_${ik}$ ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -5_${ik}$ else if( ldab<max( 1_${ik}$, kd+1 ) ) then info = -7_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETRD_HE2HB', -info ) return else if( lquery ) then work( 1_${ik}$ ) = lwmin return end if ! quick return if possible ! copy the upper/lower portion of a into ab if( n<=kd+1 ) then if( upper ) then do i = 1, n llk = min( kd+1, i ) call stdlib${ii}$_zcopy( llk, a( i-llk+1, i ), 1_${ik}$,ab( kd+1-llk+1, i ), 1_${ik}$ ) end do else do i = 1, n llk = min( kd+1, n-i+1 ) call stdlib${ii}$_zcopy( llk, a( i, i ), 1_${ik}$, ab( 1_${ik}$, i ), 1_${ik}$ ) end do endif work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine the pointer position for the workspace ldt = kd lds1 = kd lt = ldt*kd lw = n*kd ls1 = lds1*kd ls2 = lwmin - lt - lw - ls1 ! ls2 = n*max(kd,factoptnb) tpos = 1_${ik}$ wpos = tpos + lt s1pos = wpos + lw s2pos = s1pos + ls1 if( upper ) then ldw = kd lds2 = kd else ldw = n lds2 = n endif ! set the workspace of the triangular matrix t to czero once such a ! way every time t is generated the upper/lower portion will be always czero call stdlib${ii}$_zlaset( "A", ldt, kd, czero, czero, work( tpos ), ldt ) if( upper ) then do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the lq factorization of the current block call stdlib${ii}$_zgelqf( kd, pn, a( i, i+kd ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_zcopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do call stdlib${ii}$_zlaset( 'LOWER', pk, pk, czero, cone,a( i, i+kd ), lda ) ! form the matrix t call stdlib${ii}$_zlarft( 'FORWARD', 'ROWWISE', pn, pk,a( i, i+kd ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_zgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pn, pk,cone, work( tpos ), & ldt,a( i, i+kd ), lda,czero, work( s2pos ), lds2 ) call stdlib${ii}$_zhemm( 'RIGHT', uplo, pk, pn,cone, a( i+kd, i+kd ), lda,work( & s2pos ), lds2,czero, work( wpos ), ldw ) call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'CONJUGATE', pk, pk, pn,cone, work( wpos ), & ldw,work( s2pos ), lds2,czero, work( s1pos ), lds1 ) call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pk, pn, pk,-chalf, work( & s1pos ), lds1,a( i, i+kd ), lda,cone, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v'*w - w'*v call stdlib${ii}$_zher2k( uplo, 'CONJUGATE', pn, pk,-cone, a( i, i+kd ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) end do ! copy the upper band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_zcopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do else ! reduce the lower triangle of a to lower band matrix loop_40: do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the qr factorization of the current block call stdlib${ii}$_zgeqrf( pn, kd, a( i+kd, i ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_zcopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do call stdlib${ii}$_zlaset( 'UPPER', pk, pk, czero, cone,a( i+kd, i ), lda ) ! form the matrix t call stdlib${ii}$_zlarft( 'FORWARD', 'COLUMNWISE', pn, pk,a( i+kd, i ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,cone, a( i+kd, i )& , lda,work( tpos ), ldt,czero, work( s2pos ), lds2 ) call stdlib${ii}$_zhemm( 'LEFT', uplo, pn, pk,cone, a( i+kd, i+kd ), lda,work( s2pos )& , lds2,czero, work( wpos ), ldw ) call stdlib${ii}$_zgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pk, pn,cone, work( s2pos ), & lds2,work( wpos ), ldw,czero, work( s1pos ), lds1 ) call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,-chalf, a( i+kd, & i ), lda,work( s1pos ), lds1,cone, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v*w' - w*v' call stdlib${ii}$_zher2k( uplo, 'NO TRANSPOSE', pn, pk,-cone, a( i+kd, i ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) ! ================================================================== ! restore a for comparison and checking to be removed ! do 45 j = i, i+pk-1 ! llk = min( kd, n-j ) + 1 ! call stdlib${ii}$_zcopy( nlk, ab( 1, j ), 1, a( j, j ), 1 ) 45 continue ! ================================================================== end do loop_40 ! copy the lower band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_zcopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do end if work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_zhetrd_he2hb #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hetrd_he2hb( uplo, n, kd, a, lda, ab, ldab, tau,work, lwork, info ) !! ZHETRD_HE2HB: reduces a complex Hermitian matrix A to complex Hermitian !! band-diagonal form AB by a unitary similarity transformation: !! Q**H * A * Q = AB. ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldab, lwork, n, kd ! Array Arguments complex(${ck}$), intent(inout) :: a(lda,*) complex(${ck}$), intent(out) :: ab(ldab,*), tau(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, j, iinfo, lwmin, pn, pk, llk, ldt, ldw, lds2, lds1, ls2, ls1, lw, lt,& tpos, wpos, s2pos, s1pos ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required ! and test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'ZHETRD_HE2HB', '', n, kd, -1_${ik}$, -1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kd<0_${ik}$ ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -5_${ik}$ else if( ldab<max( 1_${ik}$, kd+1 ) ) then info = -7_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETRD_HE2HB', -info ) return else if( lquery ) then work( 1_${ik}$ ) = lwmin return end if ! quick return if possible ! copy the upper/lower portion of a into ab if( n<=kd+1 ) then if( upper ) then do i = 1, n llk = min( kd+1, i ) call stdlib${ii}$_${ci}$copy( llk, a( i-llk+1, i ), 1_${ik}$,ab( kd+1-llk+1, i ), 1_${ik}$ ) end do else do i = 1, n llk = min( kd+1, n-i+1 ) call stdlib${ii}$_${ci}$copy( llk, a( i, i ), 1_${ik}$, ab( 1_${ik}$, i ), 1_${ik}$ ) end do endif work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine the pointer position for the workspace ldt = kd lds1 = kd lt = ldt*kd lw = n*kd ls1 = lds1*kd ls2 = lwmin - lt - lw - ls1 ! ls2 = n*max(kd,factoptnb) tpos = 1_${ik}$ wpos = tpos + lt s1pos = wpos + lw s2pos = s1pos + ls1 if( upper ) then ldw = kd lds2 = kd else ldw = n lds2 = n endif ! set the workspace of the triangular matrix t to czero once such a ! way every time t is generated the upper/lower portion will be always czero call stdlib${ii}$_${ci}$laset( "A", ldt, kd, czero, czero, work( tpos ), ldt ) if( upper ) then do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the lq factorization of the current block call stdlib${ii}$_${ci}$gelqf( kd, pn, a( i, i+kd ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_${ci}$copy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do call stdlib${ii}$_${ci}$laset( 'LOWER', pk, pk, czero, cone,a( i, i+kd ), lda ) ! form the matrix t call stdlib${ii}$_${ci}$larft( 'FORWARD', 'ROWWISE', pn, pk,a( i, i+kd ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_${ci}$gemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pn, pk,cone, work( tpos ), & ldt,a( i, i+kd ), lda,czero, work( s2pos ), lds2 ) call stdlib${ii}$_${ci}$hemm( 'RIGHT', uplo, pk, pn,cone, a( i+kd, i+kd ), lda,work( & s2pos ), lds2,czero, work( wpos ), ldw ) call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'CONJUGATE', pk, pk, pn,cone, work( wpos ), & ldw,work( s2pos ), lds2,czero, work( s1pos ), lds1 ) call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pk, pn, pk,-chalf, work( & s1pos ), lds1,a( i, i+kd ), lda,cone, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v'*w - w'*v call stdlib${ii}$_${ci}$her2k( uplo, 'CONJUGATE', pn, pk,-cone, a( i, i+kd ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) end do ! copy the upper band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_${ci}$copy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do else ! reduce the lower triangle of a to lower band matrix loop_40: do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the qr factorization of the current block call stdlib${ii}$_${ci}$geqrf( pn, kd, a( i+kd, i ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_${ci}$copy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do call stdlib${ii}$_${ci}$laset( 'UPPER', pk, pk, czero, cone,a( i+kd, i ), lda ) ! form the matrix t call stdlib${ii}$_${ci}$larft( 'FORWARD', 'COLUMNWISE', pn, pk,a( i+kd, i ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,cone, a( i+kd, i )& , lda,work( tpos ), ldt,czero, work( s2pos ), lds2 ) call stdlib${ii}$_${ci}$hemm( 'LEFT', uplo, pn, pk,cone, a( i+kd, i+kd ), lda,work( s2pos )& , lds2,czero, work( wpos ), ldw ) call stdlib${ii}$_${ci}$gemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pk, pn,cone, work( s2pos ), & lds2,work( wpos ), ldw,czero, work( s1pos ), lds1 ) call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,-chalf, a( i+kd, & i ), lda,work( s1pos ), lds1,cone, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v*w' - w*v' call stdlib${ii}$_${ci}$her2k( uplo, 'NO TRANSPOSE', pn, pk,-cone, a( i+kd, i ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) ! ================================================================== ! restore a for comparison and checking to be removed ! do 45 j = i, i+pk-1 ! llk = min( kd, n-j ) + 1 ! call stdlib${ii}$_${ci}$copy( llk, ab( 1, j ), 1, a( j, j ), 1 ) 45 continue ! ================================================================== end do loop_40 ! copy the lower band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_${ci}$copy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do end if work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_${ci}$hetrd_he2hb #:endif #:endfor module subroutine stdlib${ii}$_chetrd_hb2st( stage1, vect, uplo, n, kd, ab, ldab,d, e, hous, lhous, & !! CHETRD_HB2ST reduces a complex Hermitian band matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. work, lwork, info ) ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: stage1, uplo, vect integer(${ik}$), intent(in) :: n, kd, ldab, lhous, lwork integer(${ik}$), intent(out) :: info ! Array Arguments real(sp), intent(out) :: d(*), e(*) complex(sp), intent(inout) :: ab(ldab,*) complex(sp), intent(out) :: hous(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, wantq, upper, afters1 integer(${ik}$) :: i, m, k, ib, sweepid, myid, shift, stt, st, ed, stind, edind, & blklastind, colpt, thed, stepercol, grsiz, thgrsiz, thgrnb, thgrid, nbtiles, ttype, & tid, nthreads, debug, abdpos, abofdpos, dpos, ofdpos, awpos, inda, indw, apos, sizea, & lda, indv, indtau, sicev, sizetau, ldv, lhmin, lwmin real(sp) :: abstmp complex(sp) :: tmp ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required. ! test the input parameters debug = 0_${ik}$ info = 0_${ik}$ afters1 = stdlib_lsame( stage1, 'Y' ) wantq = stdlib_lsame( vect, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) .or. ( lhous==-1_${ik}$ ) ! determine the block size, the workspace size and the hous size. ib = stdlib${ii}$_ilaenv2stage( 2_${ik}$, 'CHETRD_HB2ST', vect, n, kd, -1_${ik}$, -1_${ik}$ ) lhmin = stdlib${ii}$_ilaenv2stage( 3_${ik}$, 'CHETRD_HB2ST', vect, n, kd, ib, -1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'CHETRD_HB2ST', vect, n, kd, ib, -1_${ik}$ ) if( .not.afters1 .and. .not.stdlib_lsame( stage1, 'N' ) ) then info = -1_${ik}$ else if( .not.stdlib_lsame( vect, 'N' ) ) then info = -2_${ik}$ else if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( kd<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<(kd+1) ) then info = -7_${ik}$ else if( lhous<lhmin .and. .not.lquery ) then info = -11_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -13_${ik}$ end if if( info==0_${ik}$ ) then hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CHETRD_HB2ST', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0_${ik}$ ) then hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine pointer position ldv = kd + ib sizetau = 2_${ik}$ * n sicev = 2_${ik}$ * n indtau = 1_${ik}$ indv = indtau + sizetau lda = 2_${ik}$ * kd + 1_${ik}$ sizea = lda * n inda = 1_${ik}$ indw = inda + sizea nthreads = 1_${ik}$ tid = 0_${ik}$ if( upper ) then apos = inda + kd awpos = inda dpos = apos + kd ofdpos = dpos - 1_${ik}$ abdpos = kd + 1_${ik}$ abofdpos = kd else apos = inda awpos = inda + kd + 1_${ik}$ dpos = apos ofdpos = dpos + 1_${ik}$ abdpos = 1_${ik}$ abofdpos = 2_${ik}$ endif ! case kd=0: ! the matrix is diagonal. we just copy it (convert to "real" for ! complex because d is double and the imaginary part should be 0) ! and store it in d. a sequential code here is better or ! in a parallel environment it might need two cores for d and e if( kd==0_${ik}$ ) then do i = 1, n d( i ) = real( ab( abdpos, i ),KIND=sp) end do do i = 1, n-1 e( i ) = zero end do hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! case kd=1: ! the matrix is already tridiagonal. we have to make diagonal ! and offdiagonal elements real, and store them in d and e. ! for that, for real precision just copy the diag and offdiag ! to d and e while for the complex case the bulge chasing is ! performed to convert the hermetian tridiagonal to symmetric ! tridiagonal. a simpler conversion formula might be used, but then ! updating the q matrix will be required and based if q is generated ! or not this might complicate the story. if( kd==1_${ik}$ ) then do i = 1, n d( i ) = real( ab( abdpos, i ),KIND=sp) end do ! make off-diagonal elements real and copy them to e if( upper ) then do i = 1, n - 1 tmp = ab( abofdpos, i+1 ) abstmp = abs( tmp ) ab( abofdpos, i+1 ) = abstmp e( i ) = abstmp if( abstmp/=zero ) then tmp = tmp / abstmp else tmp = cone end if if( i<n-1 )ab( abofdpos, i+2 ) = ab( abofdpos, i+2 )*tmp ! if( wantz ) then ! call stdlib${ii}$_cscal( n, conjg( tmp ), q( 1, i+1 ), 1 ) ! end if end do else do i = 1, n - 1 tmp = ab( abofdpos, i ) abstmp = abs( tmp ) ab( abofdpos, i ) = abstmp e( i ) = abstmp if( abstmp/=zero ) then tmp = tmp / abstmp else tmp = cone end if if( i<n-1 )ab( abofdpos, i+1 ) = ab( abofdpos, i+1 )*tmp ! if( wantq ) then ! call stdlib${ii}$_cscal( n, tmp, q( 1, i+1 ), 1 ) ! end if end do endif hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! main code start here. ! reduce the hermitian band of a to a tridiagonal matrix. thgrsiz = n grsiz = 1_${ik}$ shift = 3_${ik}$ nbtiles = ceiling( real(n,KIND=sp)/real(kd,KIND=sp) ) stepercol = ceiling( real(shift,KIND=sp)/real(grsiz,KIND=sp) ) thgrnb = ceiling( real(n-1,KIND=sp)/real(thgrsiz,KIND=sp) ) call stdlib${ii}$_clacpy( "A", kd+1, n, ab, ldab, work( apos ), lda ) call stdlib${ii}$_claset( "A", kd, n, czero, czero, work( awpos ), lda ) ! openmp parallelisation start here !$OMP PARALLEL PRIVATE( TID, THGRID, BLKLASTIND ) & !$OMP& PRIVATE( THED, I, M, K, ST, ED, STT, SWEEPID ) & !$OMP& PRIVATE( MYID, TTYPE, COLPT, STIND, EDIND ) & !$OMP& SHARED ( UPLO, WANTQ, INDV, INDTAU, HOUS, WORK) & !$OMP& SHARED ( N, KD, IB, NBTILES, LDA, LDV, INDA ) & !$OMP& SHARED ( STEPERCOL, THGRNB, THGRSIZ, GRSIZ, SHIFT ) !$OMP MASTER ! main bulge chasing loop loop_100: do thgrid = 1, thgrnb stt = (thgrid-1)*thgrsiz+1 thed = min( (stt + thgrsiz -1_${ik}$), (n-1)) loop_110: do i = stt, n-1 ed = min( i, thed ) if( stt>ed ) exit loop_120: do m = 1, stepercol st = stt loop_130: do sweepid = st, ed loop_140: do k = 1, grsiz myid = (i-sweepid)*(stepercol*grsiz)+ (m-1)*grsiz + k if ( myid==1_${ik}$ ) then ttype = 1_${ik}$ else ttype = mod( myid, 2_${ik}$ ) + 2_${ik}$ endif if( ttype==2_${ik}$ ) then colpt = (myid/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) blklastind = colpt else colpt = ((myid+1)/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) if( ( stind>=edind-1 ).and.( edind==n ) ) then blklastind = n else blklastind = 0_${ik}$ endif endif ! call the kernel !$ if( ttype/=1 ) then !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(in:WORK(MYID-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() !$ call stdlib${ii}$_chb2st_kernels( uplo, wantq, ttype,stind, edind, & !$ sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & !$ indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ else !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() call stdlib${ii}$_chb2st_kernels( uplo, wantq, ttype,stind, edind, & sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ endif if ( blklastind>=(n-1) ) then stt = stt + 1_${ik}$ exit endif end do loop_140 end do loop_130 end do loop_120 end do loop_110 end do loop_100 !$OMP END MASTER !$OMP END PARALLEL ! copy the diagonal from a to d. note that d is real thus only ! the real part is needed, the imaginary part should be czero. do i = 1, n d( i ) = real( work( dpos+(i-1)*lda ),KIND=sp) end do ! copy the off diagonal from a to e. note that e is real thus only ! the real part is needed, the imaginary part should be czero. if( upper ) then do i = 1, n-1 e( i ) = real( work( ofdpos+i*lda ),KIND=sp) end do else do i = 1, n-1 e( i ) = real( work( ofdpos+(i-1)*lda ),KIND=sp) end do endif hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_chetrd_hb2st module subroutine stdlib${ii}$_zhetrd_hb2st( stage1, vect, uplo, n, kd, ab, ldab,d, e, hous, lhous, & !! ZHETRD_HB2ST reduces a complex Hermitian band matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. work, lwork, info ) ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: stage1, uplo, vect integer(${ik}$), intent(in) :: n, kd, ldab, lhous, lwork integer(${ik}$), intent(out) :: info ! Array Arguments real(dp), intent(out) :: d(*), e(*) complex(dp), intent(inout) :: ab(ldab,*) complex(dp), intent(out) :: hous(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, wantq, upper, afters1 integer(${ik}$) :: i, m, k, ib, sweepid, myid, shift, stt, st, ed, stind, edind, & blklastind, colpt, thed, stepercol, grsiz, thgrsiz, thgrnb, thgrid, nbtiles, ttype, & tid, nthreads, debug, abdpos, abofdpos, dpos, ofdpos, awpos, inda, indw, apos, sizea, & lda, indv, indtau, sizev, sizetau, ldv, lhmin, lwmin real(dp) :: abstmp complex(dp) :: tmp ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required. ! test the input parameters debug = 0_${ik}$ info = 0_${ik}$ afters1 = stdlib_lsame( stage1, 'Y' ) wantq = stdlib_lsame( vect, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) .or. ( lhous==-1_${ik}$ ) ! determine the block size, the workspace size and the hous size. ib = stdlib${ii}$_ilaenv2stage( 2_${ik}$, 'ZHETRD_HB2ST', vect, n, kd, -1_${ik}$, -1_${ik}$ ) lhmin = stdlib${ii}$_ilaenv2stage( 3_${ik}$, 'ZHETRD_HB2ST', vect, n, kd, ib, -1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'ZHETRD_HB2ST', vect, n, kd, ib, -1_${ik}$ ) if( .not.afters1 .and. .not.stdlib_lsame( stage1, 'N' ) ) then info = -1_${ik}$ else if( .not.stdlib_lsame( vect, 'N' ) ) then info = -2_${ik}$ else if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( kd<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<(kd+1) ) then info = -7_${ik}$ else if( lhous<lhmin .and. .not.lquery ) then info = -11_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -13_${ik}$ end if if( info==0_${ik}$ ) then hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETRD_HB2ST', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0_${ik}$ ) then hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine pointer position ldv = kd + ib sizetau = 2_${ik}$ * n sizev = 2_${ik}$ * n indtau = 1_${ik}$ indv = indtau + sizetau lda = 2_${ik}$ * kd + 1_${ik}$ sizea = lda * n inda = 1_${ik}$ indw = inda + sizea nthreads = 1_${ik}$ tid = 0_${ik}$ if( upper ) then apos = inda + kd awpos = inda dpos = apos + kd ofdpos = dpos - 1_${ik}$ abdpos = kd + 1_${ik}$ abofdpos = kd else apos = inda awpos = inda + kd + 1_${ik}$ dpos = apos ofdpos = dpos + 1_${ik}$ abdpos = 1_${ik}$ abofdpos = 2_${ik}$ endif ! case kd=0: ! the matrix is diagonal. we just copy it (convert to "real" for ! complex because d is double and the imaginary part should be 0) ! and store it in d. a sequential code here is better or ! in a parallel environment it might need two cores for d and e if( kd==0_${ik}$ ) then do i = 1, n d( i ) = real( ab( abdpos, i ),KIND=dp) end do do i = 1, n-1 e( i ) = zero end do hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! case kd=1: ! the matrix is already tridiagonal. we have to make diagonal ! and offdiagonal elements real, and store them in d and e. ! for that, for real precision just copy the diag and offdiag ! to d and e while for the complex case the bulge chasing is ! performed to convert the hermetian tridiagonal to symmetric ! tridiagonal. a simpler conversion formula might be used, but then ! updating the q matrix will be required and based if q is generated ! or not this might complicate the story. if( kd==1_${ik}$ ) then do i = 1, n d( i ) = real( ab( abdpos, i ),KIND=dp) end do ! make off-diagonal elements real and copy them to e if( upper ) then do i = 1, n - 1 tmp = ab( abofdpos, i+1 ) abstmp = abs( tmp ) ab( abofdpos, i+1 ) = abstmp e( i ) = abstmp if( abstmp/=zero ) then tmp = tmp / abstmp else tmp = cone end if if( i<n-1 )ab( abofdpos, i+2 ) = ab( abofdpos, i+2 )*tmp ! if( wantz ) then ! call stdlib${ii}$_zscal( n, conjg( tmp ), q( 1, i+1 ), 1 ) ! end if end do else do i = 1, n - 1 tmp = ab( abofdpos, i ) abstmp = abs( tmp ) ab( abofdpos, i ) = abstmp e( i ) = abstmp if( abstmp/=zero ) then tmp = tmp / abstmp else tmp = cone end if if( i<n-1 )ab( abofdpos, i+1 ) = ab( abofdpos, i+1 )*tmp ! if( wantq ) then ! call stdlib${ii}$_zscal( n, tmp, q( 1, i+1 ), 1 ) ! end if end do endif hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! main code start here. ! reduce the hermitian band of a to a tridiagonal matrix. thgrsiz = n grsiz = 1_${ik}$ shift = 3_${ik}$ nbtiles = ceiling( real(n,KIND=dp)/real(kd,KIND=dp) ) stepercol = ceiling( real(shift,KIND=dp)/real(grsiz,KIND=dp) ) thgrnb = ceiling( real(n-1,KIND=dp)/real(thgrsiz,KIND=dp) ) call stdlib${ii}$_zlacpy( "A", kd+1, n, ab, ldab, work( apos ), lda ) call stdlib${ii}$_zlaset( "A", kd, n, czero, czero, work( awpos ), lda ) ! openmp parallelisation start here !$OMP PARALLEL PRIVATE( TID, THGRID, BLKLASTIND ) & !$OMP& PRIVATE( THED, I, M, K, ST, ED, STT, SWEEPID ) & !$OMP& PRIVATE( MYID, TTYPE, COLPT, STIND, EDIND ) & !$OMP& SHARED ( UPLO, WANTQ, INDV, INDTAU, HOUS, WORK) & !$OMP& SHARED ( N, KD, IB, NBTILES, LDA, LDV, INDA ) & !$OMP& SHARED ( STEPERCOL, THGRNB, THGRSIZ, GRSIZ, SHIFT ) !$OMP MASTER ! main bulge chasing loop loop_100: do thgrid = 1, thgrnb stt = (thgrid-1)*thgrsiz+1 thed = min( (stt + thgrsiz -1_${ik}$), (n-1)) loop_110: do i = stt, n-1 ed = min( i, thed ) if( stt>ed ) exit loop_120: do m = 1, stepercol st = stt loop_130: do sweepid = st, ed loop_140: do k = 1, grsiz myid = (i-sweepid)*(stepercol*grsiz)+ (m-1)*grsiz + k if ( myid==1_${ik}$ ) then ttype = 1_${ik}$ else ttype = mod( myid, 2_${ik}$ ) + 2_${ik}$ endif if( ttype==2_${ik}$ ) then colpt = (myid/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) blklastind = colpt else colpt = ((myid+1)/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) if( ( stind>=edind-1 ).and.( edind==n ) ) then blklastind = n else blklastind = 0_${ik}$ endif endif ! call the kernel !$ if( ttype/=1 ) then !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(in:WORK(MYID-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() !$ call stdlib${ii}$_zhb2st_kernels( uplo, wantq, ttype,stind, edind, & !$ sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & !$ indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ else !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() call stdlib${ii}$_zhb2st_kernels( uplo, wantq, ttype,stind, edind, & sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ endif if ( blklastind>=(n-1) ) then stt = stt + 1_${ik}$ exit endif end do loop_140 end do loop_130 end do loop_120 end do loop_110 end do loop_100 !$OMP END MASTER !$OMP END PARALLEL ! copy the diagonal from a to d. note that d is real thus only ! the real part is needed, the imaginary part should be czero. do i = 1, n d( i ) = real( work( dpos+(i-1)*lda ),KIND=dp) end do ! copy the off diagonal from a to e. note that e is real thus only ! the real part is needed, the imaginary part should be czero. if( upper ) then do i = 1, n-1 e( i ) = real( work( ofdpos+i*lda ),KIND=dp) end do else do i = 1, n-1 e( i ) = real( work( ofdpos+(i-1)*lda ),KIND=dp) end do endif hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_zhetrd_hb2st #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] module subroutine stdlib${ii}$_${ci}$hetrd_hb2st( stage1, vect, uplo, n, kd, ab, ldab,d, e, hous, lhous, & !! ZHETRD_HB2ST: reduces a complex Hermitian band matrix A to real symmetric !! tridiagonal form T by a unitary similarity transformation: !! Q**H * A * Q = T. work, lwork, info ) ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: stage1, uplo, vect integer(${ik}$), intent(in) :: n, kd, ldab, lhous, lwork integer(${ik}$), intent(out) :: info ! Array Arguments real(${ck}$), intent(out) :: d(*), e(*) complex(${ck}$), intent(inout) :: ab(ldab,*) complex(${ck}$), intent(out) :: hous(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, wantq, upper, afters1 integer(${ik}$) :: i, m, k, ib, sweepid, myid, shift, stt, st, ed, stind, edind, & blklastind, colpt, thed, stepercol, grsiz, thgrsiz, thgrnb, thgrid, nbtiles, ttype, & tid, nthreads, debug, abdpos, abofdpos, dpos, ofdpos, awpos, inda, indw, apos, sizea, & lda, indv, indtau, sizev, sizetau, ldv, lhmin, lwmin real(${ck}$) :: abstmp complex(${ck}$) :: tmp ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required. ! test the input parameters debug = 0_${ik}$ info = 0_${ik}$ afters1 = stdlib_lsame( stage1, 'Y' ) wantq = stdlib_lsame( vect, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) .or. ( lhous==-1_${ik}$ ) ! determine the block size, the workspace size and the hous size. ib = stdlib${ii}$_ilaenv2stage( 2_${ik}$, 'ZHETRD_HB2ST', vect, n, kd, -1_${ik}$, -1_${ik}$ ) lhmin = stdlib${ii}$_ilaenv2stage( 3_${ik}$, 'ZHETRD_HB2ST', vect, n, kd, ib, -1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'ZHETRD_HB2ST', vect, n, kd, ib, -1_${ik}$ ) if( .not.afters1 .and. .not.stdlib_lsame( stage1, 'N' ) ) then info = -1_${ik}$ else if( .not.stdlib_lsame( vect, 'N' ) ) then info = -2_${ik}$ else if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( kd<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<(kd+1) ) then info = -7_${ik}$ else if( lhous<lhmin .and. .not.lquery ) then info = -11_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -13_${ik}$ end if if( info==0_${ik}$ ) then hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZHETRD_HB2ST', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0_${ik}$ ) then hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine pointer position ldv = kd + ib sizetau = 2_${ik}$ * n sizev = 2_${ik}$ * n indtau = 1_${ik}$ indv = indtau + sizetau lda = 2_${ik}$ * kd + 1_${ik}$ sizea = lda * n inda = 1_${ik}$ indw = inda + sizea nthreads = 1_${ik}$ tid = 0_${ik}$ if( upper ) then apos = inda + kd awpos = inda dpos = apos + kd ofdpos = dpos - 1_${ik}$ abdpos = kd + 1_${ik}$ abofdpos = kd else apos = inda awpos = inda + kd + 1_${ik}$ dpos = apos ofdpos = dpos + 1_${ik}$ abdpos = 1_${ik}$ abofdpos = 2_${ik}$ endif ! case kd=0: ! the matrix is diagonal. we just copy it (convert to "real" for ! complex because d is double and the imaginary part should be 0) ! and store it in d. a sequential code here is better or ! in a parallel environment it might need two cores for d and e if( kd==0_${ik}$ ) then do i = 1, n d( i ) = real( ab( abdpos, i ),KIND=${ck}$) end do do i = 1, n-1 e( i ) = zero end do hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! case kd=1: ! the matrix is already tridiagonal. we have to make diagonal ! and offdiagonal elements real, and store them in d and e. ! for that, for real precision just copy the diag and offdiag ! to d and e while for the complex case the bulge chasing is ! performed to convert the hermetian tridiagonal to symmetric ! tridiagonal. a simpler conversion formula might be used, but then ! updating the q matrix will be required and based if q is generated ! or not this might complicate the story. if( kd==1_${ik}$ ) then do i = 1, n d( i ) = real( ab( abdpos, i ),KIND=${ck}$) end do ! make off-diagonal elements real and copy them to e if( upper ) then do i = 1, n - 1 tmp = ab( abofdpos, i+1 ) abstmp = abs( tmp ) ab( abofdpos, i+1 ) = abstmp e( i ) = abstmp if( abstmp/=zero ) then tmp = tmp / abstmp else tmp = cone end if if( i<n-1 )ab( abofdpos, i+2 ) = ab( abofdpos, i+2 )*tmp ! if( wantz ) then ! call stdlib${ii}$_${ci}$scal( n, conjg( tmp ), q( 1, i+1 ), 1 ) ! end if end do else do i = 1, n - 1 tmp = ab( abofdpos, i ) abstmp = abs( tmp ) ab( abofdpos, i ) = abstmp e( i ) = abstmp if( abstmp/=zero ) then tmp = tmp / abstmp else tmp = cone end if if( i<n-1 )ab( abofdpos, i+1 ) = ab( abofdpos, i+1 )*tmp ! if( wantq ) then ! call stdlib${ii}$_${ci}$scal( n, tmp, q( 1, i+1 ), 1 ) ! end if end do endif hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! main code start here. ! reduce the hermitian band of a to a tridiagonal matrix. thgrsiz = n grsiz = 1_${ik}$ shift = 3_${ik}$ nbtiles = ceiling( real(n,KIND=${ck}$)/real(kd,KIND=${ck}$) ) stepercol = ceiling( real(shift,KIND=${ck}$)/real(grsiz,KIND=${ck}$) ) thgrnb = ceiling( real(n-1,KIND=${ck}$)/real(thgrsiz,KIND=${ck}$) ) call stdlib${ii}$_${ci}$lacpy( "A", kd+1, n, ab, ldab, work( apos ), lda ) call stdlib${ii}$_${ci}$laset( "A", kd, n, czero, czero, work( awpos ), lda ) ! openmp parallelisation start here !$OMP PARALLEL PRIVATE( TID, THGRID, BLKLASTIND ) & !$OMP& PRIVATE( THED, I, M, K, ST, ED, STT, SWEEPID ) & !$OMP& PRIVATE( MYID, TTYPE, COLPT, STIND, EDIND ) & !$OMP& SHARED ( UPLO, WANTQ, INDV, INDTAU, HOUS, WORK) & !$OMP& SHARED ( N, KD, IB, NBTILES, LDA, LDV, INDA ) & !$OMP& SHARED ( STEPERCOL, THGRNB, THGRSIZ, GRSIZ, SHIFT ) !$OMP MASTER ! main bulge chasing loop loop_100: do thgrid = 1, thgrnb stt = (thgrid-1)*thgrsiz+1 thed = min( (stt + thgrsiz -1_${ik}$), (n-1)) loop_110: do i = stt, n-1 ed = min( i, thed ) if( stt>ed ) exit loop_120: do m = 1, stepercol st = stt loop_130: do sweepid = st, ed loop_140: do k = 1, grsiz myid = (i-sweepid)*(stepercol*grsiz)+ (m-1)*grsiz + k if ( myid==1_${ik}$ ) then ttype = 1_${ik}$ else ttype = mod( myid, 2_${ik}$ ) + 2_${ik}$ endif if( ttype==2_${ik}$ ) then colpt = (myid/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) blklastind = colpt else colpt = ((myid+1)/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) if( ( stind>=edind-1 ).and.( edind==n ) ) then blklastind = n else blklastind = 0_${ik}$ endif endif ! call the kernel !$ if( ttype/=1 ) then !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(in:WORK(MYID-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() !$ call stdlib${ii}$_${ci}$hb2st_kernels( uplo, wantq, ttype,stind, edind, & !$ sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & !$ indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ else !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() call stdlib${ii}$_${ci}$hb2st_kernels( uplo, wantq, ttype,stind, edind, & sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ endif if ( blklastind>=(n-1) ) then stt = stt + 1_${ik}$ exit endif end do loop_140 end do loop_130 end do loop_120 end do loop_110 end do loop_100 !$OMP END MASTER !$OMP END PARALLEL ! copy the diagonal from a to d. note that d is real thus only ! the real part is needed, the imaginary part should be czero. do i = 1, n d( i ) = real( work( dpos+(i-1)*lda ),KIND=${ck}$) end do ! copy the off diagonal from a to e. note that e is real thus only ! the real part is needed, the imaginary part should be czero. if( upper ) then do i = 1, n-1 e( i ) = real( work( ofdpos+i*lda ),KIND=${ck}$) end do else do i = 1, n-1 e( i ) = real( work( ofdpos+(i-1)*lda ),KIND=${ck}$) end do endif hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_${ci}$hetrd_hb2st #:endif #:endfor pure module subroutine stdlib${ii}$_chb2st_kernels( uplo, wantz, ttype,st, ed, sweep, n, nb, ib,a, lda, & !! CHB2ST_KERNELS is an internal routine used by the CHETRD_HB2ST !! subroutine. v, tau, ldvt, work) ! -- 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) :: uplo logical(lk), intent(in) :: wantz integer(${ik}$), intent(in) :: ttype, st, ed, sweep, n, nb, ib, lda, ldvt ! Array Arguments complex(sp), intent(inout) :: a(lda,*) complex(sp), intent(out) :: v(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i, j1, j2, lm, ln, vpos, taupos, dpos, ofdpos, ajeter complex(sp) :: ctmp ! Intrinsic Functions ! Executable Statements ajeter = ib + ldvt upper = stdlib_lsame( uplo, 'U' ) if( upper ) then dpos = 2_${ik}$ * nb + 1_${ik}$ ofdpos = 2_${ik}$ * nb else dpos = 1_${ik}$ ofdpos = 2_${ik}$ endif ! upper case if( upper ) then if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = conjg( a( ofdpos-i, st+i ) ) a( ofdpos-i, st+i ) = czero end do ctmp = conjg( a( ofdpos, st ) ) call stdlib${ii}$_clarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$,tau( taupos ) ) a( ofdpos, st ) = ctmp lm = ed - st + 1_${ik}$ call stdlib${ii}$_clarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_clarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_clarfx( 'LEFT', ln, lm, v( vpos ),conjg( tau( taupos ) ),a( & dpos-nb, j1 ), lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) =conjg( a( dpos-nb-i, j1+i ) ) a( dpos-nb-i, j1+i ) = czero end do ctmp = conjg( a( dpos-nb, j1 ) ) call stdlib${ii}$_clarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$, tau( taupos ) ) a( dpos-nb, j1 ) = ctmp call stdlib${ii}$_clarfx( 'RIGHT', ln-1, lm, v( vpos ),tau( taupos ),a( dpos-nb+& 1_${ik}$, j1 ), lda-1, work) endif endif ! lower case else if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = a( ofdpos+i, st-1 ) a( ofdpos+i, st-1 ) = czero end do call stdlib${ii}$_clarfg( lm, a( ofdpos, st-1 ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) lm = ed - st + 1_${ik}$ call stdlib${ii}$_clarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_clarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_clarfx( 'RIGHT', lm, ln, v( vpos ),tau( taupos ), a( dpos+nb, & st ),lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = a( dpos+nb+i, st ) a( dpos+nb+i, st ) = czero end do call stdlib${ii}$_clarfg( lm, a( dpos+nb, st ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) call stdlib${ii}$_clarfx( 'LEFT', lm, ln-1, v( vpos ),conjg( tau( taupos ) ),a( & dpos+nb-1, st+1 ), lda-1, work) endif endif endif return end subroutine stdlib${ii}$_chb2st_kernels pure module subroutine stdlib${ii}$_zhb2st_kernels( uplo, wantz, ttype,st, ed, sweep, n, nb, ib,a, lda, & !! ZHB2ST_KERNELS is an internal routine used by the ZHETRD_HB2ST !! subroutine. v, tau, ldvt, work) ! -- 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) :: uplo logical(lk), intent(in) :: wantz integer(${ik}$), intent(in) :: ttype, st, ed, sweep, n, nb, ib, lda, ldvt ! Array Arguments complex(dp), intent(inout) :: a(lda,*) complex(dp), intent(out) :: v(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i, j1, j2, lm, ln, vpos, taupos, dpos, ofdpos, ajeter complex(dp) :: ctmp ! Intrinsic Functions ! Executable Statements ajeter = ib + ldvt upper = stdlib_lsame( uplo, 'U' ) if( upper ) then dpos = 2_${ik}$ * nb + 1_${ik}$ ofdpos = 2_${ik}$ * nb else dpos = 1_${ik}$ ofdpos = 2_${ik}$ endif ! upper case if( upper ) then if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = conjg( a( ofdpos-i, st+i ) ) a( ofdpos-i, st+i ) = czero end do ctmp = conjg( a( ofdpos, st ) ) call stdlib${ii}$_zlarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$,tau( taupos ) ) a( ofdpos, st ) = ctmp lm = ed - st + 1_${ik}$ call stdlib${ii}$_zlarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_zlarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_zlarfx( 'LEFT', ln, lm, v( vpos ),conjg( tau( taupos ) ),a( & dpos-nb, j1 ), lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) =conjg( a( dpos-nb-i, j1+i ) ) a( dpos-nb-i, j1+i ) = czero end do ctmp = conjg( a( dpos-nb, j1 ) ) call stdlib${ii}$_zlarfg( lm, ctmp, v( vpos+1 ), 1_${ik}$, tau( taupos ) ) a( dpos-nb, j1 ) = ctmp call stdlib${ii}$_zlarfx( 'RIGHT', ln-1, lm, v( vpos ),tau( taupos ),a( dpos-nb+& 1_${ik}$, j1 ), lda-1, work) endif endif ! lower case else if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = a( ofdpos+i, st-1 ) a( ofdpos+i, st-1 ) = czero end do call stdlib${ii}$_zlarfg( lm, a( ofdpos, st-1 ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) lm = ed - st + 1_${ik}$ call stdlib${ii}$_zlarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_zlarfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_zlarfx( 'RIGHT', lm, ln, v( vpos ),tau( taupos ), a( dpos+nb, & st ),lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = a( dpos+nb+i, st ) a( dpos+nb+i, st ) = czero end do call stdlib${ii}$_zlarfg( lm, a( dpos+nb, st ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) call stdlib${ii}$_zlarfx( 'LEFT', lm, ln-1, v( vpos ),conjg( tau( taupos ) ),a( & dpos+nb-1, st+1 ), lda-1, work) endif endif endif return end subroutine stdlib${ii}$_zhb2st_kernels #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$hb2st_kernels( uplo, wantz, ttype,st, ed, sweep, n, nb, ib,a, lda, & !! ZHB2ST_KERNELS: is an internal routine used by the ZHETRD_HB2ST !! subroutine. v, tau, ldvt, work) ! -- 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) :: uplo logical(lk), intent(in) :: wantz integer(${ik}$), intent(in) :: ttype, st, ed, sweep, n, nb, ib, lda, ldvt ! Array Arguments complex(${ck}$), intent(inout) :: a(lda,*) complex(${ck}$), intent(out) :: v(*), tau(*), work(*) ! ===================================================================== ! Local Scalars logical(lk) :: upper integer(${ik}$) :: i, j1, j2, lm, ln, vpos, taupos, dpos, ofdpos, ajeter complex(${ck}$) :: ctmp ! Intrinsic Functions ! Executable Statements ajeter = ib + ldvt upper = stdlib_lsame( uplo, 'U' ) if( upper ) then dpos = 2_${ik}$ * nb + 1_${ik}$ ofdpos = 2_${ik}$ * nb else dpos = 1_${ik}$ ofdpos = 2_${ik}$ endif ! upper case if( upper ) then if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = conjg( a( ofdpos-i, st+i ) ) a( ofdpos-i, st+i ) = czero end do ctmp = conjg( a( ofdpos, st ) ) call stdlib${ii}$_${ci}$larfg( lm, ctmp, v( vpos+1 ), 1_${ik}$,tau( taupos ) ) a( ofdpos, st ) = ctmp lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ci}$larfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ci}$larfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_${ci}$larfx( 'LEFT', ln, lm, v( vpos ),conjg( tau( taupos ) ),a( & dpos-nb, j1 ), lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) =conjg( a( dpos-nb-i, j1+i ) ) a( dpos-nb-i, j1+i ) = czero end do ctmp = conjg( a( dpos-nb, j1 ) ) call stdlib${ii}$_${ci}$larfg( lm, ctmp, v( vpos+1 ), 1_${ik}$, tau( taupos ) ) a( dpos-nb, j1 ) = ctmp call stdlib${ii}$_${ci}$larfx( 'RIGHT', ln-1, lm, v( vpos ),tau( taupos ),a( dpos-nb+& 1_${ik}$, j1 ), lda-1, work) endif endif ! lower case else if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st else vpos = mod( sweep-1, 2_${ik}$ ) * n + st taupos = mod( sweep-1, 2_${ik}$ ) * n + st endif if( ttype==1_${ik}$ ) then lm = ed - st + 1_${ik}$ v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = a( ofdpos+i, st-1 ) a( ofdpos+i, st-1 ) = czero end do call stdlib${ii}$_${ci}$larfg( lm, a( ofdpos, st-1 ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ci}$larfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==3_${ik}$ ) then lm = ed - st + 1_${ik}$ call stdlib${ii}$_${ci}$larfy( uplo, lm, v( vpos ), 1_${ik}$,conjg( tau( taupos ) ),a( dpos, st )& , lda-1, work) endif if( ttype==2_${ik}$ ) then j1 = ed+1 j2 = min( ed+nb, n ) ln = ed-st+1 lm = j2-j1+1 if( lm>0_${ik}$) then call stdlib${ii}$_${ci}$larfx( 'RIGHT', lm, ln, v( vpos ),tau( taupos ), a( dpos+nb, & st ),lda-1, work) if( wantz ) then vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 else vpos = mod( sweep-1, 2_${ik}$ ) * n + j1 taupos = mod( sweep-1, 2_${ik}$ ) * n + j1 endif v( vpos ) = cone do i = 1, lm-1 v( vpos+i ) = a( dpos+nb+i, st ) a( dpos+nb+i, st ) = czero end do call stdlib${ii}$_${ci}$larfg( lm, a( dpos+nb, st ), v( vpos+1 ), 1_${ik}$,tau( taupos ) ) call stdlib${ii}$_${ci}$larfx( 'LEFT', lm, ln-1, v( vpos ),conjg( tau( taupos ) ),a( & dpos+nb-1, st+1 ), lda-1, work) endif endif endif return end subroutine stdlib${ii}$_${ci}$hb2st_kernels #:endif #:endfor module subroutine stdlib${ii}$_ssytrd_sb2st( stage1, vect, uplo, n, kd, ab, ldab,d, e, hous, lhous, & !! SSYTRD_SB2ST reduces a real symmetric band matrix A to real symmetric !! tridiagonal form T by a orthogonal similarity transformation: !! Q**T * A * Q = T. work, lwork, info ) ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: stage1, uplo, vect integer(${ik}$), intent(in) :: n, kd, ldab, lhous, lwork integer(${ik}$), intent(out) :: info ! Array Arguments real(sp), intent(out) :: d(*), e(*) real(sp), intent(inout) :: ab(ldab,*) real(sp), intent(out) :: hous(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, wantq, upper, afters1 integer(${ik}$) :: i, m, k, ib, sweepid, myid, shift, stt, st, ed, stind, edind, & blklastind, colpt, thed, stepercol, grsiz, thgrsiz, thgrnb, thgrid, nbtiles, ttype, & tid, nthreads, debug, abdpos, abofdpos, dpos, ofdpos, awpos, inda, indw, apos, sizea, & lda, indv, indtau, sisev, sizetau, ldv, lhmin, lwmin ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required. ! test the input parameters debug = 0_${ik}$ info = 0_${ik}$ afters1 = stdlib_lsame( stage1, 'Y' ) wantq = stdlib_lsame( vect, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) .or. ( lhous==-1_${ik}$ ) ! determine the block size, the workspace size and the hous size. ib = stdlib${ii}$_ilaenv2stage( 2_${ik}$, 'SSYTRD_SB2ST', vect, n, kd, -1_${ik}$, -1_${ik}$ ) lhmin = stdlib${ii}$_ilaenv2stage( 3_${ik}$, 'SSYTRD_SB2ST', vect, n, kd, ib, -1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'SSYTRD_SB2ST', vect, n, kd, ib, -1_${ik}$ ) if( .not.afters1 .and. .not.stdlib_lsame( stage1, 'N' ) ) then info = -1_${ik}$ else if( .not.stdlib_lsame( vect, 'N' ) ) then info = -2_${ik}$ else if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( kd<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<(kd+1) ) then info = -7_${ik}$ else if( lhous<lhmin .and. .not.lquery ) then info = -11_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -13_${ik}$ end if if( info==0_${ik}$ ) then hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYTRD_SB2ST', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0_${ik}$ ) then hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine pointer position ldv = kd + ib sizetau = 2_${ik}$ * n sisev = 2_${ik}$ * n indtau = 1_${ik}$ indv = indtau + sizetau lda = 2_${ik}$ * kd + 1_${ik}$ sizea = lda * n inda = 1_${ik}$ indw = inda + sizea nthreads = 1_${ik}$ tid = 0_${ik}$ if( upper ) then apos = inda + kd awpos = inda dpos = apos + kd ofdpos = dpos - 1_${ik}$ abdpos = kd + 1_${ik}$ abofdpos = kd else apos = inda awpos = inda + kd + 1_${ik}$ dpos = apos ofdpos = dpos + 1_${ik}$ abdpos = 1_${ik}$ abofdpos = 2_${ik}$ endif ! case kd=0: ! the matrix is diagonal. we just copy it (convert to "real" for ! real because d is double and the imaginary part should be 0) ! and store it in d. a sequential code here is better or ! in a parallel environment it might need two cores for d and e if( kd==0_${ik}$ ) then do i = 1, n d( i ) = ( ab( abdpos, i ) ) end do do i = 1, n-1 e( i ) = zero end do hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! case kd=1: ! the matrix is already tridiagonal. we have to make diagonal ! and offdiagonal elements real, and store them in d and e. ! for that, for real precision just copy the diag and offdiag ! to d and e while for the complex case the bulge chasing is ! performed to convert the hermetian tridiagonal to symmetric ! tridiagonal. a simpler conversion formula might be used, but then ! updating the q matrix will be required and based if q is generated ! or not this might complicate the story. if( kd==1_${ik}$ ) then do i = 1, n d( i ) = ( ab( abdpos, i ) ) end do if( upper ) then do i = 1, n-1 e( i ) = ( ab( abofdpos, i+1 ) ) end do else do i = 1, n-1 e( i ) = ( ab( abofdpos, i ) ) end do endif hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! main code start here. ! reduce the symmetric band of a to a tridiagonal matrix. thgrsiz = n grsiz = 1_${ik}$ shift = 3_${ik}$ nbtiles = ceiling( real(n,KIND=sp)/real(kd,KIND=sp) ) stepercol = ceiling( real(shift,KIND=sp)/real(grsiz,KIND=sp) ) thgrnb = ceiling( real(n-1,KIND=sp)/real(thgrsiz,KIND=sp) ) call stdlib${ii}$_slacpy( "A", kd+1, n, ab, ldab, work( apos ), lda ) call stdlib${ii}$_slaset( "A", kd, n, zero, zero, work( awpos ), lda ) ! openmp parallelisation start here !$OMP PARALLEL PRIVATE( TID, THGRID, BLKLASTIND ) & !$OMP& PRIVATE( THED, I, M, K, ST, ED, STT, SWEEPID ) & !$OMP& PRIVATE( MYID, TTYPE, COLPT, STIND, EDIND ) & !$OMP& SHARED ( UPLO, WANTQ, INDV, INDTAU, HOUS, WORK) & !$OMP& SHARED ( N, KD, IB, NBTILES, LDA, LDV, INDA ) & !$OMP& SHARED ( STEPERCOL, THGRNB, THGRSIZ, GRSIZ, SHIFT ) !$OMP MASTER ! main bulge chasing loop loop_100: do thgrid = 1, thgrnb stt = (thgrid-1)*thgrsiz+1 thed = min( (stt + thgrsiz -1_${ik}$), (n-1)) loop_110: do i = stt, n-1 ed = min( i, thed ) if( stt>ed ) exit loop_120: do m = 1, stepercol st = stt loop_130: do sweepid = st, ed loop_140: do k = 1, grsiz myid = (i-sweepid)*(stepercol*grsiz)+ (m-1)*grsiz + k if ( myid==1_${ik}$ ) then ttype = 1_${ik}$ else ttype = mod( myid, 2_${ik}$ ) + 2_${ik}$ endif if( ttype==2_${ik}$ ) then colpt = (myid/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) blklastind = colpt else colpt = ((myid+1)/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) if( ( stind>=edind-1 ).and.( edind==n ) ) then blklastind = n else blklastind = 0_${ik}$ endif endif ! call the kernel !$ if( ttype/=1 ) then !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(in:WORK(MYID-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() !$ call stdlib${ii}$_ssb2st_kernels( uplo, wantq, ttype,stind, edind, & !$ sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & !$ indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ else !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() call stdlib${ii}$_ssb2st_kernels( uplo, wantq, ttype,stind, edind, & sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ endif if ( blklastind>=(n-1) ) then stt = stt + 1_${ik}$ exit endif end do loop_140 end do loop_130 end do loop_120 end do loop_110 end do loop_100 !$OMP END MASTER !$OMP END PARALLEL ! copy the diagonal from a to d. note that d is real thus only ! the real part is needed, the imaginary part should be zero. do i = 1, n d( i ) = ( work( dpos+(i-1)*lda ) ) end do ! copy the off diagonal from a to e. note that e is real thus only ! the real part is needed, the imaginary part should be zero. if( upper ) then do i = 1, n-1 e( i ) = ( work( ofdpos+i*lda ) ) end do else do i = 1, n-1 e( i ) = ( work( ofdpos+(i-1)*lda ) ) end do endif hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_ssytrd_sb2st module subroutine stdlib${ii}$_dsytrd_sb2st( stage1, vect, uplo, n, kd, ab, ldab,d, e, hous, lhous, & !! DSYTRD_SB2ST reduces a real symmetric band matrix A to real symmetric !! tridiagonal form T by a orthogonal similarity transformation: !! Q**T * A * Q = T. work, lwork, info ) ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: stage1, uplo, vect integer(${ik}$), intent(in) :: n, kd, ldab, lhous, lwork integer(${ik}$), intent(out) :: info ! Array Arguments real(dp), intent(out) :: d(*), e(*) real(dp), intent(inout) :: ab(ldab,*) real(dp), intent(out) :: hous(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, wantq, upper, afters1 integer(${ik}$) :: i, m, k, ib, sweepid, myid, shift, stt, st, ed, stind, edind, & blklastind, colpt, thed, stepercol, grsiz, thgrsiz, thgrnb, thgrid, nbtiles, ttype, & tid, nthreads, debug, abdpos, abofdpos, dpos, ofdpos, awpos, inda, indw, apos, sizea, & lda, indv, indtau, sidev, sizetau, ldv, lhmin, lwmin ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required. ! test the input parameters debug = 0_${ik}$ info = 0_${ik}$ afters1 = stdlib_lsame( stage1, 'Y' ) wantq = stdlib_lsame( vect, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) .or. ( lhous==-1_${ik}$ ) ! determine the block size, the workspace size and the hous size. ib = stdlib${ii}$_ilaenv2stage( 2_${ik}$, 'DSYTRD_SB2ST', vect, n, kd, -1_${ik}$, -1_${ik}$ ) lhmin = stdlib${ii}$_ilaenv2stage( 3_${ik}$, 'DSYTRD_SB2ST', vect, n, kd, ib, -1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'DSYTRD_SB2ST', vect, n, kd, ib, -1_${ik}$ ) if( .not.afters1 .and. .not.stdlib_lsame( stage1, 'N' ) ) then info = -1_${ik}$ else if( .not.stdlib_lsame( vect, 'N' ) ) then info = -2_${ik}$ else if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( kd<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<(kd+1) ) then info = -7_${ik}$ else if( lhous<lhmin .and. .not.lquery ) then info = -11_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -13_${ik}$ end if if( info==0_${ik}$ ) then hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTRD_SB2ST', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0_${ik}$ ) then hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine pointer position ldv = kd + ib sizetau = 2_${ik}$ * n sidev = 2_${ik}$ * n indtau = 1_${ik}$ indv = indtau + sizetau lda = 2_${ik}$ * kd + 1_${ik}$ sizea = lda * n inda = 1_${ik}$ indw = inda + sizea nthreads = 1_${ik}$ tid = 0_${ik}$ if( upper ) then apos = inda + kd awpos = inda dpos = apos + kd ofdpos = dpos - 1_${ik}$ abdpos = kd + 1_${ik}$ abofdpos = kd else apos = inda awpos = inda + kd + 1_${ik}$ dpos = apos ofdpos = dpos + 1_${ik}$ abdpos = 1_${ik}$ abofdpos = 2_${ik}$ endif ! case kd=0: ! the matrix is diagonal. we just copy it (convert to "real" for ! real because d is double and the imaginary part should be 0) ! and store it in d. a sequential code here is better or ! in a parallel environment it might need two cores for d and e if( kd==0_${ik}$ ) then do i = 1, n d( i ) = ( ab( abdpos, i ) ) end do do i = 1, n-1 e( i ) = zero end do hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! case kd=1: ! the matrix is already tridiagonal. we have to make diagonal ! and offdiagonal elements real, and store them in d and e. ! for that, for real precision just copy the diag and offdiag ! to d and e while for the complex case the bulge chasing is ! performed to convert the hermetian tridiagonal to symmetric ! tridiagonal. a simpler conversion formula might be used, but then ! updating the q matrix will be required and based if q is generated ! or not this might complicate the story. if( kd==1_${ik}$ ) then do i = 1, n d( i ) = ( ab( abdpos, i ) ) end do if( upper ) then do i = 1, n-1 e( i ) = ( ab( abofdpos, i+1 ) ) end do else do i = 1, n-1 e( i ) = ( ab( abofdpos, i ) ) end do endif hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! main code start here. ! reduce the symmetric band of a to a tridiagonal matrix. thgrsiz = n grsiz = 1_${ik}$ shift = 3_${ik}$ nbtiles = ceiling( real(n,KIND=dp)/real(kd,KIND=dp) ) stepercol = ceiling( real(shift,KIND=dp)/real(grsiz,KIND=dp) ) thgrnb = ceiling( real(n-1,KIND=dp)/real(thgrsiz,KIND=dp) ) call stdlib${ii}$_dlacpy( "A", kd+1, n, ab, ldab, work( apos ), lda ) call stdlib${ii}$_dlaset( "A", kd, n, zero, zero, work( awpos ), lda ) ! openmp parallelisation start here !$OMP PARALLEL PRIVATE( TID, THGRID, BLKLASTIND ) & !$OMP& PRIVATE( THED, I, M, K, ST, ED, STT, SWEEPID ) & !$OMP& PRIVATE( MYID, TTYPE, COLPT, STIND, EDIND ) & !$OMP& SHARED ( UPLO, WANTQ, INDV, INDTAU, HOUS, WORK) & !$OMP& SHARED ( N, KD, IB, NBTILES, LDA, LDV, INDA ) & !$OMP& SHARED ( STEPERCOL, THGRNB, THGRSIZ, GRSIZ, SHIFT ) !$OMP MASTER ! main bulge chasing loop loop_100: do thgrid = 1, thgrnb stt = (thgrid-1)*thgrsiz+1 thed = min( (stt + thgrsiz -1_${ik}$), (n-1)) loop_110: do i = stt, n-1 ed = min( i, thed ) if( stt>ed ) exit loop_120: do m = 1, stepercol st = stt loop_130: do sweepid = st, ed loop_140: do k = 1, grsiz myid = (i-sweepid)*(stepercol*grsiz)+ (m-1)*grsiz + k if ( myid==1_${ik}$ ) then ttype = 1_${ik}$ else ttype = mod( myid, 2_${ik}$ ) + 2_${ik}$ endif if( ttype==2_${ik}$ ) then colpt = (myid/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) blklastind = colpt else colpt = ((myid+1)/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) if( ( stind>=edind-1 ).and.( edind==n ) ) then blklastind = n else blklastind = 0_${ik}$ endif endif ! call the kernel !$ if( ttype/=1 ) then !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(in:WORK(MYID-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() !$ call stdlib${ii}$_dsb2st_kernels( uplo, wantq, ttype,stind, edind, & !$ sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & !$ indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ else !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() call stdlib${ii}$_dsb2st_kernels( uplo, wantq, ttype,stind, edind, & sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ endif if ( blklastind>=(n-1) ) then stt = stt + 1_${ik}$ exit endif end do loop_140 end do loop_130 end do loop_120 end do loop_110 end do loop_100 !$OMP END MASTER !$OMP END PARALLEL ! copy the diagonal from a to d. note that d is real thus only ! the real part is needed, the imaginary part should be zero. do i = 1, n d( i ) = ( work( dpos+(i-1)*lda ) ) end do ! copy the off diagonal from a to e. note that e is real thus only ! the real part is needed, the imaginary part should be zero. if( upper ) then do i = 1, n-1 e( i ) = ( work( ofdpos+i*lda ) ) end do else do i = 1, n-1 e( i ) = ( work( ofdpos+(i-1)*lda ) ) end do endif hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_dsytrd_sb2st #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$sytrd_sb2st( stage1, vect, uplo, n, kd, ab, ldab,d, e, hous, lhous, & !! DSYTRD_SB2ST: reduces a real symmetric band matrix A to real symmetric !! tridiagonal form T by a orthogonal similarity transformation: !! Q**T * A * Q = T. work, lwork, info ) ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments character, intent(in) :: stage1, uplo, vect integer(${ik}$), intent(in) :: n, kd, ldab, lhous, lwork integer(${ik}$), intent(out) :: info ! Array Arguments real(${rk}$), intent(out) :: d(*), e(*) real(${rk}$), intent(inout) :: ab(ldab,*) real(${rk}$), intent(out) :: hous(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, wantq, upper, afters1 integer(${ik}$) :: i, m, k, ib, sweepid, myid, shift, stt, st, ed, stind, edind, & blklastind, colpt, thed, stepercol, grsiz, thgrsiz, thgrnb, thgrid, nbtiles, ttype, & tid, nthreads, debug, abdpos, abofdpos, dpos, ofdpos, awpos, inda, indw, apos, sizea, & lda, indv, indtau, sidev, sizetau, ldv, lhmin, lwmin ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required. ! test the input parameters debug = 0_${ik}$ info = 0_${ik}$ afters1 = stdlib_lsame( stage1, 'Y' ) wantq = stdlib_lsame( vect, 'V' ) upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) .or. ( lhous==-1_${ik}$ ) ! determine the block size, the workspace size and the hous size. ib = stdlib${ii}$_ilaenv2stage( 2_${ik}$, 'DSYTRD_SB2ST', vect, n, kd, -1_${ik}$, -1_${ik}$ ) lhmin = stdlib${ii}$_ilaenv2stage( 3_${ik}$, 'DSYTRD_SB2ST', vect, n, kd, ib, -1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'DSYTRD_SB2ST', vect, n, kd, ib, -1_${ik}$ ) if( .not.afters1 .and. .not.stdlib_lsame( stage1, 'N' ) ) then info = -1_${ik}$ else if( .not.stdlib_lsame( vect, 'N' ) ) then info = -2_${ik}$ else if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -3_${ik}$ else if( n<0_${ik}$ ) then info = -4_${ik}$ else if( kd<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<(kd+1) ) then info = -7_${ik}$ else if( lhous<lhmin .and. .not.lquery ) then info = -11_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -13_${ik}$ end if if( info==0_${ik}$ ) then hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTRD_SB2ST', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0_${ik}$ ) then hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine pointer position ldv = kd + ib sizetau = 2_${ik}$ * n sidev = 2_${ik}$ * n indtau = 1_${ik}$ indv = indtau + sizetau lda = 2_${ik}$ * kd + 1_${ik}$ sizea = lda * n inda = 1_${ik}$ indw = inda + sizea nthreads = 1_${ik}$ tid = 0_${ik}$ if( upper ) then apos = inda + kd awpos = inda dpos = apos + kd ofdpos = dpos - 1_${ik}$ abdpos = kd + 1_${ik}$ abofdpos = kd else apos = inda awpos = inda + kd + 1_${ik}$ dpos = apos ofdpos = dpos + 1_${ik}$ abdpos = 1_${ik}$ abofdpos = 2_${ik}$ endif ! case kd=0: ! the matrix is diagonal. we just copy it (convert to "real" for ! real because d is double and the imaginary part should be 0) ! and store it in d. a sequential code here is better or ! in a parallel environment it might need two cores for d and e if( kd==0_${ik}$ ) then do i = 1, n d( i ) = ( ab( abdpos, i ) ) end do do i = 1, n-1 e( i ) = zero end do hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! case kd=1: ! the matrix is already tridiagonal. we have to make diagonal ! and offdiagonal elements real, and store them in d and e. ! for that, for real precision just copy the diag and offdiag ! to d and e while for the complex case the bulge chasing is ! performed to convert the hermetian tridiagonal to symmetric ! tridiagonal. a simpler conversion formula might be used, but then ! updating the q matrix will be required and based if q is generated ! or not this might complicate the story. if( kd==1_${ik}$ ) then do i = 1, n d( i ) = ( ab( abdpos, i ) ) end do if( upper ) then do i = 1, n-1 e( i ) = ( ab( abofdpos, i+1 ) ) end do else do i = 1, n-1 e( i ) = ( ab( abofdpos, i ) ) end do endif hous( 1_${ik}$ ) = 1_${ik}$ work( 1_${ik}$ ) = 1_${ik}$ return end if ! main code start here. ! reduce the symmetric band of a to a tridiagonal matrix. thgrsiz = n grsiz = 1_${ik}$ shift = 3_${ik}$ nbtiles = ceiling( real(n,KIND=${rk}$)/real(kd,KIND=${rk}$) ) stepercol = ceiling( real(shift,KIND=${rk}$)/real(grsiz,KIND=${rk}$) ) thgrnb = ceiling( real(n-1,KIND=${rk}$)/real(thgrsiz,KIND=${rk}$) ) call stdlib${ii}$_${ri}$lacpy( "A", kd+1, n, ab, ldab, work( apos ), lda ) call stdlib${ii}$_${ri}$laset( "A", kd, n, zero, zero, work( awpos ), lda ) ! openmp parallelisation start here !$OMP PARALLEL PRIVATE( TID, THGRID, BLKLASTIND ) & !$OMP& PRIVATE( THED, I, M, K, ST, ED, STT, SWEEPID ) & !$OMP& PRIVATE( MYID, TTYPE, COLPT, STIND, EDIND ) & !$OMP& SHARED ( UPLO, WANTQ, INDV, INDTAU, HOUS, WORK) & !$OMP& SHARED ( N, KD, IB, NBTILES, LDA, LDV, INDA ) & !$OMP& SHARED ( STEPERCOL, THGRNB, THGRSIZ, GRSIZ, SHIFT ) !$OMP MASTER ! main bulge chasing loop loop_100: do thgrid = 1, thgrnb stt = (thgrid-1)*thgrsiz+1 thed = min( (stt + thgrsiz -1_${ik}$), (n-1)) loop_110: do i = stt, n-1 ed = min( i, thed ) if( stt>ed ) exit loop_120: do m = 1, stepercol st = stt loop_130: do sweepid = st, ed loop_140: do k = 1, grsiz myid = (i-sweepid)*(stepercol*grsiz)+ (m-1)*grsiz + k if ( myid==1_${ik}$ ) then ttype = 1_${ik}$ else ttype = mod( myid, 2_${ik}$ ) + 2_${ik}$ endif if( ttype==2_${ik}$ ) then colpt = (myid/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) blklastind = colpt else colpt = ((myid+1)/2_${ik}$)*kd + sweepid stind = colpt-kd+1 edind = min(colpt,n) if( ( stind>=edind-1 ).and.( edind==n ) ) then blklastind = n else blklastind = 0_${ik}$ endif endif ! call the kernel !$ if( ttype/=1 ) then !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(in:WORK(MYID-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() !$ call stdlib${ii}$_${ri}$sb2st_kernels( uplo, wantq, ttype,stind, edind, & !$ sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & !$ indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ else !$OMP TASK DEPEND(in:WORK(MYID+SHIFT-1)) & !$OMP& DEPEND(out:WORK(MYID)) !$ tid = omp_get_thread_num() call stdlib${ii}$_${ri}$sb2st_kernels( uplo, wantq, ttype,stind, edind, & sweepid, n, kd, ib,work ( inda ), lda,hous( indv ), hous( & indtau ), ldv,work( indw + tid*kd ) ) !$OMP END TASK !$ endif if ( blklastind>=(n-1) ) then stt = stt + 1_${ik}$ exit endif end do loop_140 end do loop_130 end do loop_120 end do loop_110 end do loop_100 !$OMP END MASTER !$OMP END PARALLEL ! copy the diagonal from a to d. note that d is real thus only ! the real part is needed, the imaginary part should be zero. do i = 1, n d( i ) = ( work( dpos+(i-1)*lda ) ) end do ! copy the off diagonal from a to e. note that e is real thus only ! the real part is needed, the imaginary part should be zero. if( upper ) then do i = 1, n-1 e( i ) = ( work( ofdpos+i*lda ) ) end do else do i = 1, n-1 e( i ) = ( work( ofdpos+(i-1)*lda ) ) end do endif hous( 1_${ik}$ ) = lhmin work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_${ri}$sytrd_sb2st #:endif #:endfor module subroutine stdlib${ii}$_ssytrd_sy2sb( uplo, n, kd, a, lda, ab, ldab, tau,work, lwork, info ) !! SSYTRD_SY2SB reduces a real symmetric matrix A to real symmetric !! band-diagonal form AB by a orthogonal similarity transformation: !! Q**T * A * Q = AB. ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldab, lwork, n, kd ! Array Arguments real(sp), intent(inout) :: a(lda,*) real(sp), intent(out) :: ab(ldab,*), tau(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, j, iinfo, lwmin, pn, pk, llk, ldt, ldw, lds2, lds1, ls2, ls1, lw, lt,& tpos, wpos, s2pos, s1pos ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required ! and test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'SSYTRD_SY2SB', '', n, kd, -1_${ik}$, -1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kd<0_${ik}$ ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -5_${ik}$ else if( ldab<max( 1_${ik}$, kd+1 ) ) then info = -7_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SSYTRD_SY2SB', -info ) return else if( lquery ) then work( 1_${ik}$ ) = lwmin return end if ! quick return if possible ! copy the upper/lower portion of a into ab if( n<=kd+1 ) then if( upper ) then do i = 1, n llk = min( kd+1, i ) call stdlib${ii}$_scopy( llk, a( i-llk+1, i ), 1_${ik}$,ab( kd+1-llk+1, i ), 1_${ik}$ ) end do else do i = 1, n llk = min( kd+1, n-i+1 ) call stdlib${ii}$_scopy( llk, a( i, i ), 1_${ik}$, ab( 1_${ik}$, i ), 1_${ik}$ ) end do endif work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine the pointer position for the workspace ldt = kd lds1 = kd lt = ldt*kd lw = n*kd ls1 = lds1*kd ls2 = lwmin - lt - lw - ls1 ! ls2 = n*max(kd,factoptnb) tpos = 1_${ik}$ wpos = tpos + lt s1pos = wpos + lw s2pos = s1pos + ls1 if( upper ) then ldw = kd lds2 = kd else ldw = n lds2 = n endif ! set the workspace of the triangular matrix t to zero once such a ! way every time t is generated the upper/lower portion will be always zero call stdlib${ii}$_slaset( "A", ldt, kd, zero, zero, work( tpos ), ldt ) if( upper ) then do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the lq factorization of the current block call stdlib${ii}$_sgelqf( kd, pn, a( i, i+kd ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_scopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do call stdlib${ii}$_slaset( 'LOWER', pk, pk, zero, one,a( i, i+kd ), lda ) ! form the matrix t call stdlib${ii}$_slarft( 'FORWARD', 'ROWWISE', pn, pk,a( i, i+kd ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_sgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pn, pk,one, work( tpos ), & ldt,a( i, i+kd ), lda,zero, work( s2pos ), lds2 ) call stdlib${ii}$_ssymm( 'RIGHT', uplo, pk, pn,one, a( i+kd, i+kd ), lda,work( s2pos & ), lds2,zero, work( wpos ), ldw ) call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'CONJUGATE', pk, pk, pn,one, work( wpos ), & ldw,work( s2pos ), lds2,zero, work( s1pos ), lds1 ) call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pk, pn, pk,-half, work( & s1pos ), lds1,a( i, i+kd ), lda,one, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v'*w - w'*v call stdlib${ii}$_ssyr2k( uplo, 'CONJUGATE', pn, pk,-one, a( i, i+kd ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) end do ! copy the upper band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_scopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do else ! reduce the lower triangle of a to lower band matrix loop_40: do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the qr factorization of the current block call stdlib${ii}$_sgeqrf( pn, kd, a( i+kd, i ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_scopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do call stdlib${ii}$_slaset( 'UPPER', pk, pk, zero, one,a( i+kd, i ), lda ) ! form the matrix t call stdlib${ii}$_slarft( 'FORWARD', 'COLUMNWISE', pn, pk,a( i+kd, i ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,one, a( i+kd, i ),& lda,work( tpos ), ldt,zero, work( s2pos ), lds2 ) call stdlib${ii}$_ssymm( 'LEFT', uplo, pn, pk,one, a( i+kd, i+kd ), lda,work( s2pos ),& lds2,zero, work( wpos ), ldw ) call stdlib${ii}$_sgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pk, pn,one, work( s2pos ), & lds2,work( wpos ), ldw,zero, work( s1pos ), lds1 ) call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,-half, a( i+kd, i & ), lda,work( s1pos ), lds1,one, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v*w' - w*v' call stdlib${ii}$_ssyr2k( uplo, 'NO TRANSPOSE', pn, pk,-one, a( i+kd, i ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) ! ================================================================== ! restore a for comparison and checking to be removed ! do 45 j = i, i+pk-1 ! llk = min( kd, n-j ) + 1 ! call stdlib${ii}$_scopy( llk, ab( 1, j ), 1, a( j, j ), 1 ) 45 continue ! ================================================================== end do loop_40 ! copy the lower band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_scopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do end if work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_ssytrd_sy2sb module subroutine stdlib${ii}$_dsytrd_sy2sb( uplo, n, kd, a, lda, ab, ldab, tau,work, lwork, info ) !! DSYTRD_SY2SB reduces a real symmetric matrix A to real symmetric !! band-diagonal form AB by a orthogonal similarity transformation: !! Q**T * A * Q = AB. ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldab, lwork, n, kd ! Array Arguments real(dp), intent(inout) :: a(lda,*) real(dp), intent(out) :: ab(ldab,*), tau(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, j, iinfo, lwmin, pn, pk, llk, ldt, ldw, lds2, lds1, ls2, ls1, lw, lt,& tpos, wpos, s2pos, s1pos ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required ! and test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'DSYTRD_SY2SB', '', n, kd, -1_${ik}$, -1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kd<0_${ik}$ ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -5_${ik}$ else if( ldab<max( 1_${ik}$, kd+1 ) ) then info = -7_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTRD_SY2SB', -info ) return else if( lquery ) then work( 1_${ik}$ ) = lwmin return end if ! quick return if possible ! copy the upper/lower portion of a into ab if( n<=kd+1 ) then if( upper ) then do i = 1, n llk = min( kd+1, i ) call stdlib${ii}$_dcopy( llk, a( i-llk+1, i ), 1_${ik}$,ab( kd+1-llk+1, i ), 1_${ik}$ ) end do else do i = 1, n llk = min( kd+1, n-i+1 ) call stdlib${ii}$_dcopy( llk, a( i, i ), 1_${ik}$, ab( 1_${ik}$, i ), 1_${ik}$ ) end do endif work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine the pointer position for the workspace ldt = kd lds1 = kd lt = ldt*kd lw = n*kd ls1 = lds1*kd ls2 = lwmin - lt - lw - ls1 ! ls2 = n*max(kd,factoptnb) tpos = 1_${ik}$ wpos = tpos + lt s1pos = wpos + lw s2pos = s1pos + ls1 if( upper ) then ldw = kd lds2 = kd else ldw = n lds2 = n endif ! set the workspace of the triangular matrix t to zero once such a ! way every time t is generated the upper/lower portion will be always zero call stdlib${ii}$_dlaset( "A", ldt, kd, zero, zero, work( tpos ), ldt ) if( upper ) then do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the lq factorization of the current block call stdlib${ii}$_dgelqf( kd, pn, a( i, i+kd ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_dcopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do call stdlib${ii}$_dlaset( 'LOWER', pk, pk, zero, one,a( i, i+kd ), lda ) ! form the matrix t call stdlib${ii}$_dlarft( 'FORWARD', 'ROWWISE', pn, pk,a( i, i+kd ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_dgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pn, pk,one, work( tpos ), & ldt,a( i, i+kd ), lda,zero, work( s2pos ), lds2 ) call stdlib${ii}$_dsymm( 'RIGHT', uplo, pk, pn,one, a( i+kd, i+kd ), lda,work( s2pos & ), lds2,zero, work( wpos ), ldw ) call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'CONJUGATE', pk, pk, pn,one, work( wpos ), & ldw,work( s2pos ), lds2,zero, work( s1pos ), lds1 ) call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pk, pn, pk,-half, work( & s1pos ), lds1,a( i, i+kd ), lda,one, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v'*w - w'*v call stdlib${ii}$_dsyr2k( uplo, 'CONJUGATE', pn, pk,-one, a( i, i+kd ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) end do ! copy the upper band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_dcopy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do else ! reduce the lower triangle of a to lower band matrix loop_40: do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the qr factorization of the current block call stdlib${ii}$_dgeqrf( pn, kd, a( i+kd, i ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_dcopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do call stdlib${ii}$_dlaset( 'UPPER', pk, pk, zero, one,a( i+kd, i ), lda ) ! form the matrix t call stdlib${ii}$_dlarft( 'FORWARD', 'COLUMNWISE', pn, pk,a( i+kd, i ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,one, a( i+kd, i ),& lda,work( tpos ), ldt,zero, work( s2pos ), lds2 ) call stdlib${ii}$_dsymm( 'LEFT', uplo, pn, pk,one, a( i+kd, i+kd ), lda,work( s2pos ),& lds2,zero, work( wpos ), ldw ) call stdlib${ii}$_dgemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pk, pn,one, work( s2pos ), & lds2,work( wpos ), ldw,zero, work( s1pos ), lds1 ) call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,-half, a( i+kd, i & ), lda,work( s1pos ), lds1,one, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v*w' - w*v' call stdlib${ii}$_dsyr2k( uplo, 'NO TRANSPOSE', pn, pk,-one, a( i+kd, i ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) ! ================================================================== ! restore a for comparison and checking to be removed ! do 45 j = i, i+pk-1 ! llk = min( kd, n-j ) + 1 ! call stdlib${ii}$_dcopy( llk, ab( 1, j ), 1, a( j, j ), 1 ) 45 continue ! ================================================================== end do loop_40 ! copy the lower band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_dcopy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do end if work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_dsytrd_sy2sb #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] module subroutine stdlib${ii}$_${ri}$sytrd_sy2sb( uplo, n, kd, a, lda, ab, ldab, tau,work, lwork, info ) !! DSYTRD_SY2SB: reduces a real symmetric matrix A to real symmetric !! band-diagonal form AB by a orthogonal similarity transformation: !! Q**T * A * Q = AB. ! -- 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) :: uplo integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldab, lwork, n, kd ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(out) :: ab(ldab,*), tau(*), work(*) ! ===================================================================== ! Parameters ! Local Scalars logical(lk) :: lquery, upper integer(${ik}$) :: i, j, iinfo, lwmin, pn, pk, llk, ldt, ldw, lds2, lds1, ls2, ls1, lw, lt,& tpos, wpos, s2pos, s1pos ! Intrinsic Functions ! Executable Statements ! determine the minimal workspace size required ! and test the input parameters info = 0_${ik}$ upper = stdlib_lsame( uplo, 'U' ) lquery = ( lwork==-1_${ik}$ ) lwmin = stdlib${ii}$_ilaenv2stage( 4_${ik}$, 'DSYTRD_SY2SB', '', n, kd, -1_${ik}$, -1_${ik}$ ) if( .not.upper .and. .not.stdlib_lsame( uplo, 'L' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kd<0_${ik}$ ) then info = -3_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -5_${ik}$ else if( ldab<max( 1_${ik}$, kd+1 ) ) then info = -7_${ik}$ else if( lwork<lwmin .and. .not.lquery ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DSYTRD_SY2SB', -info ) return else if( lquery ) then work( 1_${ik}$ ) = lwmin return end if ! quick return if possible ! copy the upper/lower portion of a into ab if( n<=kd+1 ) then if( upper ) then do i = 1, n llk = min( kd+1, i ) call stdlib${ii}$_${ri}$copy( llk, a( i-llk+1, i ), 1_${ik}$,ab( kd+1-llk+1, i ), 1_${ik}$ ) end do else do i = 1, n llk = min( kd+1, n-i+1 ) call stdlib${ii}$_${ri}$copy( llk, a( i, i ), 1_${ik}$, ab( 1_${ik}$, i ), 1_${ik}$ ) end do endif work( 1_${ik}$ ) = 1_${ik}$ return end if ! determine the pointer position for the workspace ldt = kd lds1 = kd lt = ldt*kd lw = n*kd ls1 = lds1*kd ls2 = lwmin - lt - lw - ls1 ! ls2 = n*max(kd,factoptnb) tpos = 1_${ik}$ wpos = tpos + lt s1pos = wpos + lw s2pos = s1pos + ls1 if( upper ) then ldw = kd lds2 = kd else ldw = n lds2 = n endif ! set the workspace of the triangular matrix t to zero once such a ! way every time t is generated the upper/lower portion will be always zero call stdlib${ii}$_${ri}$laset( "A", ldt, kd, zero, zero, work( tpos ), ldt ) if( upper ) then do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the lq factorization of the current block call stdlib${ii}$_${ri}$gelqf( kd, pn, a( i, i+kd ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_${ri}$copy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do call stdlib${ii}$_${ri}$laset( 'LOWER', pk, pk, zero, one,a( i, i+kd ), lda ) ! form the matrix t call stdlib${ii}$_${ri}$larft( 'FORWARD', 'ROWWISE', pn, pk,a( i, i+kd ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_${ri}$gemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pn, pk,one, work( tpos ), & ldt,a( i, i+kd ), lda,zero, work( s2pos ), lds2 ) call stdlib${ii}$_${ri}$symm( 'RIGHT', uplo, pk, pn,one, a( i+kd, i+kd ), lda,work( s2pos & ), lds2,zero, work( wpos ), ldw ) call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'CONJUGATE', pk, pk, pn,one, work( wpos ), & ldw,work( s2pos ), lds2,zero, work( s1pos ), lds1 ) call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pk, pn, pk,-half, work( & s1pos ), lds1,a( i, i+kd ), lda,one, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v'*w - w'*v call stdlib${ii}$_${ri}$syr2k( uplo, 'CONJUGATE', pn, pk,-one, a( i, i+kd ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) end do ! copy the upper band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_${ri}$copy( llk, a( j, j ), lda, ab( kd+1, j ), ldab-1 ) end do else ! reduce the lower triangle of a to lower band matrix loop_40: do i = 1, n - kd, kd pn = n-i-kd+1 pk = min( n-i-kd+1, kd ) ! compute the qr factorization of the current block call stdlib${ii}$_${ri}$geqrf( pn, kd, a( i+kd, i ), lda,tau( i ), work( s2pos ), ls2, & iinfo ) ! copy the upper portion of a into ab do j = i, i+pk-1 llk = min( kd, n-j ) + 1_${ik}$ call stdlib${ii}$_${ri}$copy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do call stdlib${ii}$_${ri}$laset( 'UPPER', pk, pk, zero, one,a( i+kd, i ), lda ) ! form the matrix t call stdlib${ii}$_${ri}$larft( 'FORWARD', 'COLUMNWISE', pn, pk,a( i+kd, i ), lda, tau( i ),& work( tpos ), ldt ) ! compute w: call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,one, a( i+kd, i ),& lda,work( tpos ), ldt,zero, work( s2pos ), lds2 ) call stdlib${ii}$_${ri}$symm( 'LEFT', uplo, pn, pk,one, a( i+kd, i+kd ), lda,work( s2pos ),& lds2,zero, work( wpos ), ldw ) call stdlib${ii}$_${ri}$gemm( 'CONJUGATE', 'NO TRANSPOSE', pk, pk, pn,one, work( s2pos ), & lds2,work( wpos ), ldw,zero, work( s1pos ), lds1 ) call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', pn, pk, pk,-half, a( i+kd, i & ), lda,work( s1pos ), lds1,one, work( wpos ), ldw ) ! update the unreduced submatrix a(i+kd:n,i+kd:n), using ! an update of the form: a := a - v*w' - w*v' call stdlib${ii}$_${ri}$syr2k( uplo, 'NO TRANSPOSE', pn, pk,-one, a( i+kd, i ), lda,work( & wpos ), ldw,one, a( i+kd, i+kd ), lda ) ! ================================================================== ! restore a for comparison and checking to be removed ! do 45 j = i, i+pk-1 ! llk = min( kd, n-j ) + 1 ! call stdlib${ii}$_${ri}$copy( llk, ab( 1, j ), 1, a( j, j ), 1 ) 45 continue ! ================================================================== end do loop_40 ! copy the lower band to ab which is the band storage matrix do j = n-kd+1, n llk = min(kd, n-j) + 1_${ik}$ call stdlib${ii}$_${ri}$copy( llk, a( j, j ), 1_${ik}$, ab( 1_${ik}$, j ), 1_${ik}$ ) end do end if work( 1_${ik}$ ) = lwmin return end subroutine stdlib${ii}$_${ri}$sytrd_sy2sb #:endif #:endfor #:endfor end submodule stdlib_lapack_eigv_sym