stdlib_lapack_solve_chol_comp.fypp Source File


Source Code

#:include "common.fypp" 
submodule(stdlib_lapack_solve) stdlib_lapack_solve_chol_comp
  implicit none


  contains
#:for ik,it,ii in LINALG_INT_KINDS_TYPES

     pure module subroutine stdlib${ii}$_spocon( uplo, n, a, lda, anorm, rcond, work, iwork,info )
     !! SPOCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite matrix using the
     !! Cholesky factorization A = U**T*U or A = L*L**T computed by SPOTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(sp) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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}$
           else if( anorm<zero ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPOCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of inv(a).
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_slacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_slatrs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_slatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_slatrs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_slatrs( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_srscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_spocon

     pure module subroutine stdlib${ii}$_dpocon( uplo, n, a, lda, anorm, rcond, work, iwork,info )
     !! DPOCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite matrix using the
     !! Cholesky factorization A = U**T*U or A = L*L**T computed by DPOTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(dp) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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}$
           else if( anorm<zero ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of inv(a).
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_dlacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_dlatrs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_dlatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_dlatrs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_dlatrs( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_drscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_dpocon

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pocon( uplo, n, a, lda, anorm, rcond, work, iwork,info )
     !! DPOCON: estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite matrix using the
     !! Cholesky factorization A = U**T*U or A = L*L**T computed by DPOTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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
           real(${rk}$), intent(in) :: anorm
           real(${rk}$), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(inout) :: a(lda,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(${rk}$) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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}$
           else if( anorm<zero ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of inv(a).
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_${ri}$lacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_${ri}$latrs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_${ri}$latrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_${ri}$latrs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_${ri}$latrs( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_i${ri}$amax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_${ri}$rscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_${ri}$pocon

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpocon( uplo, n, a, lda, anorm, rcond, work, rwork,info )
     !! CPOCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite matrix using the
     !! Cholesky factorization A = U**H*U or A = L*L**H computed by CPOTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(inout) :: a(lda,*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(sp) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(sp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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}$
           else if( anorm<zero ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPOCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of inv(a).
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_clacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_clatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,&
                            work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_clatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_clatrs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_clatrs( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,&
                            work, scaleu, rwork, info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_icamax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_csrscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_cpocon

     pure module subroutine stdlib${ii}$_zpocon( uplo, n, a, lda, anorm, rcond, work, rwork,info )
     !! ZPOCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite matrix using the
     !! Cholesky factorization A = U**H*U or A = L*L**H computed by ZPOTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(inout) :: a(lda,*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(dp) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(dp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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}$
           else if( anorm<zero ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of inv(a).
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_zlatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,&
                            work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_zlatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_zlatrs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_zlatrs( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,&
                            work, scaleu, rwork, info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_izamax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_zdrscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_zpocon

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pocon( uplo, n, a, lda, anorm, rcond, work, rwork,info )
     !! ZPOCON: estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite matrix using the
     !! Cholesky factorization A = U**H*U or A = L*L**H computed by ZPOTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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
           real(${ck}$), intent(in) :: anorm
           real(${ck}$), intent(out) :: rcond
           ! Array Arguments 
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(inout) :: a(lda,*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(${ck}$) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(${ck}$) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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}$
           else if( anorm<zero ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of inv(a).
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_${ci}$latrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,&
                            work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_${ci}$latrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_${ci}$latrs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, &
                           scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_${ci}$latrs( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,&
                            work, scaleu, rwork, info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_i${ci}$amax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_${ci}$drscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_${ci}$pocon

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spotrf( uplo, n, a, lda, info )
     !! SPOTRF computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jb, nb
           ! 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( 'SPOTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment.
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code.
              call stdlib${ii}$_spotrf2( uplo, n, a, lda, info )
           else
              ! use blocked code.
              if( upper ) then
                 ! compute the cholesky factorization a = u**t*u.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_ssyrk( 'UPPER', 'TRANSPOSE', jb, j-1, -one,a( 1_${ik}$, j ), lda, one, a(&
                               j, j ), lda )
                    call stdlib${ii}$_spotrf2( 'UPPER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block row.
                       call stdlib${ii}$_sgemm( 'TRANSPOSE', 'NO TRANSPOSE', jb, n-j-jb+1,j-1, -one, a( &
                                 1_${ik}$, j ), lda, a( 1_${ik}$, j+jb ),lda, one, a( j, j+jb ), lda )
                       call stdlib${ii}$_strsm( 'LEFT', 'UPPER', 'TRANSPOSE', 'NON-UNIT',jb, n-j-jb+1, &
                                 one, a( j, j ), lda,a( j, j+jb ), lda )
                    end if
                 end do
              else
                 ! compute the cholesky factorization a = l*l**t.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_ssyrk( 'LOWER', 'NO TRANSPOSE', jb, j-1, -one,a( j, 1_${ik}$ ), lda, one,&
                               a( j, j ), lda )
                    call stdlib${ii}$_spotrf2( 'LOWER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block column.
                       call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'TRANSPOSE', n-j-jb+1, jb,j-1, -one, a( &
                                 j+jb, 1_${ik}$ ), lda, a( j, 1_${ik}$ ),lda, one, a( j+jb, j ), lda )
                       call stdlib${ii}$_strsm( 'RIGHT', 'LOWER', 'TRANSPOSE', 'NON-UNIT',n-j-jb+1, jb, &
                                 one, a( j, j ), lda,a( j+jb, j ), lda )
                    end if
                 end do
              end if
           end if
           go to 40
           30 continue
           info = info + j - 1_${ik}$
           40 continue
           return
     end subroutine stdlib${ii}$_spotrf

     pure module subroutine stdlib${ii}$_dpotrf( uplo, n, a, lda, info )
     !! DPOTRF computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jb, nb
           ! 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( 'DPOTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment.
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code.
              call stdlib${ii}$_dpotrf2( uplo, n, a, lda, info )
           else
              ! use blocked code.
              if( upper ) then
                 ! compute the cholesky factorization a = u**t*u.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_dsyrk( 'UPPER', 'TRANSPOSE', jb, j-1, -one,a( 1_${ik}$, j ), lda, one, a(&
                               j, j ), lda )
                    call stdlib${ii}$_dpotrf2( 'UPPER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block row.
                       call stdlib${ii}$_dgemm( 'TRANSPOSE', 'NO TRANSPOSE', jb, n-j-jb+1,j-1, -one, a( &
                                 1_${ik}$, j ), lda, a( 1_${ik}$, j+jb ),lda, one, a( j, j+jb ), lda )
                       call stdlib${ii}$_dtrsm( 'LEFT', 'UPPER', 'TRANSPOSE', 'NON-UNIT',jb, n-j-jb+1, &
                                 one, a( j, j ), lda,a( j, j+jb ), lda )
                    end if
                 end do
              else
                 ! compute the cholesky factorization a = l*l**t.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_dsyrk( 'LOWER', 'NO TRANSPOSE', jb, j-1, -one,a( j, 1_${ik}$ ), lda, one,&
                               a( j, j ), lda )
                    call stdlib${ii}$_dpotrf2( 'LOWER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block column.
                       call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'TRANSPOSE', n-j-jb+1, jb,j-1, -one, a( &
                                 j+jb, 1_${ik}$ ), lda, a( j, 1_${ik}$ ),lda, one, a( j+jb, j ), lda )
                       call stdlib${ii}$_dtrsm( 'RIGHT', 'LOWER', 'TRANSPOSE', 'NON-UNIT',n-j-jb+1, jb, &
                                 one, a( j, j ), lda,a( j+jb, j ), lda )
                    end if
                 end do
              end if
           end if
           go to 40
           30 continue
           info = info + j - 1_${ik}$
           40 continue
           return
     end subroutine stdlib${ii}$_dpotrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$potrf( uplo, n, a, lda, info )
     !! DPOTRF: computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jb, nb
           ! 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( 'DPOTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment.
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code.
              call stdlib${ii}$_${ri}$potrf2( uplo, n, a, lda, info )
           else
              ! use blocked code.
              if( upper ) then
                 ! compute the cholesky factorization a = u**t*u.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_${ri}$syrk( 'UPPER', 'TRANSPOSE', jb, j-1, -one,a( 1_${ik}$, j ), lda, one, a(&
                               j, j ), lda )
                    call stdlib${ii}$_${ri}$potrf2( 'UPPER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block row.
                       call stdlib${ii}$_${ri}$gemm( 'TRANSPOSE', 'NO TRANSPOSE', jb, n-j-jb+1,j-1, -one, a( &
                                 1_${ik}$, j ), lda, a( 1_${ik}$, j+jb ),lda, one, a( j, j+jb ), lda )
                       call stdlib${ii}$_${ri}$trsm( 'LEFT', 'UPPER', 'TRANSPOSE', 'NON-UNIT',jb, n-j-jb+1, &
                                 one, a( j, j ), lda,a( j, j+jb ), lda )
                    end if
                 end do
              else
                 ! compute the cholesky factorization a = l*l**t.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_${ri}$syrk( 'LOWER', 'NO TRANSPOSE', jb, j-1, -one,a( j, 1_${ik}$ ), lda, one,&
                               a( j, j ), lda )
                    call stdlib${ii}$_${ri}$potrf2( 'LOWER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block column.
                       call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'TRANSPOSE', n-j-jb+1, jb,j-1, -one, a( &
                                 j+jb, 1_${ik}$ ), lda, a( j, 1_${ik}$ ),lda, one, a( j+jb, j ), lda )
                       call stdlib${ii}$_${ri}$trsm( 'RIGHT', 'LOWER', 'TRANSPOSE', 'NON-UNIT',n-j-jb+1, jb, &
                                 one, a( j, j ), lda,a( j+jb, j ), lda )
                    end if
                 end do
              end if
           end if
           go to 40
           30 continue
           info = info + j - 1_${ik}$
           40 continue
           return
     end subroutine stdlib${ii}$_${ri}$potrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpotrf( uplo, n, a, lda, info )
     !! CPOTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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 
           complex(sp), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jb, nb
           ! 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( 'CPOTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment.
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code.
              call stdlib${ii}$_cpotrf2( uplo, n, a, lda, info )
           else
              ! use blocked code.
              if( upper ) then
                 ! compute the cholesky factorization a = u**h *u.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_cherk( 'UPPER', 'CONJUGATE TRANSPOSE', jb, j-1,-one, a( 1_${ik}$, j ), &
                              lda, one, a( j, j ), lda )
                    call stdlib${ii}$_cpotrf2( 'UPPER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block row.
                       call stdlib${ii}$_cgemm( 'CONJUGATE TRANSPOSE', 'NO TRANSPOSE', jb,n-j-jb+1, j-1,&
                                  -cone, a( 1_${ik}$, j ), lda,a( 1_${ik}$, j+jb ), lda, cone, a( j, j+jb ),lda )
                       call stdlib${ii}$_ctrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', jb, &
                                 n-j-jb+1, cone, a( j, j ),lda, a( j, j+jb ), lda )
                    end if
                 end do
              else
                 ! compute the cholesky factorization a = l*l**h.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_cherk( 'LOWER', 'NO TRANSPOSE', jb, j-1, -one,a( j, 1_${ik}$ ), lda, one,&
                               a( j, j ), lda )
                    call stdlib${ii}$_cpotrf2( 'LOWER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block column.
                       call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'CONJUGATE TRANSPOSE',n-j-jb+1, jb, j-1,&
                                  -cone, a( j+jb, 1_${ik}$ ),lda, a( j, 1_${ik}$ ), lda, cone, a( j+jb, j ),lda )
                       call stdlib${ii}$_ctrsm( 'RIGHT', 'LOWER', 'CONJUGATE TRANSPOSE','NON-UNIT', n-j-&
                                 jb+1, jb, cone, a( j, j ),lda, a( j+jb, j ), lda )
                    end if
                 end do
              end if
           end if
           go to 40
           30 continue
           info = info + j - 1_${ik}$
           40 continue
           return
     end subroutine stdlib${ii}$_cpotrf

     pure module subroutine stdlib${ii}$_zpotrf( uplo, n, a, lda, info )
     !! ZPOTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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 
           complex(dp), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jb, nb
           ! 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( 'ZPOTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment.
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code.
              call stdlib${ii}$_zpotrf2( uplo, n, a, lda, info )
           else
              ! use blocked code.
              if( upper ) then
                 ! compute the cholesky factorization a = u**h *u.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_zherk( 'UPPER', 'CONJUGATE TRANSPOSE', jb, j-1,-one, a( 1_${ik}$, j ), &
                              lda, one, a( j, j ), lda )
                    call stdlib${ii}$_zpotrf2( 'UPPER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block row.
                       call stdlib${ii}$_zgemm( 'CONJUGATE TRANSPOSE', 'NO TRANSPOSE', jb,n-j-jb+1, j-1,&
                                  -cone, a( 1_${ik}$, j ), lda,a( 1_${ik}$, j+jb ), lda, cone, a( j, j+jb ),lda )
                       call stdlib${ii}$_ztrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', jb, &
                                 n-j-jb+1, cone, a( j, j ),lda, a( j, j+jb ), lda )
                    end if
                 end do
              else
                 ! compute the cholesky factorization a = l*l**h.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_zherk( 'LOWER', 'NO TRANSPOSE', jb, j-1, -one,a( j, 1_${ik}$ ), lda, one,&
                               a( j, j ), lda )
                    call stdlib${ii}$_zpotrf2( 'LOWER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block column.
                       call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'CONJUGATE TRANSPOSE',n-j-jb+1, jb, j-1,&
                                  -cone, a( j+jb, 1_${ik}$ ),lda, a( j, 1_${ik}$ ), lda, cone, a( j+jb, j ),lda )
                       call stdlib${ii}$_ztrsm( 'RIGHT', 'LOWER', 'CONJUGATE TRANSPOSE','NON-UNIT', n-j-&
                                 jb+1, jb, cone, a( j, j ),lda, a( j+jb, j ), lda )
                    end if
                 end do
              end if
           end if
           go to 40
           30 continue
           info = info + j - 1_${ik}$
           40 continue
           return
     end subroutine stdlib${ii}$_zpotrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$potrf( uplo, n, a, lda, info )
     !! ZPOTRF: computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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 
           complex(${ck}$), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jb, nb
           ! 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( 'ZPOTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment.
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code.
              call stdlib${ii}$_${ci}$potrf2( uplo, n, a, lda, info )
           else
              ! use blocked code.
              if( upper ) then
                 ! compute the cholesky factorization a = u**h *u.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_${ci}$herk( 'UPPER', 'CONJUGATE TRANSPOSE', jb, j-1,-one, a( 1_${ik}$, j ), &
                              lda, one, a( j, j ), lda )
                    call stdlib${ii}$_${ci}$potrf2( 'UPPER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block row.
                       call stdlib${ii}$_${ci}$gemm( 'CONJUGATE TRANSPOSE', 'NO TRANSPOSE', jb,n-j-jb+1, j-1,&
                                  -cone, a( 1_${ik}$, j ), lda,a( 1_${ik}$, j+jb ), lda, cone, a( j, j+jb ),lda )
                       call stdlib${ii}$_${ci}$trsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', jb, &
                                 n-j-jb+1, cone, a( j, j ),lda, a( j, j+jb ), lda )
                    end if
                 end do
              else
                 ! compute the cholesky factorization a = l*l**h.
                 do j = 1, n, nb
                    ! update and factorize the current diagonal block and test
                    ! for non-positive-definiteness.
                    jb = min( nb, n-j+1 )
                    call stdlib${ii}$_${ci}$herk( 'LOWER', 'NO TRANSPOSE', jb, j-1, -one,a( j, 1_${ik}$ ), lda, one,&
                               a( j, j ), lda )
                    call stdlib${ii}$_${ci}$potrf2( 'LOWER', jb, a( j, j ), lda, info )
                    if( info/=0 )go to 30
                    if( j+jb<=n ) then
                       ! compute the current block column.
                       call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'CONJUGATE TRANSPOSE',n-j-jb+1, jb, j-1,&
                                  -cone, a( j+jb, 1_${ik}$ ),lda, a( j, 1_${ik}$ ), lda, cone, a( j+jb, j ),lda )
                       call stdlib${ii}$_${ci}$trsm( 'RIGHT', 'LOWER', 'CONJUGATE TRANSPOSE','NON-UNIT', n-j-&
                                 jb+1, jb, cone, a( j, j ),lda, a( j+jb, j ), lda )
                    end if
                 end do
              end if
           end if
           go to 40
           30 continue
           info = info + j - 1_${ik}$
           40 continue
           return
     end subroutine stdlib${ii}$_${ci}$potrf

#:endif
#:endfor



     pure recursive module subroutine stdlib${ii}$_spotrf2( uplo, n, a, lda, info )
     !! SPOTRF2 computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A using the recursive algorithm.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the recursive version of the algorithm. It divides
     !! the matrix into four submatrices:
     !! [  A11 | A12  ]  where A11 is n1 by n1 and A22 is n2 by n2
     !! A = [ -----|----- ]  with n1 = n/2
     !! [  A21 | A22  ]       n2 = n-n1
     !! The subroutine calls itself to factor A11. Update and scale A21
     !! or A12, update A22 then call itself to factor A22.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: n1, n2, iinfo
           ! 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( 'SPOTRF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! n=1 case
           if( n==1_${ik}$ ) then
              ! test for non-positive-definiteness
              if( a( 1_${ik}$, 1_${ik}$ )<=zero.or.stdlib${ii}$_sisnan( a( 1_${ik}$, 1_${ik}$ ) ) ) then
                 info = 1_${ik}$
                 return
              end if
              ! factor
              a( 1_${ik}$, 1_${ik}$ ) = sqrt( a( 1_${ik}$, 1_${ik}$ ) )
           ! use recursive code
           else
              n1 = n/2_${ik}$
              n2 = n-n1
              ! factor a11
              call stdlib${ii}$_spotrf2( uplo, n1, a( 1_${ik}$, 1_${ik}$ ), lda, iinfo )
              if ( iinfo/=0_${ik}$ ) then
                 info = iinfo
                 return
              end if
              ! compute the cholesky factorization a = u**t*u
              if( upper ) then
                 ! update and scale a12
                 call stdlib${ii}$_strsm( 'L', 'U', 'T', 'N', n1, n2, one,a( 1_${ik}$, 1_${ik}$ ), lda, a( 1_${ik}$, n1+1 ), &
                           lda )
                 ! update and factor a22
                 call stdlib${ii}$_ssyrk( uplo, 'T', n2, n1, -one, a( 1_${ik}$, n1+1 ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_spotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              ! compute the cholesky factorization a = l*l**t
              else
                 ! update and scale a21
                 call stdlib${ii}$_strsm( 'R', 'L', 'T', 'N', n2, n1, one,a( 1_${ik}$, 1_${ik}$ ), lda, a( n1+1, 1_${ik}$ ), &
                           lda )
                 ! update and factor a22
                 call stdlib${ii}$_ssyrk( uplo, 'N', n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_spotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_spotrf2

     pure recursive module subroutine stdlib${ii}$_dpotrf2( uplo, n, a, lda, info )
     !! DPOTRF2 computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A using the recursive algorithm.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the recursive version of the algorithm. It divides
     !! the matrix into four submatrices:
     !! [  A11 | A12  ]  where A11 is n1 by n1 and A22 is n2 by n2
     !! A = [ -----|----- ]  with n1 = n/2
     !! [  A21 | A22  ]       n2 = n-n1
     !! The subroutine calls itself to factor A11. Update and scale A21
     !! or A12, update A22 then calls itself to factor A22.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: n1, n2, iinfo
           ! 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( 'DPOTRF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! n=1 case
           if( n==1_${ik}$ ) then
              ! test for non-positive-definiteness
              if( a( 1_${ik}$, 1_${ik}$ )<=zero.or.stdlib${ii}$_disnan( a( 1_${ik}$, 1_${ik}$ ) ) ) then
                 info = 1_${ik}$
                 return
              end if
              ! factor
              a( 1_${ik}$, 1_${ik}$ ) = sqrt( a( 1_${ik}$, 1_${ik}$ ) )
           ! use recursive code
           else
              n1 = n/2_${ik}$
              n2 = n-n1
              ! factor a11
              call stdlib${ii}$_dpotrf2( uplo, n1, a( 1_${ik}$, 1_${ik}$ ), lda, iinfo )
              if ( iinfo/=0_${ik}$ ) then
                 info = iinfo
                 return
              end if
              ! compute the cholesky factorization a = u**t*u
              if( upper ) then
                 ! update and scale a12
                 call stdlib${ii}$_dtrsm( 'L', 'U', 'T', 'N', n1, n2, one,a( 1_${ik}$, 1_${ik}$ ), lda, a( 1_${ik}$, n1+1 ), &
                           lda )
                 ! update and factor a22
                 call stdlib${ii}$_dsyrk( uplo, 'T', n2, n1, -one, a( 1_${ik}$, n1+1 ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_dpotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              ! compute the cholesky factorization a = l*l**t
              else
                 ! update and scale a21
                 call stdlib${ii}$_dtrsm( 'R', 'L', 'T', 'N', n2, n1, one,a( 1_${ik}$, 1_${ik}$ ), lda, a( n1+1, 1_${ik}$ ), &
                           lda )
                 ! update and factor a22
                 call stdlib${ii}$_dsyrk( uplo, 'N', n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_dpotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_dpotrf2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure recursive module subroutine stdlib${ii}$_${ri}$potrf2( uplo, n, a, lda, info )
     !! DPOTRF2: computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A using the recursive algorithm.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the recursive version of the algorithm. It divides
     !! the matrix into four submatrices:
     !! [  A11 | A12  ]  where A11 is n1 by n1 and A22 is n2 by n2
     !! A = [ -----|----- ]  with n1 = n/2
     !! [  A21 | A22  ]       n2 = n-n1
     !! The subroutine calls itself to factor A11. Update and scale A21
     !! or A12, update A22 then calls itself to factor A22.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: n1, n2, iinfo
           ! 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( 'DPOTRF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! n=1 case
           if( n==1_${ik}$ ) then
              ! test for non-positive-definiteness
              if( a( 1_${ik}$, 1_${ik}$ )<=zero.or.stdlib${ii}$_${ri}$isnan( a( 1_${ik}$, 1_${ik}$ ) ) ) then
                 info = 1_${ik}$
                 return
              end if
              ! factor
              a( 1_${ik}$, 1_${ik}$ ) = sqrt( a( 1_${ik}$, 1_${ik}$ ) )
           ! use recursive code
           else
              n1 = n/2_${ik}$
              n2 = n-n1
              ! factor a11
              call stdlib${ii}$_${ri}$potrf2( uplo, n1, a( 1_${ik}$, 1_${ik}$ ), lda, iinfo )
              if ( iinfo/=0_${ik}$ ) then
                 info = iinfo
                 return
              end if
              ! compute the cholesky factorization a = u**t*u
              if( upper ) then
                 ! update and scale a12
                 call stdlib${ii}$_${ri}$trsm( 'L', 'U', 'T', 'N', n1, n2, one,a( 1_${ik}$, 1_${ik}$ ), lda, a( 1_${ik}$, n1+1 ), &
                           lda )
                 ! update and factor a22
                 call stdlib${ii}$_${ri}$syrk( uplo, 'T', n2, n1, -one, a( 1_${ik}$, n1+1 ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_${ri}$potrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              ! compute the cholesky factorization a = l*l**t
              else
                 ! update and scale a21
                 call stdlib${ii}$_${ri}$trsm( 'R', 'L', 'T', 'N', n2, n1, one,a( 1_${ik}$, 1_${ik}$ ), lda, a( n1+1, 1_${ik}$ ), &
                           lda )
                 ! update and factor a22
                 call stdlib${ii}$_${ri}$syrk( uplo, 'N', n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_${ri}$potrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ri}$potrf2

#:endif
#:endfor

     pure recursive module subroutine stdlib${ii}$_cpotrf2( uplo, n, a, lda, info )
     !! CPOTRF2 computes the Cholesky factorization of a Hermitian
     !! positive definite matrix A using the recursive algorithm.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the recursive version of the algorithm. It divides
     !! the matrix into four submatrices:
     !! [  A11 | A12  ]  where A11 is n1 by n1 and A22 is n2 by n2
     !! A = [ -----|----- ]  with n1 = n/2
     !! [  A21 | A22  ]       n2 = n-n1
     !! The subroutine calls itself to factor A11. Update and scale A21
     !! or A12, update A22 then calls itself to factor A22.
        ! -- 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 
           complex(sp), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: n1, n2, iinfo
           real(sp) :: ajj
           ! 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( 'CPOTRF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! n=1 case
           if( n==1_${ik}$ ) then
              ! test for non-positive-definiteness
              ajj = real( a( 1_${ik}$, 1_${ik}$ ),KIND=sp)
              if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                 info = 1_${ik}$
                 return
              end if
              ! factor
              a( 1_${ik}$, 1_${ik}$ ) = sqrt( ajj )
           ! use recursive code
           else
              n1 = n/2_${ik}$
              n2 = n-n1
              ! factor a11
              call stdlib${ii}$_cpotrf2( uplo, n1, a( 1_${ik}$, 1_${ik}$ ), lda, iinfo )
              if ( iinfo/=0_${ik}$ ) then
                 info = iinfo
                 return
              end if
              ! compute the cholesky factorization a = u**h*u
              if( upper ) then
                 ! update and scale a12
                 call stdlib${ii}$_ctrsm( 'L', 'U', 'C', 'N', n1, n2, cone,a( 1_${ik}$, 1_${ik}$ ), lda, a( 1_${ik}$, n1+1 ),&
                            lda )
                 ! update and factor a22
                 call stdlib${ii}$_cherk( uplo, 'C', n2, n1, -one, a( 1_${ik}$, n1+1 ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_cpotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              ! compute the cholesky factorization a = l*l**h
              else
                 ! update and scale a21
                 call stdlib${ii}$_ctrsm( 'R', 'L', 'C', 'N', n2, n1, cone,a( 1_${ik}$, 1_${ik}$ ), lda, a( n1+1, 1_${ik}$ ),&
                            lda )
                 ! update and factor a22
                 call stdlib${ii}$_cherk( uplo, 'N', n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_cpotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_cpotrf2

     pure recursive module subroutine stdlib${ii}$_zpotrf2( uplo, n, a, lda, info )
     !! ZPOTRF2 computes the Cholesky factorization of a Hermitian
     !! positive definite matrix A using the recursive algorithm.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the recursive version of the algorithm. It divides
     !! the matrix into four submatrices:
     !! [  A11 | A12  ]  where A11 is n1 by n1 and A22 is n2 by n2
     !! A = [ -----|----- ]  with n1 = n/2
     !! [  A21 | A22  ]       n2 = n-n1
     !! The subroutine calls itself to factor A11. Update and scale A21
     !! or A12, update A22 then call itself to factor A22.
        ! -- 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 
           complex(dp), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: n1, n2, iinfo
           real(dp) :: ajj
           ! 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( 'ZPOTRF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! n=1 case
           if( n==1_${ik}$ ) then
              ! test for non-positive-definiteness
              ajj = real( a( 1_${ik}$, 1_${ik}$ ),KIND=dp)
              if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                 info = 1_${ik}$
                 return
              end if
              ! factor
              a( 1_${ik}$, 1_${ik}$ ) = sqrt( ajj )
           ! use recursive code
           else
              n1 = n/2_${ik}$
              n2 = n-n1
              ! factor a11
              call stdlib${ii}$_zpotrf2( uplo, n1, a( 1_${ik}$, 1_${ik}$ ), lda, iinfo )
              if ( iinfo/=0_${ik}$ ) then
                 info = iinfo
                 return
              end if
              ! compute the cholesky factorization a = u**h*u
              if( upper ) then
                 ! update and scale a12
                 call stdlib${ii}$_ztrsm( 'L', 'U', 'C', 'N', n1, n2, cone,a( 1_${ik}$, 1_${ik}$ ), lda, a( 1_${ik}$, n1+1 ),&
                            lda )
                 ! update and factor a22
                 call stdlib${ii}$_zherk( uplo, 'C', n2, n1, -one, a( 1_${ik}$, n1+1 ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_zpotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              ! compute the cholesky factorization a = l*l**h
              else
                 ! update and scale a21
                 call stdlib${ii}$_ztrsm( 'R', 'L', 'C', 'N', n2, n1, cone,a( 1_${ik}$, 1_${ik}$ ), lda, a( n1+1, 1_${ik}$ ),&
                            lda )
                 ! update and factor a22
                 call stdlib${ii}$_zherk( uplo, 'N', n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_zpotrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_zpotrf2

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure recursive module subroutine stdlib${ii}$_${ci}$potrf2( uplo, n, a, lda, info )
     !! ZPOTRF2: computes the Cholesky factorization of a Hermitian
     !! positive definite matrix A using the recursive algorithm.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the recursive version of the algorithm. It divides
     !! the matrix into four submatrices:
     !! [  A11 | A12  ]  where A11 is n1 by n1 and A22 is n2 by n2
     !! A = [ -----|----- ]  with n1 = n/2
     !! [  A21 | A22  ]       n2 = n-n1
     !! The subroutine calls itself to factor A11. Update and scale A21
     !! or A12, update A22 then call itself to factor A22.
        ! -- 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 
           complex(${ck}$), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: n1, n2, iinfo
           real(${ck}$) :: ajj
           ! 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( 'ZPOTRF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! n=1 case
           if( n==1_${ik}$ ) then
              ! test for non-positive-definiteness
              ajj = real( a( 1_${ik}$, 1_${ik}$ ),KIND=${ck}$)
              if( ajj<=zero.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                 info = 1_${ik}$
                 return
              end if
              ! factor
              a( 1_${ik}$, 1_${ik}$ ) = sqrt( ajj )
           ! use recursive code
           else
              n1 = n/2_${ik}$
              n2 = n-n1
              ! factor a11
              call stdlib${ii}$_${ci}$potrf2( uplo, n1, a( 1_${ik}$, 1_${ik}$ ), lda, iinfo )
              if ( iinfo/=0_${ik}$ ) then
                 info = iinfo
                 return
              end if
              ! compute the cholesky factorization a = u**h*u
              if( upper ) then
                 ! update and scale a12
                 call stdlib${ii}$_${ci}$trsm( 'L', 'U', 'C', 'N', n1, n2, cone,a( 1_${ik}$, 1_${ik}$ ), lda, a( 1_${ik}$, n1+1 ),&
                            lda )
                 ! update and factor a22
                 call stdlib${ii}$_${ci}$herk( uplo, 'C', n2, n1, -one, a( 1_${ik}$, n1+1 ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_${ci}$potrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              ! compute the cholesky factorization a = l*l**h
              else
                 ! update and scale a21
                 call stdlib${ii}$_${ci}$trsm( 'R', 'L', 'C', 'N', n2, n1, cone,a( 1_${ik}$, 1_${ik}$ ), lda, a( n1+1, 1_${ik}$ ),&
                            lda )
                 ! update and factor a22
                 call stdlib${ii}$_${ci}$herk( uplo, 'N', n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,one, a( n1+1, n1+1 &
                           ), lda )
                 call stdlib${ii}$_${ci}$potrf2( uplo, n2, a( n1+1, n1+1 ), lda, iinfo )
                 if ( iinfo/=0_${ik}$ ) then
                    info = iinfo + n1
                    return
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ci}$potrf2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spotf2( uplo, n, a, lda, info )
     !! SPOTF2 computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U ,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           real(sp) :: ajj
           ! 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( 'SPOTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**t *u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = a( j, j ) - stdlib${ii}$_sdot( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, j ), 1_${ik}$ )
                 if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j.
                 if( j<n ) then
                    call stdlib${ii}$_sgemv( 'TRANSPOSE', j-1, n-j, -one, a( 1_${ik}$, j+1 ),lda, a( 1_${ik}$, j ), 1_${ik}$,&
                               one, a( j, j+1 ), lda )
                    call stdlib${ii}$_sscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = a( j, j ) - stdlib${ii}$_sdot( j-1, a( j, 1_${ik}$ ), lda, a( j, 1_${ik}$ ),lda )
                 if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j.
                 if( j<n ) then
                    call stdlib${ii}$_sgemv( 'NO TRANSPOSE', n-j, j-1, -one, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ ),&
                               lda, one, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_sscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_spotf2

     pure module subroutine stdlib${ii}$_dpotf2( uplo, n, a, lda, info )
     !! DPOTF2 computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U ,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           real(dp) :: ajj
           ! 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( 'DPOTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**t *u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = a( j, j ) - stdlib${ii}$_ddot( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, j ), 1_${ik}$ )
                 if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j.
                 if( j<n ) then
                    call stdlib${ii}$_dgemv( 'TRANSPOSE', j-1, n-j, -one, a( 1_${ik}$, j+1 ),lda, a( 1_${ik}$, j ), 1_${ik}$,&
                               one, a( j, j+1 ), lda )
                    call stdlib${ii}$_dscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = a( j, j ) - stdlib${ii}$_ddot( j-1, a( j, 1_${ik}$ ), lda, a( j, 1_${ik}$ ),lda )
                 if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j.
                 if( j<n ) then
                    call stdlib${ii}$_dgemv( 'NO TRANSPOSE', n-j, j-1, -one, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ ),&
                               lda, one, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_dscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_dpotf2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$potf2( uplo, n, a, lda, info )
     !! DPOTF2: computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U ,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           real(${rk}$) :: ajj
           ! 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( 'DPOTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**t *u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = a( j, j ) - stdlib${ii}$_${ri}$dot( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, j ), 1_${ik}$ )
                 if( ajj<=zero.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j.
                 if( j<n ) then
                    call stdlib${ii}$_${ri}$gemv( 'TRANSPOSE', j-1, n-j, -one, a( 1_${ik}$, j+1 ),lda, a( 1_${ik}$, j ), 1_${ik}$,&
                               one, a( j, j+1 ), lda )
                    call stdlib${ii}$_${ri}$scal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = a( j, j ) - stdlib${ii}$_${ri}$dot( j-1, a( j, 1_${ik}$ ), lda, a( j, 1_${ik}$ ),lda )
                 if( ajj<=zero.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j.
                 if( j<n ) then
                    call stdlib${ii}$_${ri}$gemv( 'NO TRANSPOSE', n-j, j-1, -one, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ ),&
                               lda, one, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ri}$scal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_${ri}$potf2

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpotf2( uplo, n, a, lda, info )
     !! CPOTF2 computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U ,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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 
           complex(sp), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           real(sp) :: ajj
           ! 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( 'CPOTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**h *u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( real( a( j, j ),KIND=sp) - stdlib${ii}$_cdotc( j-1, a( 1_${ik}$, j ), 1_${ik}$,a( 1_${ik}$, j ),&
                            1_${ik}$ ),KIND=sp)
                 if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j.
                 if( j<n ) then
                    call stdlib${ii}$_clacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_cgemv( 'TRANSPOSE', j-1, n-j, -cone, a( 1_${ik}$, j+1 ),lda, a( 1_${ik}$, j ), &
                              1_${ik}$, cone, a( j, j+1 ), lda )
                    call stdlib${ii}$_clacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_csscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**h.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( real( a( j, j ),KIND=sp) - stdlib${ii}$_cdotc( j-1, a( j, 1_${ik}$ ), lda,a( j, 1_${ik}$ &
                           ), lda ),KIND=sp)
                 if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j.
                 if( j<n ) then
                    call stdlib${ii}$_clacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_cgemv( 'NO TRANSPOSE', n-j, j-1, -cone, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ )&
                              , lda, cone, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_clacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_csscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_cpotf2

     pure module subroutine stdlib${ii}$_zpotf2( uplo, n, a, lda, info )
     !! ZPOTF2 computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U ,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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 
           complex(dp), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           real(dp) :: ajj
           ! 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( 'ZPOTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**h *u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( a( j, j ),KIND=dp) - real( stdlib${ii}$_zdotc( j-1, a( 1_${ik}$, j ), 1_${ik}$,a( 1_${ik}$, j ),&
                            1_${ik}$ ),KIND=dp)
                 if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j.
                 if( j<n ) then
                    call stdlib${ii}$_zlacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_zgemv( 'TRANSPOSE', j-1, n-j, -cone, a( 1_${ik}$, j+1 ),lda, a( 1_${ik}$, j ), &
                              1_${ik}$, cone, a( j, j+1 ), lda )
                    call stdlib${ii}$_zlacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_zdscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**h.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( a( j, j ),KIND=dp) - real( stdlib${ii}$_zdotc( j-1, a( j, 1_${ik}$ ), lda,a( j, 1_${ik}$ &
                           ), lda ),KIND=dp)
                 if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j.
                 if( j<n ) then
                    call stdlib${ii}$_zlacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_zgemv( 'NO TRANSPOSE', n-j, j-1, -cone, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ )&
                              , lda, cone, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_zlacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_zdscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_zpotf2

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$potf2( uplo, n, a, lda, info )
     !! ZPOTF2: computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U ,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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 
           complex(${ck}$), intent(inout) :: a(lda,*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           real(${ck}$) :: ajj
           ! 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( 'ZPOTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**h *u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( a( j, j ),KIND=${ck}$) - real( stdlib${ii}$_${ci}$dotc( j-1, a( 1_${ik}$, j ), 1_${ik}$,a( 1_${ik}$, j ),&
                            1_${ik}$ ),KIND=${ck}$)
                 if( ajj<=zero.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j.
                 if( j<n ) then
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$gemv( 'TRANSPOSE', j-1, n-j, -cone, a( 1_${ik}$, j+1 ),lda, a( 1_${ik}$, j ), &
                              1_${ik}$, cone, a( j, j+1 ), lda )
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**h.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( a( j, j ),KIND=${ck}$) - real( stdlib${ii}$_${ci}$dotc( j-1, a( j, 1_${ik}$ ), lda,a( j, 1_${ik}$ &
                           ), lda ),KIND=${ck}$)
                 if( ajj<=zero.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                    a( j, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j.
                 if( j<n ) then
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_${ci}$gemv( 'NO TRANSPOSE', n-j, j-1, -cone, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ )&
                              , lda, cone, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_${ci}$potf2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spstrf( uplo, n, a, lda, piv, rank, tol, work, info )
     !! SPSTRF computes the Cholesky factorization with complete
     !! pivoting of a real symmetric positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**T * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 3 BLAS.
        ! -- 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 
           real(sp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           real(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           ! Local Scalars 
           real(sp) :: ajj, sstop, stemp
           integer(${ik}$) :: i, itemp, j, jb, k, nb, pvt
           logical(lk) :: upper
           ! 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( 'SPSTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! get block size
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code
              call stdlib${ii}$_spstf2( uplo, n, a( 1_${ik}$, 1_${ik}$ ), lda, piv, rank, tol, work,info )
              go to 200
           else
           ! initialize piv
              do i = 1, n
                 piv( i ) = i
              end do
           ! compute stopping value
              pvt = 1_${ik}$
              ajj = a( pvt, pvt )
              do i = 2, n
                 if( a( i, i )>ajj ) then
                    pvt = i
                    ajj = a( pvt, pvt )
                 end if
              end do
              if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                 rank = 0_${ik}$
                 info = 1_${ik}$
                 go to 200
              end if
           ! compute stopping value if not supplied
              if( tol<zero ) then
                 sstop = n * stdlib${ii}$_slamch( 'EPSILON' ) * ajj
              else
                 sstop = tol
              end if
              if( upper ) then
                 ! compute the cholesky factorization p**t * a * p = u**t * u
                 loop_140: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first half of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_130: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second half of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) + a( j-1, i )**2_${ik}$
                          end if
                          work( n+i ) = a( i, i ) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 190
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_sswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                          if( pvt<n )call stdlib${ii}$_sswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ),&
                                     lda )
                          call stdlib${ii}$_sswap( pvt-j-1, a( j, j+1 ), lda,a( j+1, pvt ), 1_${ik}$ )
                          ! swap dot products and piv
                          stemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = stemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of row j.
                       if( j<n ) then
                          call stdlib${ii}$_sgemv( 'TRANS', j-k, n-j, -one, a( k, j+1 ),lda, a( k, j ), &
                                    1_${ik}$, one, a( j, j+1 ),lda )
                          call stdlib${ii}$_sscal( n-j, one / ajj, a( j, j+1 ), lda )
                       end if
                    end do loop_130
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_ssyrk( 'UPPER', 'TRANS', n-j+1, jb, -one,a( k, j ), lda, one, &
                                 a( j, j ), lda )
                    end if
                 end do loop_140
              else
              ! compute the cholesky factorization p**t * a * p = l * l**t
                 loop_180: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first half of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_170: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second half of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) + a( i, j-1 )**2_${ik}$
                          end if
                          work( n+i ) = a( i, i ) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 190
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_sswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                          if( pvt<n )call stdlib${ii}$_sswap( n-pvt, a( pvt+1, j ), 1_${ik}$,a( pvt+1, pvt ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_sswap( pvt-j-1, a( j+1, j ), 1_${ik}$, a( pvt, j+1 ),lda )
                          ! swap dot products and piv
                          stemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = stemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of column j.
                       if( j<n ) then
                          call stdlib${ii}$_sgemv( 'NO TRANS', n-j, j-k, -one,a( j+1, k ), lda, a( j, k &
                                    ), lda, one,a( j+1, j ), 1_${ik}$ )
                          call stdlib${ii}$_sscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                       end if
                    end do loop_170
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_ssyrk( 'LOWER', 'NO TRANS', n-j+1, jb, -one,a( j, k ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_180
              end if
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 200
           190 continue
           ! rank is the number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           200 continue
           return
     end subroutine stdlib${ii}$_spstrf

     pure module subroutine stdlib${ii}$_dpstrf( uplo, n, a, lda, piv, rank, tol, work, info )
     !! DPSTRF computes the Cholesky factorization with complete
     !! pivoting of a real symmetric positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**T * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 3 BLAS.
        ! -- 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 
           real(dp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           real(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           ! Local Scalars 
           real(dp) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, jb, k, nb, pvt
           logical(lk) :: upper
           ! 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( 'DPSTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! get block size
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code
              call stdlib${ii}$_dpstf2( uplo, n, a( 1_${ik}$, 1_${ik}$ ), lda, piv, rank, tol, work,info )
              go to 200
           else
           ! initialize piv
              do i = 1, n
                 piv( i ) = i
              end do
           ! compute stopping value
              pvt = 1_${ik}$
              ajj = a( pvt, pvt )
              do i = 2, n
                 if( a( i, i )>ajj ) then
                    pvt = i
                    ajj = a( pvt, pvt )
                 end if
              end do
              if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                 rank = 0_${ik}$
                 info = 1_${ik}$
                 go to 200
              end if
           ! compute stopping value if not supplied
              if( tol<zero ) then
                 dstop = n * stdlib${ii}$_dlamch( 'EPSILON' ) * ajj
              else
                 dstop = tol
              end if
              if( upper ) then
                 ! compute the cholesky factorization p**t * a * p = u**t * u
                 loop_140: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first half of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_130: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second half of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) + a( j-1, i )**2_${ik}$
                          end if
                          work( n+i ) = a( i, i ) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 190
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_dswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                          if( pvt<n )call stdlib${ii}$_dswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ),&
                                     lda )
                          call stdlib${ii}$_dswap( pvt-j-1, a( j, j+1 ), lda,a( j+1, pvt ), 1_${ik}$ )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of row j.
                       if( j<n ) then
                          call stdlib${ii}$_dgemv( 'TRANS', j-k, n-j, -one, a( k, j+1 ),lda, a( k, j ), &
                                    1_${ik}$, one, a( j, j+1 ),lda )
                          call stdlib${ii}$_dscal( n-j, one / ajj, a( j, j+1 ), lda )
                       end if
                    end do loop_130
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_dsyrk( 'UPPER', 'TRANS', n-j+1, jb, -one,a( k, j ), lda, one, &
                                 a( j, j ), lda )
                    end if
                 end do loop_140
              else
              ! compute the cholesky factorization p**t * a * p = l * l**t
                 loop_180: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first half of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_170: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second half of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) + a( i, j-1 )**2_${ik}$
                          end if
                          work( n+i ) = a( i, i ) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 190
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_dswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                          if( pvt<n )call stdlib${ii}$_dswap( n-pvt, a( pvt+1, j ), 1_${ik}$,a( pvt+1, pvt ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_dswap( pvt-j-1, a( j+1, j ), 1_${ik}$, a( pvt, j+1 ),lda )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of column j.
                       if( j<n ) then
                          call stdlib${ii}$_dgemv( 'NO TRANS', n-j, j-k, -one,a( j+1, k ), lda, a( j, k &
                                    ), lda, one,a( j+1, j ), 1_${ik}$ )
                          call stdlib${ii}$_dscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                       end if
                    end do loop_170
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_dsyrk( 'LOWER', 'NO TRANS', n-j+1, jb, -one,a( j, k ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_180
              end if
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 200
           190 continue
           ! rank is the number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           200 continue
           return
     end subroutine stdlib${ii}$_dpstrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pstrf( uplo, n, a, lda, piv, rank, tol, work, info )
     !! DPSTRF: computes the Cholesky factorization with complete
     !! pivoting of a real symmetric positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**T * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 3 BLAS.
        ! -- 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 
           real(${rk}$), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(lda,*)
           real(${rk}$), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           ! Local Scalars 
           real(${rk}$) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, jb, k, nb, pvt
           logical(lk) :: upper
           ! 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( 'DPSTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! get block size
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code
              call stdlib${ii}$_${ri}$pstf2( uplo, n, a( 1_${ik}$, 1_${ik}$ ), lda, piv, rank, tol, work,info )
              go to 200
           else
           ! initialize piv
              do i = 1, n
                 piv( i ) = i
              end do
           ! compute stopping value
              pvt = 1_${ik}$
              ajj = a( pvt, pvt )
              do i = 2, n
                 if( a( i, i )>ajj ) then
                    pvt = i
                    ajj = a( pvt, pvt )
                 end if
              end do
              if( ajj<=zero.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                 rank = 0_${ik}$
                 info = 1_${ik}$
                 go to 200
              end if
           ! compute stopping value if not supplied
              if( tol<zero ) then
                 dstop = n * stdlib${ii}$_${ri}$lamch( 'EPSILON' ) * ajj
              else
                 dstop = tol
              end if
              if( upper ) then
                 ! compute the cholesky factorization p**t * a * p = u**t * u
                 loop_140: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first half of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_130: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second half of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) + a( j-1, i )**2_${ik}$
                          end if
                          work( n+i ) = a( i, i ) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 190
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_${ri}$swap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                          if( pvt<n )call stdlib${ii}$_${ri}$swap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ),&
                                     lda )
                          call stdlib${ii}$_${ri}$swap( pvt-j-1, a( j, j+1 ), lda,a( j+1, pvt ), 1_${ik}$ )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of row j.
                       if( j<n ) then
                          call stdlib${ii}$_${ri}$gemv( 'TRANS', j-k, n-j, -one, a( k, j+1 ),lda, a( k, j ), &
                                    1_${ik}$, one, a( j, j+1 ),lda )
                          call stdlib${ii}$_${ri}$scal( n-j, one / ajj, a( j, j+1 ), lda )
                       end if
                    end do loop_130
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_${ri}$syrk( 'UPPER', 'TRANS', n-j+1, jb, -one,a( k, j ), lda, one, &
                                 a( j, j ), lda )
                    end if
                 end do loop_140
              else
              ! compute the cholesky factorization p**t * a * p = l * l**t
                 loop_180: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first half of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_170: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second half of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) + a( i, j-1 )**2_${ik}$
                          end if
                          work( n+i ) = a( i, i ) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 190
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_${ri}$swap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                          if( pvt<n )call stdlib${ii}$_${ri}$swap( n-pvt, a( pvt+1, j ), 1_${ik}$,a( pvt+1, pvt ), &
                                    1_${ik}$ )
                          call stdlib${ii}$_${ri}$swap( pvt-j-1, a( j+1, j ), 1_${ik}$, a( pvt, j+1 ),lda )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of column j.
                       if( j<n ) then
                          call stdlib${ii}$_${ri}$gemv( 'NO TRANS', n-j, j-k, -one,a( j+1, k ), lda, a( j, k &
                                    ), lda, one,a( j+1, j ), 1_${ik}$ )
                          call stdlib${ii}$_${ri}$scal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                       end if
                    end do loop_170
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_${ri}$syrk( 'LOWER', 'NO TRANS', n-j+1, jb, -one,a( j, k ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_180
              end if
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 200
           190 continue
           ! rank is the number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           200 continue
           return
     end subroutine stdlib${ii}$_${ri}$pstrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpstrf( uplo, n, a, lda, piv, rank, tol, work, info )
     !! CPSTRF computes the Cholesky factorization with complete
     !! pivoting of a complex Hermitian positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**H * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 3 BLAS.
        ! -- 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 
           real(sp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           
           ! Local Scalars 
           complex(sp) :: ctemp
           real(sp) :: ajj, sstop, stemp
           integer(${ik}$) :: i, itemp, j, jb, k, nb, pvt
           logical(lk) :: upper
           ! 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( 'CPSTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! get block size
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code
              call stdlib${ii}$_cpstf2( uplo, n, a( 1_${ik}$, 1_${ik}$ ), lda, piv, rank, tol, work,info )
              go to 230
           else
           ! initialize piv
              do i = 1, n
                 piv( i ) = i
              end do
           ! compute stopping value
              do i = 1, n
                 work( i ) = real( a( i, i ),KIND=sp)
              end do
              pvt = maxloc( work( 1_${ik}$:n ), 1_${ik}$ )
              ajj = real( a( pvt, pvt ),KIND=sp)
              if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
                 rank = 0_${ik}$
                 info = 1_${ik}$
                 go to 230
              end if
           ! compute stopping value if not supplied
              if( tol<zero ) then
                 sstop = n * stdlib${ii}$_slamch( 'EPSILON' ) * ajj
              else
                 sstop = tol
              end if
              if( upper ) then
                 ! compute the cholesky factorization p**t * a * p = u**h * u
                 loop_160: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first chalf of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_150: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second chalf of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) +real( conjg( a( j-1, i ) )*a( j-1, i ),&
                                       KIND=sp)
                          end if
                          work( n+i ) = real( a( i, i ),KIND=sp) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 220
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_cswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                          if( pvt<n )call stdlib${ii}$_cswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ),&
                                     lda )
                          do i = j + 1, pvt - 1
                             ctemp = conjg( a( j, i ) )
                             a( j, i ) = conjg( a( i, pvt ) )
                             a( i, pvt ) = ctemp
                          end do
                          a( j, pvt ) = conjg( a( j, pvt ) )
                          ! swap dot products and piv
                          stemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = stemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of row j.
                       if( j<n ) then
                          call stdlib${ii}$_clacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                          call stdlib${ii}$_cgemv( 'TRANS', j-k, n-j, -cone, a( k, j+1 ),lda, a( k, j ),&
                                     1_${ik}$, cone, a( j, j+1 ),lda )
                          call stdlib${ii}$_clacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                          call stdlib${ii}$_csscal( n-j, one / ajj, a( j, j+1 ), lda )
                       end if
                    end do loop_150
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_cherk( 'UPPER', 'CONJ TRANS', n-j+1, jb, -one,a( k, j ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_160
              else
              ! compute the cholesky factorization p**t * a * p = l * l**h
                 loop_210: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first chalf of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_200: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second chalf of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) +real( conjg( a( i, j-1 ) )*a( i, j-1 ),&
                                       KIND=sp)
                          end if
                          work( n+i ) = real( a( i, i ),KIND=sp) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 220
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_cswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                          if( pvt<n )call stdlib${ii}$_cswap( n-pvt, a( pvt+1, j ), 1_${ik}$,a( pvt+1, pvt ), &
                                    1_${ik}$ )
                          do i = j + 1, pvt - 1
                             ctemp = conjg( a( i, j ) )
                             a( i, j ) = conjg( a( pvt, i ) )
                             a( pvt, i ) = ctemp
                          end do
                          a( pvt, j ) = conjg( a( pvt, j ) )
                          ! swap dot products and piv
                          stemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = stemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of column j.
                       if( j<n ) then
                          call stdlib${ii}$_clacgv( j-1, a( j, 1_${ik}$ ), lda )
                          call stdlib${ii}$_cgemv( 'NO TRANS', n-j, j-k, -cone,a( j+1, k ), lda, a( j, &
                                    k ), lda, cone,a( j+1, j ), 1_${ik}$ )
                          call stdlib${ii}$_clacgv( j-1, a( j, 1_${ik}$ ), lda )
                          call stdlib${ii}$_csscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                       end if
                    end do loop_200
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_cherk( 'LOWER', 'NO TRANS', n-j+1, jb, -one,a( j, k ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_210
              end if
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 230
           220 continue
           ! rank is the number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           230 continue
           return
     end subroutine stdlib${ii}$_cpstrf

     pure module subroutine stdlib${ii}$_zpstrf( uplo, n, a, lda, piv, rank, tol, work, info )
     !! ZPSTRF computes the Cholesky factorization with complete
     !! pivoting of a complex Hermitian positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**H * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 3 BLAS.
        ! -- 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 
           real(dp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           
           ! Local Scalars 
           complex(dp) :: ztemp
           real(dp) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, jb, k, nb, pvt
           logical(lk) :: upper
           ! 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( 'ZPSTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! get block size
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code
              call stdlib${ii}$_zpstf2( uplo, n, a( 1_${ik}$, 1_${ik}$ ), lda, piv, rank, tol, work,info )
              go to 230
           else
           ! initialize piv
              do i = 1, n
                 piv( i ) = i
              end do
           ! compute stopping value
              do i = 1, n
                 work( i ) = real( a( i, i ),KIND=dp)
              end do
              pvt = maxloc( work( 1_${ik}$:n ), 1_${ik}$ )
              ajj = real( a( pvt, pvt ),KIND=dp)
              if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
                 rank = 0_${ik}$
                 info = 1_${ik}$
                 go to 230
              end if
           ! compute stopping value if not supplied
              if( tol<zero ) then
                 dstop = n * stdlib${ii}$_dlamch( 'EPSILON' ) * ajj
              else
                 dstop = tol
              end if
              if( upper ) then
                 ! compute the cholesky factorization p**t * a * p = u**h * u
                 loop_160: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first chalf of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_150: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second chalf of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) +real( conjg( a( j-1, i ) )*a( j-1, i ),&
                                       KIND=dp)
                          end if
                          work( n+i ) = real( a( i, i ),KIND=dp) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 220
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_zswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                          if( pvt<n )call stdlib${ii}$_zswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ),&
                                     lda )
                          do i = j + 1, pvt - 1
                             ztemp = conjg( a( j, i ) )
                             a( j, i ) = conjg( a( i, pvt ) )
                             a( i, pvt ) = ztemp
                          end do
                          a( j, pvt ) = conjg( a( j, pvt ) )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of row j.
                       if( j<n ) then
                          call stdlib${ii}$_zlacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                          call stdlib${ii}$_zgemv( 'TRANS', j-k, n-j, -cone, a( k, j+1 ),lda, a( k, j ),&
                                     1_${ik}$, cone, a( j, j+1 ),lda )
                          call stdlib${ii}$_zlacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                          call stdlib${ii}$_zdscal( n-j, one / ajj, a( j, j+1 ), lda )
                       end if
                    end do loop_150
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_zherk( 'UPPER', 'CONJ TRANS', n-j+1, jb, -one,a( k, j ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_160
              else
              ! compute the cholesky factorization p**t * a * p = l * l**h
                 loop_210: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first chalf of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_200: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second chalf of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) +real( conjg( a( i, j-1 ) )*a( i, j-1 ),&
                                       KIND=dp)
                          end if
                          work( n+i ) = real( a( i, i ),KIND=dp) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 220
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_zswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                          if( pvt<n )call stdlib${ii}$_zswap( n-pvt, a( pvt+1, j ), 1_${ik}$,a( pvt+1, pvt ), &
                                    1_${ik}$ )
                          do i = j + 1, pvt - 1
                             ztemp = conjg( a( i, j ) )
                             a( i, j ) = conjg( a( pvt, i ) )
                             a( pvt, i ) = ztemp
                          end do
                          a( pvt, j ) = conjg( a( pvt, j ) )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of column j.
                       if( j<n ) then
                          call stdlib${ii}$_zlacgv( j-1, a( j, 1_${ik}$ ), lda )
                          call stdlib${ii}$_zgemv( 'NO TRANS', n-j, j-k, -cone,a( j+1, k ), lda, a( j, &
                                    k ), lda, cone,a( j+1, j ), 1_${ik}$ )
                          call stdlib${ii}$_zlacgv( j-1, a( j, 1_${ik}$ ), lda )
                          call stdlib${ii}$_zdscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                       end if
                    end do loop_200
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_zherk( 'LOWER', 'NO TRANS', n-j+1, jb, -one,a( j, k ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_210
              end if
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 230
           220 continue
           ! rank is the number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           230 continue
           return
     end subroutine stdlib${ii}$_zpstrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pstrf( uplo, n, a, lda, piv, rank, tol, work, info )
     !! ZPSTRF: computes the Cholesky factorization with complete
     !! pivoting of a complex Hermitian positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**H * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 3 BLAS.
        ! -- 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 
           real(${ck}$), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           real(${ck}$), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           
           ! Local Scalars 
           complex(${ck}$) :: ztemp
           real(${ck}$) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, jb, k, nb, pvt
           logical(lk) :: upper
           ! 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( 'ZPSTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! get block size
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPOTRF', uplo, n, -1_${ik}$, -1_${ik}$, -1_${ik}$ )
           if( nb<=1_${ik}$ .or. nb>=n ) then
              ! use unblocked code
              call stdlib${ii}$_${ci}$pstf2( uplo, n, a( 1_${ik}$, 1_${ik}$ ), lda, piv, rank, tol, work,info )
              go to 230
           else
           ! initialize piv
              do i = 1, n
                 piv( i ) = i
              end do
           ! compute stopping value
              do i = 1, n
                 work( i ) = real( a( i, i ),KIND=${ck}$)
              end do
              pvt = maxloc( work( 1_${ik}$:n ), 1_${ik}$ )
              ajj = real( a( pvt, pvt ),KIND=${ck}$)
              if( ajj<=zero.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                 rank = 0_${ik}$
                 info = 1_${ik}$
                 go to 230
              end if
           ! compute stopping value if not supplied
              if( tol<zero ) then
                 dstop = n * stdlib${ii}$_${c2ri(ci)}$lamch( 'EPSILON' ) * ajj
              else
                 dstop = tol
              end if
              if( upper ) then
                 ! compute the cholesky factorization p**t * a * p = u**h * u
                 loop_160: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first chalf of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_150: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second chalf of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) +real( conjg( a( j-1, i ) )*a( j-1, i ),&
                                       KIND=${ck}$)
                          end if
                          work( n+i ) = real( a( i, i ),KIND=${ck}$) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 220
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_${ci}$swap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                          if( pvt<n )call stdlib${ii}$_${ci}$swap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ),&
                                     lda )
                          do i = j + 1, pvt - 1
                             ztemp = conjg( a( j, i ) )
                             a( j, i ) = conjg( a( i, pvt ) )
                             a( i, pvt ) = ztemp
                          end do
                          a( j, pvt ) = conjg( a( j, pvt ) )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of row j.
                       if( j<n ) then
                          call stdlib${ii}$_${ci}$lacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                          call stdlib${ii}$_${ci}$gemv( 'TRANS', j-k, n-j, -cone, a( k, j+1 ),lda, a( k, j ),&
                                     1_${ik}$, cone, a( j, j+1 ),lda )
                          call stdlib${ii}$_${ci}$lacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                          call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, a( j, j+1 ), lda )
                       end if
                    end do loop_150
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_${ci}$herk( 'UPPER', 'CONJ TRANS', n-j+1, jb, -one,a( k, j ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_160
              else
              ! compute the cholesky factorization p**t * a * p = l * l**h
                 loop_210: do k = 1, n, nb
                    ! account for last block not being nb wide
                    jb = min( nb, n-k+1 )
                    ! set relevant part of first chalf of work to zero,
                    ! holds dot products
                    do i = k, n
                       work( i ) = 0_${ik}$
                    end do
                    loop_200: do j = k, k + jb - 1
                    ! find pivot, test for exit, else swap rows and columns
                    ! update dot products, compute possible pivots which are
                    ! stored in the second chalf of work
                       do i = j, n
                          if( j>k ) then
                             work( i ) = work( i ) +real( conjg( a( i, j-1 ) )*a( i, j-1 ),&
                                       KIND=${ck}$)
                          end if
                          work( n+i ) = real( a( i, i ),KIND=${ck}$) - work( i )
                       end do
                       if( j>1_${ik}$ ) then
                          itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                          pvt = itemp + j - 1_${ik}$
                          ajj = work( n+pvt )
                          if( ajj<=dstop.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                             a( j, j ) = ajj
                             go to 220
                          end if
                       end if
                       if( j/=pvt ) then
                          ! pivot ok, so can now swap pivot rows and columns
                          a( pvt, pvt ) = a( j, j )
                          call stdlib${ii}$_${ci}$swap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                          if( pvt<n )call stdlib${ii}$_${ci}$swap( n-pvt, a( pvt+1, j ), 1_${ik}$,a( pvt+1, pvt ), &
                                    1_${ik}$ )
                          do i = j + 1, pvt - 1
                             ztemp = conjg( a( i, j ) )
                             a( i, j ) = conjg( a( pvt, i ) )
                             a( pvt, i ) = ztemp
                          end do
                          a( pvt, j ) = conjg( a( pvt, j ) )
                          ! swap dot products and piv
                          dtemp = work( j )
                          work( j ) = work( pvt )
                          work( pvt ) = dtemp
                          itemp = piv( pvt )
                          piv( pvt ) = piv( j )
                          piv( j ) = itemp
                       end if
                       ajj = sqrt( ajj )
                       a( j, j ) = ajj
                       ! compute elements j+1:n of column j.
                       if( j<n ) then
                          call stdlib${ii}$_${ci}$lacgv( j-1, a( j, 1_${ik}$ ), lda )
                          call stdlib${ii}$_${ci}$gemv( 'NO TRANS', n-j, j-k, -cone,a( j+1, k ), lda, a( j, &
                                    k ), lda, cone,a( j+1, j ), 1_${ik}$ )
                          call stdlib${ii}$_${ci}$lacgv( j-1, a( j, 1_${ik}$ ), lda )
                          call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                       end if
                    end do loop_200
                    ! update trailing matrix, j already incremented
                    if( k+jb<=n ) then
                       call stdlib${ii}$_${ci}$herk( 'LOWER', 'NO TRANS', n-j+1, jb, -one,a( j, k ), lda, &
                                 one, a( j, j ), lda )
                    end if
                 end do loop_210
              end if
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 230
           220 continue
           ! rank is the number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           230 continue
           return
     end subroutine stdlib${ii}$_${ci}$pstrf

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spstf2( uplo, n, a, lda, piv, rank, tol, work, info )
     !! SPSTF2 computes the Cholesky factorization with complete
     !! pivoting of a real symmetric positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**T * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 2 BLAS.
        ! -- 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 
           real(sp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           real(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           ! Local Scalars 
           real(sp) :: ajj, sstop, stemp
           integer(${ik}$) :: i, itemp, j, pvt
           logical(lk) :: upper
           ! 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( 'SPSTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! initialize piv
           do i = 1, n
              piv( i ) = i
           end do
           ! compute stopping value
           pvt = 1_${ik}$
           ajj = a( pvt, pvt )
           do i = 2, n
              if( a( i, i )>ajj ) then
                 pvt = i
                 ajj = a( pvt, pvt )
              end if
           end do
           if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
              rank = 0_${ik}$
              info = 1_${ik}$
              go to 170
           end if
           ! compute stopping value if not supplied
           if( tol<zero ) then
              sstop = n * stdlib${ii}$_slamch( 'EPSILON' ) * ajj
           else
              sstop = tol
           end if
           ! set first half of work to zero, holds dot products
           do i = 1, n
              work( i ) = 0_${ik}$
           end do
           if( upper ) then
              ! compute the cholesky factorization p**t * a * p = u**t * u
              loop_130: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second half of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) + a( j-1, i )**2_${ik}$
                    end if
                    work( n+i ) = a( i, i ) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 160
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_sswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                    if( pvt<n )call stdlib${ii}$_sswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ), lda )
                              
                    call stdlib${ii}$_sswap( pvt-j-1, a( j, j+1 ), lda, a( j+1, pvt ), 1_${ik}$ )
                    ! swap dot products and piv
                    stemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = stemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j
                 if( j<n ) then
                    call stdlib${ii}$_sgemv( 'TRANS', j-1, n-j, -one, a( 1_${ik}$, j+1 ), lda,a( 1_${ik}$, j ), 1_${ik}$, &
                              one, a( j, j+1 ), lda )
                    call stdlib${ii}$_sscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do loop_130
           else
              ! compute the cholesky factorization p**t * a * p = l * l**t
              loop_150: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second half of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) + a( i, j-1 )**2_${ik}$
                    end if
                    work( n+i ) = a( i, i ) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 160
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_sswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                    if( pvt<n )call stdlib${ii}$_sswap( n-pvt, a( pvt+1, j ), 1_${ik}$, a( pvt+1, pvt ),1_${ik}$ )
                              
                    call stdlib${ii}$_sswap( pvt-j-1, a( j+1, j ), 1_${ik}$, a( pvt, j+1 ), lda )
                    ! swap dot products and piv
                    stemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = stemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j
                 if( j<n ) then
                    call stdlib${ii}$_sgemv( 'NO TRANS', n-j, j-1, -one, a( j+1, 1_${ik}$ ), lda,a( j, 1_${ik}$ ), &
                              lda, one, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_sscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do loop_150
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 170
           160 continue
           ! rank is number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           170 continue
           return
     end subroutine stdlib${ii}$_spstf2

     pure module subroutine stdlib${ii}$_dpstf2( uplo, n, a, lda, piv, rank, tol, work, info )
     !! DPSTF2 computes the Cholesky factorization with complete
     !! pivoting of a real symmetric positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**T * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 2 BLAS.
        ! -- 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 
           real(dp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           real(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           ! Local Scalars 
           real(dp) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, pvt
           logical(lk) :: upper
           ! 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( 'DPSTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! initialize piv
           do i = 1, n
              piv( i ) = i
           end do
           ! compute stopping value
           pvt = 1_${ik}$
           ajj = a( pvt, pvt )
           do i = 2, n
              if( a( i, i )>ajj ) then
                 pvt = i
                 ajj = a( pvt, pvt )
              end if
           end do
           if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
              rank = 0_${ik}$
              info = 1_${ik}$
              go to 170
           end if
           ! compute stopping value if not supplied
           if( tol<zero ) then
              dstop = n * stdlib${ii}$_dlamch( 'EPSILON' ) * ajj
           else
              dstop = tol
           end if
           ! set first half of work to zero, holds dot products
           do i = 1, n
              work( i ) = 0_${ik}$
           end do
           if( upper ) then
              ! compute the cholesky factorization p**t * a * p = u**t * u
              loop_130: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second half of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) + a( j-1, i )**2_${ik}$
                    end if
                    work( n+i ) = a( i, i ) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 160
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_dswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                    if( pvt<n )call stdlib${ii}$_dswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ), lda )
                              
                    call stdlib${ii}$_dswap( pvt-j-1, a( j, j+1 ), lda, a( j+1, pvt ), 1_${ik}$ )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j
                 if( j<n ) then
                    call stdlib${ii}$_dgemv( 'TRANS', j-1, n-j, -one, a( 1_${ik}$, j+1 ), lda,a( 1_${ik}$, j ), 1_${ik}$, &
                              one, a( j, j+1 ), lda )
                    call stdlib${ii}$_dscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do loop_130
           else
              ! compute the cholesky factorization p**t * a * p = l * l**t
              loop_150: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second half of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) + a( i, j-1 )**2_${ik}$
                    end if
                    work( n+i ) = a( i, i ) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 160
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_dswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                    if( pvt<n )call stdlib${ii}$_dswap( n-pvt, a( pvt+1, j ), 1_${ik}$, a( pvt+1, pvt ),1_${ik}$ )
                              
                    call stdlib${ii}$_dswap( pvt-j-1, a( j+1, j ), 1_${ik}$, a( pvt, j+1 ), lda )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j
                 if( j<n ) then
                    call stdlib${ii}$_dgemv( 'NO TRANS', n-j, j-1, -one, a( j+1, 1_${ik}$ ), lda,a( j, 1_${ik}$ ), &
                              lda, one, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_dscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do loop_150
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 170
           160 continue
           ! rank is number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           170 continue
           return
     end subroutine stdlib${ii}$_dpstf2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pstf2( uplo, n, a, lda, piv, rank, tol, work, info )
     !! DPSTF2: computes the Cholesky factorization with complete
     !! pivoting of a real symmetric positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**T * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 2 BLAS.
        ! -- 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 
           real(${rk}$), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(lda,*)
           real(${rk}$), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           ! Local Scalars 
           real(${rk}$) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, pvt
           logical(lk) :: upper
           ! 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( 'DPSTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! initialize piv
           do i = 1, n
              piv( i ) = i
           end do
           ! compute stopping value
           pvt = 1_${ik}$
           ajj = a( pvt, pvt )
           do i = 2, n
              if( a( i, i )>ajj ) then
                 pvt = i
                 ajj = a( pvt, pvt )
              end if
           end do
           if( ajj<=zero.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
              rank = 0_${ik}$
              info = 1_${ik}$
              go to 170
           end if
           ! compute stopping value if not supplied
           if( tol<zero ) then
              dstop = n * stdlib${ii}$_${ri}$lamch( 'EPSILON' ) * ajj
           else
              dstop = tol
           end if
           ! set first half of work to zero, holds dot products
           do i = 1, n
              work( i ) = 0_${ik}$
           end do
           if( upper ) then
              ! compute the cholesky factorization p**t * a * p = u**t * u
              loop_130: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second half of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) + a( j-1, i )**2_${ik}$
                    end if
                    work( n+i ) = a( i, i ) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 160
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_${ri}$swap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                    if( pvt<n )call stdlib${ii}$_${ri}$swap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ), lda )
                              
                    call stdlib${ii}$_${ri}$swap( pvt-j-1, a( j, j+1 ), lda, a( j+1, pvt ), 1_${ik}$ )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j
                 if( j<n ) then
                    call stdlib${ii}$_${ri}$gemv( 'TRANS', j-1, n-j, -one, a( 1_${ik}$, j+1 ), lda,a( 1_${ik}$, j ), 1_${ik}$, &
                              one, a( j, j+1 ), lda )
                    call stdlib${ii}$_${ri}$scal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do loop_130
           else
              ! compute the cholesky factorization p**t * a * p = l * l**t
              loop_150: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second half of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) + a( i, j-1 )**2_${ik}$
                    end if
                    work( n+i ) = a( i, i ) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_${ri}$isnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 160
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_${ri}$swap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                    if( pvt<n )call stdlib${ii}$_${ri}$swap( n-pvt, a( pvt+1, j ), 1_${ik}$, a( pvt+1, pvt ),1_${ik}$ )
                              
                    call stdlib${ii}$_${ri}$swap( pvt-j-1, a( j+1, j ), 1_${ik}$, a( pvt, j+1 ), lda )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j
                 if( j<n ) then
                    call stdlib${ii}$_${ri}$gemv( 'NO TRANS', n-j, j-1, -one, a( j+1, 1_${ik}$ ), lda,a( j, 1_${ik}$ ), &
                              lda, one, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ri}$scal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do loop_150
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 170
           160 continue
           ! rank is number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           170 continue
           return
     end subroutine stdlib${ii}$_${ri}$pstf2

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpstf2( uplo, n, a, lda, piv, rank, tol, work, info )
     !! CPSTF2 computes the Cholesky factorization with complete
     !! pivoting of a complex Hermitian positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**H * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 2 BLAS.
        ! -- 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 
           real(sp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           complex(sp), intent(inout) :: a(lda,*)
           real(sp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           
           ! Local Scalars 
           complex(sp) :: ctemp
           real(sp) :: ajj, sstop, stemp
           integer(${ik}$) :: i, itemp, j, pvt
           logical(lk) :: upper
           ! 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( 'CPSTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! initialize piv
           do i = 1, n
              piv( i ) = i
           end do
           ! compute stopping value
           do i = 1, n
              work( i ) = real( a( i, i ),KIND=sp)
           end do
           pvt = maxloc( work( 1_${ik}$:n ), 1_${ik}$ )
           ajj = real( a( pvt, pvt ),KIND=sp)
           if( ajj<=zero.or.stdlib${ii}$_sisnan( ajj ) ) then
              rank = 0_${ik}$
              info = 1_${ik}$
              go to 200
           end if
           ! compute stopping value if not supplied
           if( tol<zero ) then
              sstop = n * stdlib${ii}$_slamch( 'EPSILON' ) * ajj
           else
              sstop = tol
           end if
           ! set first chalf of work to zero, holds dot products
           do i = 1, n
              work( i ) = 0_${ik}$
           end do
           if( upper ) then
              ! compute the cholesky factorization p**t * a * p = u**h * u
              loop_150: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second chalf of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) +real( conjg( a( j-1, i ) )*a( j-1, i ),KIND=sp)
                                 
                    end if
                    work( n+i ) = real( a( i, i ),KIND=sp) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 190
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_cswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                    if( pvt<n )call stdlib${ii}$_cswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ), lda )
                              
                    do i = j + 1, pvt - 1
                       ctemp = conjg( a( j, i ) )
                       a( j, i ) = conjg( a( i, pvt ) )
                       a( i, pvt ) = ctemp
                    end do
                    a( j, pvt ) = conjg( a( j, pvt ) )
                    ! swap dot products and piv
                    stemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = stemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j
                 if( j<n ) then
                    call stdlib${ii}$_clacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_cgemv( 'TRANS', j-1, n-j, -cone, a( 1_${ik}$, j+1 ), lda,a( 1_${ik}$, j ), 1_${ik}$, &
                              cone, a( j, j+1 ), lda )
                    call stdlib${ii}$_clacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_csscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do loop_150
           else
              ! compute the cholesky factorization p**t * a * p = l * l**h
              loop_180: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second chalf of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) +real( conjg( a( i, j-1 ) )*a( i, j-1 ),KIND=sp)
                                 
                    end if
                    work( n+i ) = real( a( i, i ),KIND=sp) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=sstop.or.stdlib${ii}$_sisnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 190
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_cswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                    if( pvt<n )call stdlib${ii}$_cswap( n-pvt, a( pvt+1, j ), 1_${ik}$, a( pvt+1, pvt ),1_${ik}$ )
                              
                    do i = j + 1, pvt - 1
                       ctemp = conjg( a( i, j ) )
                       a( i, j ) = conjg( a( pvt, i ) )
                       a( pvt, i ) = ctemp
                    end do
                    a( pvt, j ) = conjg( a( pvt, j ) )
                    ! swap dot products and piv
                    stemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = stemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j
                 if( j<n ) then
                    call stdlib${ii}$_clacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_cgemv( 'NO TRANS', n-j, j-1, -cone, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ ), &
                              lda, cone, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_clacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_csscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do loop_180
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 200
           190 continue
           ! rank is number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           200 continue
           return
     end subroutine stdlib${ii}$_cpstf2

     pure module subroutine stdlib${ii}$_zpstf2( uplo, n, a, lda, piv, rank, tol, work, info )
     !! ZPSTF2 computes the Cholesky factorization with complete
     !! pivoting of a complex Hermitian positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**H * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 2 BLAS.
        ! -- 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 
           real(dp), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           complex(dp), intent(inout) :: a(lda,*)
           real(dp), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           
           ! Local Scalars 
           complex(dp) :: ztemp
           real(dp) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, pvt
           logical(lk) :: upper
           ! 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( 'ZPSTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! initialize piv
           do i = 1, n
              piv( i ) = i
           end do
           ! compute stopping value
           do i = 1, n
              work( i ) = real( a( i, i ),KIND=dp)
           end do
           pvt = maxloc( work( 1_${ik}$:n ), 1_${ik}$ )
           ajj = real( a( pvt, pvt ),KIND=dp)
           if( ajj<=zero.or.stdlib${ii}$_disnan( ajj ) ) then
              rank = 0_${ik}$
              info = 1_${ik}$
              go to 200
           end if
           ! compute stopping value if not supplied
           if( tol<zero ) then
              dstop = n * stdlib${ii}$_dlamch( 'EPSILON' ) * ajj
           else
              dstop = tol
           end if
           ! set first chalf of work to zero, holds dot products
           do i = 1, n
              work( i ) = 0_${ik}$
           end do
           if( upper ) then
              ! compute the cholesky factorization p**t * a * p = u**h* u
              loop_150: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second chalf of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) +real( conjg( a( j-1, i ) )*a( j-1, i ),KIND=dp)
                                 
                    end if
                    work( n+i ) = real( a( i, i ),KIND=dp) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 190
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_zswap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                    if( pvt<n )call stdlib${ii}$_zswap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ), lda )
                              
                    do i = j + 1, pvt - 1
                       ztemp = conjg( a( j, i ) )
                       a( j, i ) = conjg( a( i, pvt ) )
                       a( i, pvt ) = ztemp
                    end do
                    a( j, pvt ) = conjg( a( j, pvt ) )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j
                 if( j<n ) then
                    call stdlib${ii}$_zlacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_zgemv( 'TRANS', j-1, n-j, -cone, a( 1_${ik}$, j+1 ), lda,a( 1_${ik}$, j ), 1_${ik}$, &
                              cone, a( j, j+1 ), lda )
                    call stdlib${ii}$_zlacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_zdscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do loop_150
           else
              ! compute the cholesky factorization p**t * a * p = l * l**h
              loop_180: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second chalf of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) +real( conjg( a( i, j-1 ) )*a( i, j-1 ),KIND=dp)
                                 
                    end if
                    work( n+i ) = real( a( i, i ),KIND=dp) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_disnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 190
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_zswap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                    if( pvt<n )call stdlib${ii}$_zswap( n-pvt, a( pvt+1, j ), 1_${ik}$, a( pvt+1, pvt ),1_${ik}$ )
                              
                    do i = j + 1, pvt - 1
                       ztemp = conjg( a( i, j ) )
                       a( i, j ) = conjg( a( pvt, i ) )
                       a( pvt, i ) = ztemp
                    end do
                    a( pvt, j ) = conjg( a( pvt, j ) )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j
                 if( j<n ) then
                    call stdlib${ii}$_zlacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_zgemv( 'NO TRANS', n-j, j-1, -cone, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ ), &
                              lda, cone, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_zlacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_zdscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do loop_180
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 200
           190 continue
           ! rank is number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           200 continue
           return
     end subroutine stdlib${ii}$_zpstf2

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pstf2( uplo, n, a, lda, piv, rank, tol, work, info )
     !! ZPSTF2: computes the Cholesky factorization with complete
     !! pivoting of a complex Hermitian positive semidefinite matrix A.
     !! The factorization has the form
     !! P**T * A * P = U**H * U ,  if UPLO = 'U',
     !! P**T * A * P = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular, and
     !! P is stored as vector PIV.
     !! This algorithm does not attempt to check that A is positive
     !! semidefinite. This version of the algorithm calls level 2 BLAS.
        ! -- 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 
           real(${ck}$), intent(in) :: tol
           integer(${ik}$), intent(out) :: info, rank
           integer(${ik}$), intent(in) :: lda, n
           character, intent(in) :: uplo
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(lda,*)
           real(${ck}$), intent(out) :: work(2_${ik}$*n)
           integer(${ik}$), intent(out) :: piv(n)
        ! =====================================================================
           
           
           ! Local Scalars 
           complex(${ck}$) :: ztemp
           real(${ck}$) :: ajj, dstop, dtemp
           integer(${ik}$) :: i, itemp, j, pvt
           logical(lk) :: upper
           ! 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( 'ZPSTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! initialize piv
           do i = 1, n
              piv( i ) = i
           end do
           ! compute stopping value
           do i = 1, n
              work( i ) = real( a( i, i ),KIND=${ck}$)
           end do
           pvt = maxloc( work( 1_${ik}$:n ), 1_${ik}$ )
           ajj = real( a( pvt, pvt ),KIND=${ck}$)
           if( ajj<=zero.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
              rank = 0_${ik}$
              info = 1_${ik}$
              go to 200
           end if
           ! compute stopping value if not supplied
           if( tol<zero ) then
              dstop = n * stdlib${ii}$_${c2ri(ci)}$lamch( 'EPSILON' ) * ajj
           else
              dstop = tol
           end if
           ! set first chalf of work to zero, holds dot products
           do i = 1, n
              work( i ) = 0_${ik}$
           end do
           if( upper ) then
              ! compute the cholesky factorization p**t * a * p = u**h* u
              loop_150: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second chalf of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) +real( conjg( a( j-1, i ) )*a( j-1, i ),KIND=${ck}$)
                                 
                    end if
                    work( n+i ) = real( a( i, i ),KIND=${ck}$) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 190
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_${ci}$swap( j-1, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, pvt ), 1_${ik}$ )
                    if( pvt<n )call stdlib${ii}$_${ci}$swap( n-pvt, a( j, pvt+1 ), lda,a( pvt, pvt+1 ), lda )
                              
                    do i = j + 1, pvt - 1
                       ztemp = conjg( a( j, i ) )
                       a( j, i ) = conjg( a( i, pvt ) )
                       a( i, pvt ) = ztemp
                    end do
                    a( j, pvt ) = conjg( a( j, pvt ) )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of row j
                 if( j<n ) then
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$gemv( 'TRANS', j-1, n-j, -cone, a( 1_${ik}$, j+1 ), lda,a( 1_${ik}$, j ), 1_${ik}$, &
                              cone, a( j, j+1 ), lda )
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( 1_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, a( j, j+1 ), lda )
                 end if
              end do loop_150
           else
              ! compute the cholesky factorization p**t * a * p = l * l**h
              loop_180: do j = 1, n
              ! find pivot, test for exit, else swap rows and columns
              ! update dot products, compute possible pivots which are
              ! stored in the second chalf of work
                 do i = j, n
                    if( j>1_${ik}$ ) then
                       work( i ) = work( i ) +real( conjg( a( i, j-1 ) )*a( i, j-1 ),KIND=${ck}$)
                                 
                    end if
                    work( n+i ) = real( a( i, i ),KIND=${ck}$) - work( i )
                 end do
                 if( j>1_${ik}$ ) then
                    itemp = maxloc( work( (n+j):(2_${ik}$*n) ), 1_${ik}$ )
                    pvt = itemp + j - 1_${ik}$
                    ajj = work( n+pvt )
                    if( ajj<=dstop.or.stdlib${ii}$_${c2ri(ci)}$isnan( ajj ) ) then
                       a( j, j ) = ajj
                       go to 190
                    end if
                 end if
                 if( j/=pvt ) then
                    ! pivot ok, so can now swap pivot rows and columns
                    a( pvt, pvt ) = a( j, j )
                    call stdlib${ii}$_${ci}$swap( j-1, a( j, 1_${ik}$ ), lda, a( pvt, 1_${ik}$ ), lda )
                    if( pvt<n )call stdlib${ii}$_${ci}$swap( n-pvt, a( pvt+1, j ), 1_${ik}$, a( pvt+1, pvt ),1_${ik}$ )
                              
                    do i = j + 1, pvt - 1
                       ztemp = conjg( a( i, j ) )
                       a( i, j ) = conjg( a( pvt, i ) )
                       a( pvt, i ) = ztemp
                    end do
                    a( pvt, j ) = conjg( a( pvt, j ) )
                    ! swap dot products and piv
                    dtemp = work( j )
                    work( j ) = work( pvt )
                    work( pvt ) = dtemp
                    itemp = piv( pvt )
                    piv( pvt ) = piv( j )
                    piv( j ) = itemp
                 end if
                 ajj = sqrt( ajj )
                 a( j, j ) = ajj
                 ! compute elements j+1:n of column j
                 if( j<n ) then
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_${ci}$gemv( 'NO TRANS', n-j, j-1, -cone, a( j+1, 1_${ik}$ ),lda, a( j, 1_${ik}$ ), &
                              lda, cone, a( j+1, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$lacgv( j-1, a( j, 1_${ik}$ ), lda )
                    call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, a( j+1, j ), 1_${ik}$ )
                 end if
              end do loop_180
           end if
           ! ran to completion, a has full rank
           rank = n
           go to 200
           190 continue
           ! rank is number of steps completed.  set info = 1 to signal
           ! that the factorization cannot be used to solve a system.
           rank = j - 1_${ik}$
           info = 1_${ik}$
           200 continue
           return
     end subroutine stdlib${ii}$_${ci}$pstf2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spotrs( uplo, n, nrhs, a, lda, b, ldb, info )
     !! SPOTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by SPOTRF.
        ! -- 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, ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*)
           real(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPOTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t *u.
              ! solve u**t *x = b, overwriting b with x.
              call stdlib${ii}$_strsm( 'LEFT', 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, nrhs,one, a, lda, b,&
                         ldb )
              ! solve u*x = b, overwriting b with x.
              call stdlib${ii}$_strsm( 'LEFT', 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, one, a, lda,&
                         b, ldb )
           else
              ! solve a*x = b where a = l*l**t.
              ! solve l*x = b, overwriting b with x.
              call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, one, a, lda,&
                         b, ldb )
              ! solve l**t *x = b, overwriting b with x.
              call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, nrhs,one, a, lda, b,&
                         ldb )
           end if
           return
     end subroutine stdlib${ii}$_spotrs

     pure module subroutine stdlib${ii}$_dpotrs( uplo, n, nrhs, a, lda, b, ldb, info )
     !! DPOTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by DPOTRF.
        ! -- 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, ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*)
           real(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t *u.
              ! solve u**t *x = b, overwriting b with x.
              call stdlib${ii}$_dtrsm( 'LEFT', 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, nrhs,one, a, lda, b,&
                         ldb )
              ! solve u*x = b, overwriting b with x.
              call stdlib${ii}$_dtrsm( 'LEFT', 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, one, a, lda,&
                         b, ldb )
           else
              ! solve a*x = b where a = l*l**t.
              ! solve l*x = b, overwriting b with x.
              call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, one, a, lda,&
                         b, ldb )
              ! solve l**t *x = b, overwriting b with x.
              call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, nrhs,one, a, lda, b,&
                         ldb )
           end if
           return
     end subroutine stdlib${ii}$_dpotrs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$potrs( uplo, n, nrhs, a, lda, b, ldb, info )
     !! DPOTRS: solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by DPOTRF.
        ! -- 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, ldb, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*)
           real(${rk}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t *u.
              ! solve u**t *x = b, overwriting b with x.
              call stdlib${ii}$_${ri}$trsm( 'LEFT', 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, nrhs,one, a, lda, b,&
                         ldb )
              ! solve u*x = b, overwriting b with x.
              call stdlib${ii}$_${ri}$trsm( 'LEFT', 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, one, a, lda,&
                         b, ldb )
           else
              ! solve a*x = b where a = l*l**t.
              ! solve l*x = b, overwriting b with x.
              call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, one, a, lda,&
                         b, ldb )
              ! solve l**t *x = b, overwriting b with x.
              call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, nrhs,one, a, lda, b,&
                         ldb )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$potrs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpotrs( uplo, n, nrhs, a, lda, b, ldb, info )
     !! CPOTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**H*U or A = L*L**H computed by CPOTRF.
        ! -- 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, ldb, n, nrhs
           ! Array Arguments 
           complex(sp), intent(in) :: a(lda,*)
           complex(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPOTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h *u.
              ! solve u**h *x = b, overwriting b with x.
              call stdlib${ii}$_ctrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n, nrhs, cone,&
                         a, lda, b, ldb )
              ! solve u*x = b, overwriting b with x.
              call stdlib${ii}$_ctrsm( 'LEFT', 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, cone, a, &
                        lda, b, ldb )
           else
              ! solve a*x = b where a = l*l**h.
              ! solve l*x = b, overwriting b with x.
              call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, cone, a, &
                        lda, b, ldb )
              ! solve l**h *x = b, overwriting b with x.
              call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n, nrhs, cone,&
                         a, lda, b, ldb )
           end if
           return
     end subroutine stdlib${ii}$_cpotrs

     pure module subroutine stdlib${ii}$_zpotrs( uplo, n, nrhs, a, lda, b, ldb, info )
     !! ZPOTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**H * U or A = L * L**H computed by ZPOTRF.
        ! -- 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, ldb, n, nrhs
           ! Array Arguments 
           complex(dp), intent(in) :: a(lda,*)
           complex(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h *u.
              ! solve u**h *x = b, overwriting b with x.
              call stdlib${ii}$_ztrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n, nrhs, cone,&
                         a, lda, b, ldb )
              ! solve u*x = b, overwriting b with x.
              call stdlib${ii}$_ztrsm( 'LEFT', 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, cone, a, &
                        lda, b, ldb )
           else
              ! solve a*x = b where a = l*l**h.
              ! solve l*x = b, overwriting b with x.
              call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, cone, a, &
                        lda, b, ldb )
              ! solve l**h *x = b, overwriting b with x.
              call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n, nrhs, cone,&
                         a, lda, b, ldb )
           end if
           return
     end subroutine stdlib${ii}$_zpotrs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$potrs( uplo, n, nrhs, a, lda, b, ldb, info )
     !! ZPOTRS: solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**H * U or A = L * L**H computed by ZPOTRF.
        ! -- 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, ldb, n, nrhs
           ! Array Arguments 
           complex(${ck}$), intent(in) :: a(lda,*)
           complex(${ck}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h *u.
              ! solve u**h *x = b, overwriting b with x.
              call stdlib${ii}$_${ci}$trsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n, nrhs, cone,&
                         a, lda, b, ldb )
              ! solve u*x = b, overwriting b with x.
              call stdlib${ii}$_${ci}$trsm( 'LEFT', 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, cone, a, &
                        lda, b, ldb )
           else
              ! solve a*x = b where a = l*l**h.
              ! solve l*x = b, overwriting b with x.
              call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n,nrhs, cone, a, &
                        lda, b, ldb )
              ! solve l**h *x = b, overwriting b with x.
              call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n, nrhs, cone,&
                         a, lda, b, ldb )
           end if
           return
     end subroutine stdlib${ii}$_${ci}$potrs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spotri( uplo, n, a, lda, info )
     !! SPOTRI computes the inverse of a real symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by SPOTRF.
        ! -- 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,*)
        ! =====================================================================
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( .not.stdlib_lsame( uplo, 'U' ) .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( 'SPOTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_strtri( uplo, 'NON-UNIT', n, a, lda, info )
           if( info>0 )return
           ! form inv(u) * inv(u)**t or inv(l)**t * inv(l).
           call stdlib${ii}$_slauum( uplo, n, a, lda, info )
           return
     end subroutine stdlib${ii}$_spotri

     pure module subroutine stdlib${ii}$_dpotri( uplo, n, a, lda, info )
     !! DPOTRI computes the inverse of a real symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by DPOTRF.
        ! -- 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,*)
        ! =====================================================================
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( .not.stdlib_lsame( uplo, 'U' ) .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( 'DPOTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_dtrtri( uplo, 'NON-UNIT', n, a, lda, info )
           if( info>0 )return
           ! form inv(u) * inv(u)**t or inv(l)**t * inv(l).
           call stdlib${ii}$_dlauum( uplo, n, a, lda, info )
           return
     end subroutine stdlib${ii}$_dpotri

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$potri( uplo, n, a, lda, info )
     !! DPOTRI: computes the inverse of a real symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by DPOTRF.
        ! -- 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,*)
        ! =====================================================================
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( .not.stdlib_lsame( uplo, 'U' ) .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( 'DPOTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_${ri}$trtri( uplo, 'NON-UNIT', n, a, lda, info )
           if( info>0 )return
           ! form inv(u) * inv(u)**t or inv(l)**t * inv(l).
           call stdlib${ii}$_${ri}$lauum( uplo, n, a, lda, info )
           return
     end subroutine stdlib${ii}$_${ri}$potri

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpotri( uplo, n, a, lda, info )
     !! CPOTRI computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by CPOTRF.
        ! -- 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 
           complex(sp), intent(inout) :: a(lda,*)
        ! =====================================================================
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( .not.stdlib_lsame( uplo, 'U' ) .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( 'CPOTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_ctrtri( uplo, 'NON-UNIT', n, a, lda, info )
           if( info>0 )return
           ! form inv(u) * inv(u)**h or inv(l)**h * inv(l).
           call stdlib${ii}$_clauum( uplo, n, a, lda, info )
           return
     end subroutine stdlib${ii}$_cpotri

     pure module subroutine stdlib${ii}$_zpotri( uplo, n, a, lda, info )
     !! ZPOTRI computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by ZPOTRF.
        ! -- 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 
           complex(dp), intent(inout) :: a(lda,*)
        ! =====================================================================
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( .not.stdlib_lsame( uplo, 'U' ) .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( 'ZPOTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_ztrtri( uplo, 'NON-UNIT', n, a, lda, info )
           if( info>0 )return
           ! form inv(u) * inv(u)**h or inv(l)**h * inv(l).
           call stdlib${ii}$_zlauum( uplo, n, a, lda, info )
           return
     end subroutine stdlib${ii}$_zpotri

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$potri( uplo, n, a, lda, info )
     !! ZPOTRI: computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by ZPOTRF.
        ! -- 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 
           complex(${ck}$), intent(inout) :: a(lda,*)
        ! =====================================================================
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( .not.stdlib_lsame( uplo, 'U' ) .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( 'ZPOTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_${ci}$trtri( uplo, 'NON-UNIT', n, a, lda, info )
           if( info>0 )return
           ! form inv(u) * inv(u)**h or inv(l)**h * inv(l).
           call stdlib${ii}$_${ci}$lauum( uplo, n, a, lda, info )
           return
     end subroutine stdlib${ii}$_${ci}$potri

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sporfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x,ldx, ferr, berr, &
     !! SPORFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite,
     !! and provides error bounds and backward error estimates for the
     !! solution.
               work, iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(in) :: a(lda,*), af(ldaf,*), b(ldb,*)
           real(sp), intent(out) :: berr(*), ferr(*), work(*)
           real(sp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldaf<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPORFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_scopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_ssymv( uplo, n, -one, a, lda, x( 1_${ik}$, j ), 1_${ik}$, one,work( n+1 ), 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    do i = 1, k - 1
                       work( i ) = work( i ) + abs( a( i, k ) )*xk
                       s = s + abs( a( i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + abs( a( k, k ) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( a( k, k ) )*xk
                    do i = k + 1, n
                       work( i ) = work( i ) + abs( a( i, k ) )*xk
                       s = s + abs( a( i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_spotrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                 call stdlib${ii}$_saxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_slacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_slacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_spotrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                    call stdlib${ii}$_spotrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_sporfs

     pure module subroutine stdlib${ii}$_dporfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x,ldx, ferr, berr, &
     !! DPORFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite,
     !! and provides error bounds and backward error estimates for the
     !! solution.
               work, iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(in) :: a(lda,*), af(ldaf,*), b(ldb,*)
           real(dp), intent(out) :: berr(*), ferr(*), work(*)
           real(dp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldaf<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPORFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_dcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_dsymv( uplo, n, -one, a, lda, x( 1_${ik}$, j ), 1_${ik}$, one,work( n+1 ), 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    do i = 1, k - 1
                       work( i ) = work( i ) + abs( a( i, k ) )*xk
                       s = s + abs( a( i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + abs( a( k, k ) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( a( k, k ) )*xk
                    do i = k + 1, n
                       work( i ) = work( i ) + abs( a( i, k ) )*xk
                       s = s + abs( a( i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_dpotrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                 call stdlib${ii}$_daxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_dlacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_dlacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_dpotrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                    call stdlib${ii}$_dpotrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_dporfs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$porfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x,ldx, ferr, berr, &
     !! DPORFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite,
     !! and provides error bounds and backward error estimates for the
     !! solution.
               work, iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(in) :: a(lda,*), af(ldaf,*), b(ldb,*)
           real(${rk}$), intent(out) :: berr(*), ferr(*), work(*)
           real(${rk}$), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, nz
           real(${rk}$) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldaf<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPORFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_${ri}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_${ri}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_${ri}$symv( uplo, n, -one, a, lda, x( 1_${ik}$, j ), 1_${ik}$, one,work( n+1 ), 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    do i = 1, k - 1
                       work( i ) = work( i ) + abs( a( i, k ) )*xk
                       s = s + abs( a( i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + abs( a( k, k ) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( a( k, k ) )*xk
                    do i = k + 1, n
                       work( i ) = work( i ) + abs( a( i, k ) )*xk
                       s = s + abs( a( i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ri}$potrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                 call stdlib${ii}$_${ri}$axpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_${ri}$lacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_${ri}$lacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_${ri}$potrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                    call stdlib${ii}$_${ri}$potrs( uplo, n, 1_${ik}$, af, ldaf, work( n+1 ), n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_${ri}$porfs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cporfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x,ldx, ferr, berr, &
     !! CPORFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite,
     !! and provides error bounds and backward error estimates for the
     !! solution.
               work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs
           ! Array Arguments 
           real(sp), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(sp), intent(in) :: a(lda,*), af(ldaf,*), b(ldb,*)
           complex(sp), intent(out) :: work(*)
           complex(sp), intent(inout) :: x(ldx,*)
        ! ====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(sp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldaf<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPORFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_ccopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_chemv( uplo, n, -cone, a, lda, x( 1_${ik}$, j ), 1_${ik}$, cone, work, 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    do i = 1, k - 1
                       rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk
                       s = s + cabs1( a( i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + abs( real( a( k, k ),KIND=sp) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( a( k, k ),KIND=sp) )*xk
                    do i = k + 1, n
                       rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk
                       s = s + cabs1( a( i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_cpotrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                 call stdlib${ii}$_caxpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_clacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_clacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_cpotrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_cpotrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_cporfs

     pure module subroutine stdlib${ii}$_zporfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x,ldx, ferr, berr, &
     !! ZPORFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite,
     !! and provides error bounds and backward error estimates for the
     !! solution.
               work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs
           ! Array Arguments 
           real(dp), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(dp), intent(in) :: a(lda,*), af(ldaf,*), b(ldb,*)
           complex(dp), intent(out) :: work(*)
           complex(dp), intent(inout) :: x(ldx,*)
        ! ====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(dp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldaf<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPORFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_zcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_zhemv( uplo, n, -cone, a, lda, x( 1_${ik}$, j ), 1_${ik}$, cone, work, 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    do i = 1, k - 1
                       rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk
                       s = s + cabs1( a( i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + abs( real( a( k, k ),KIND=dp) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( a( k, k ),KIND=dp) )*xk
                    do i = k + 1, n
                       rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk
                       s = s + cabs1( a( i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_zpotrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                 call stdlib${ii}$_zaxpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_zlacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_zpotrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_zpotrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_zporfs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$porfs( uplo, n, nrhs, a, lda, af, ldaf, b, ldb, x,ldx, ferr, berr, &
     !! ZPORFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite,
     !! and provides error bounds and backward error estimates for the
     !! solution.
               work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs
           ! Array Arguments 
           real(${ck}$), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(${ck}$), intent(in) :: a(lda,*), af(ldaf,*), b(ldb,*)
           complex(${ck}$), intent(out) :: work(*)
           complex(${ck}$), intent(inout) :: x(ldx,*)
        ! ====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, nz
           real(${ck}$) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(${ck}$) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -5_${ik}$
           else if( ldaf<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPORFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_${ci}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_${ci}$hemv( uplo, n, -cone, a, lda, x( 1_${ik}$, j ), 1_${ik}$, cone, work, 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    do i = 1, k - 1
                       rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk
                       s = s + cabs1( a( i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + abs( real( a( k, k ),KIND=${ck}$) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( a( k, k ),KIND=${ck}$) )*xk
                    do i = k + 1, n
                       rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk
                       s = s + cabs1( a( i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ci}$potrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                 call stdlib${ii}$_${ci}$axpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_${ci}$lacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_${ci}$potrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_${ci}$potrs( uplo, n, 1_${ik}$, af, ldaf, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_${ci}$porfs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spoequ( n, a, lda, s, scond, amax, info )
     !! SPOEQU computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*)
           real(sp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(sp) :: smin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPOEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = a( i, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_spoequ

     pure module subroutine stdlib${ii}$_dpoequ( n, a, lda, s, scond, amax, info )
     !! DPOEQU computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*)
           real(dp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(dp) :: smin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = a( i, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_dpoequ

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$poequ( n, a, lda, s, scond, amax, info )
     !! DPOEQU: computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(${rk}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*)
           real(${rk}$), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(${rk}$) :: smin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = a( i, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$poequ

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpoequ( n, a, lda, s, scond, amax, info )
     !! CPOEQU computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(out) :: s(*)
           complex(sp), intent(in) :: a(lda,*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(sp) :: smin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPOEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=sp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = real( a( i, i ),KIND=sp)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_cpoequ

     pure module subroutine stdlib${ii}$_zpoequ( n, a, lda, s, scond, amax, info )
     !! ZPOEQU computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(out) :: s(*)
           complex(dp), intent(in) :: a(lda,*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(dp) :: smin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=dp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = real( a( i, i ),KIND=dp)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_zpoequ

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$poequ( n, a, lda, s, scond, amax, info )
     !! ZPOEQU: computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(${ck}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(out) :: s(*)
           complex(${ck}$), intent(in) :: a(lda,*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(${ck}$) :: smin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=${ck}$)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = real( a( i, i ),KIND=${ck}$)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ci}$poequ

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spoequb( n, a, lda, s, scond, amax, info )
     !! SPOEQUB computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
     !! This routine differs from SPOEQU by restricting the scaling factors
     !! to a power of the radix.  Barring over- and underflow, scaling by
     !! these factors introduces no additional rounding errors.  However, the
     !! scaled diagonal entries are no longer approximately 1 but lie
     !! between sqrt(radix) and 1/sqrt(radix).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*)
           real(sp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(sp) :: smin, base, tmp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           ! positive definite only performs 1 pass of equilibration.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPOEQUB', -info )
              return
           end if
           ! quick return if possible.
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           base = stdlib${ii}$_slamch( 'B' )
           tmp = -0.5_sp / log ( base )
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = a( i, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = base ** int( tmp * log( s( i ) ),KIND=${ik}$)
              end do
              ! compute scond = min(s(i)) / max(s(i)).
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_spoequb

     pure module subroutine stdlib${ii}$_dpoequb( n, a, lda, s, scond, amax, info )
     !! DPOEQUB computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
     !! This routine differs from DPOEQU by restricting the scaling factors
     !! to a power of the radix.  Barring over- and underflow, scaling by
     !! these factors introduces no additional rounding errors.  However, the
     !! scaled diagonal entries are no longer approximately 1 but lie
     !! between sqrt(radix) and 1/sqrt(radix).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*)
           real(dp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(dp) :: smin, base, tmp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           ! positive definite only performs 1 pass of equilibration.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOEQUB', -info )
              return
           end if
           ! quick return if possible.
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           base = stdlib${ii}$_dlamch( 'B' )
           tmp = -0.5e+0_dp / log ( base )
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = a( i, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = base ** int( tmp * log( s( i ) ),KIND=${ik}$)
              end do
              ! compute scond = min(s(i)) / max(s(i)).
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_dpoequb

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$poequb( n, a, lda, s, scond, amax, info )
     !! DPOEQUB: computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
     !! This routine differs from DPOEQU by restricting the scaling factors
     !! to a power of the radix.  Barring over- and underflow, scaling by
     !! these factors introduces no additional rounding errors.  However, the
     !! scaled diagonal entries are no longer approximately 1 but lie
     !! between sqrt(radix) and 1/sqrt(radix).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(${rk}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*)
           real(${rk}$), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(${rk}$) :: smin, base, tmp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           ! positive definite only performs 1 pass of equilibration.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPOEQUB', -info )
              return
           end if
           ! quick return if possible.
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           base = stdlib${ii}$_${ri}$lamch( 'B' )
           tmp = -0.5e+0_${rk}$ / log ( base )
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = a( 1_${ik}$, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = a( i, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = base ** int( tmp * log( s( i ) ),KIND=${ik}$)
              end do
              ! compute scond = min(s(i)) / max(s(i)).
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$poequb

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpoequb( n, a, lda, s, scond, amax, info )
     !! CPOEQUB computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
     !! This routine differs from CPOEQU by restricting the scaling factors
     !! to a power of the radix.  Barring over- and underflow, scaling by
     !! these factors introduces no additional rounding errors.  However, the
     !! scaled diagonal entries are no longer approximately 1 but lie
     !! between sqrt(radix) and 1/sqrt(radix).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           complex(sp), intent(in) :: a(lda,*)
           real(sp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(sp) :: smin, base, tmp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           ! positive definite only performs 1 pass of equilibration.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPOEQUB', -info )
              return
           end if
           ! quick return if possible.
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           base = stdlib${ii}$_slamch( 'B' )
           tmp = -0.5_sp / log ( base )
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=sp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = real( a( i, i ),KIND=sp)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = base ** int( tmp * log( s( i ) ),KIND=${ik}$)
              end do
              ! compute scond = min(s(i)) / max(s(i)).
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_cpoequb

     pure module subroutine stdlib${ii}$_zpoequb( n, a, lda, s, scond, amax, info )
     !! ZPOEQUB computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
     !! This routine differs from ZPOEQU by restricting the scaling factors
     !! to a power of the radix.  Barring over- and underflow, scaling by
     !! these factors introduces no additional rounding errors.  However, the
     !! scaled diagonal entries are no longer approximately 1 but lie
     !! between sqrt(radix) and 1/sqrt(radix).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           complex(dp), intent(in) :: a(lda,*)
           real(dp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(dp) :: smin, base, tmp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           ! positive definite only performs 1 pass of equilibration.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOEQUB', -info )
              return
           end if
           ! quick return if possible.
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           base = stdlib${ii}$_dlamch( 'B' )
           tmp = -0.5e+0_dp / log ( base )
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=dp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = real( a( i, i ),KIND=dp)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = base ** int( tmp * log( s( i ) ),KIND=${ik}$)
              end do
              ! compute scond = min(s(i)) / max(s(i)).
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_zpoequb

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$poequb( n, a, lda, s, scond, amax, info )
     !! ZPOEQUB: computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A and reduce its condition number
     !! (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
     !! This routine differs from ZPOEQU by restricting the scaling factors
     !! to a power of the radix.  Barring over- and underflow, scaling by
     !! these factors introduces no additional rounding errors.  However, the
     !! scaled diagonal entries are no longer approximately 1 but lie
     !! between sqrt(radix) and 1/sqrt(radix).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: lda, n
           real(${ck}$), intent(out) :: amax, scond
           ! Array Arguments 
           complex(${ck}$), intent(in) :: a(lda,*)
           real(${ck}$), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i
           real(${ck}$) :: smin, base, tmp
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           ! positive definite only performs 1 pass of equilibration.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( lda<max( 1_${ik}$, n ) ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPOEQUB', -info )
              return
           end if
           ! quick return if possible.
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           base = stdlib${ii}$_${c2ri(ci)}$lamch( 'B' )
           tmp = -0.5e+0_${ck}$ / log ( base )
           ! find the minimum and maximum diagonal elements.
           s( 1_${ik}$ ) = real( a( 1_${ik}$, 1_${ik}$ ),KIND=${ck}$)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           do i = 2, n
              s( i ) = real( a( i, i ),KIND=${ck}$)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = base ** int( tmp * log( s( i ) ),KIND=${ik}$)
              end do
              ! compute scond = min(s(i)) / max(s(i)).
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ci}$poequb

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_claqhe( uplo, n, a, lda, s, scond, amax, equed )
     !! CLAQHE equilibrates a Hermitian matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: lda, n
           real(sp), intent(in) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: s(*)
           complex(sp), intent(inout) :: a(lda,*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: thresh = 0.1e+0_sp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(sp) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_slamch( 'SAFE MINIMUM' ) / stdlib${ii}$_slamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j - 1
                       a( i, j ) = cj*s( i )*a( i, j )
                    end do
                    a( j, j ) = cj*cj*real( a( j, j ),KIND=sp)
                 end do
              else
                 ! lower triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    a( j, j ) = cj*cj*real( a( j, j ),KIND=sp)
                    do i = j + 1, n
                       a( i, j ) = cj*s( i )*a( i, j )
                    end do
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_claqhe

     pure module subroutine stdlib${ii}$_zlaqhe( uplo, n, a, lda, s, scond, amax, equed )
     !! ZLAQHE equilibrates a Hermitian matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: lda, n
           real(dp), intent(in) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: s(*)
           complex(dp), intent(inout) :: a(lda,*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: thresh = 0.1e+0_dp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(dp) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_dlamch( 'SAFE MINIMUM' ) / stdlib${ii}$_dlamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j - 1
                       a( i, j ) = cj*s( i )*a( i, j )
                    end do
                    a( j, j ) = cj*cj*real( a( j, j ),KIND=dp)
                 end do
              else
                 ! lower triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    a( j, j ) = cj*cj*real( a( j, j ),KIND=dp)
                    do i = j + 1, n
                       a( i, j ) = cj*s( i )*a( i, j )
                    end do
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_zlaqhe

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$laqhe( uplo, n, a, lda, s, scond, amax, equed )
     !! ZLAQHE: equilibrates a Hermitian matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: lda, n
           real(${ck}$), intent(in) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(in) :: s(*)
           complex(${ck}$), intent(inout) :: a(lda,*)
        ! =====================================================================
           ! Parameters 
           real(${ck}$), parameter :: thresh = 0.1e+0_${ck}$
           
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(${ck}$) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' ) / stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j - 1
                       a( i, j ) = cj*s( i )*a( i, j )
                    end do
                    a( j, j ) = cj*cj*real( a( j, j ),KIND=${ck}$)
                 end do
              else
                 ! lower triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    a( j, j ) = cj*cj*real( a( j, j ),KIND=${ck}$)
                    do i = j + 1, n
                       a( i, j ) = cj*s( i )*a( i, j )
                    end do
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_${ci}$laqhe

#:endif
#:endfor



     real(sp) module function stdlib${ii}$_sla_porcond( uplo, n, a, lda, af, ldaf, cmode, c,info, work, iwork )
     !! SLA_PORCOND Estimates the Skeel condition number of  op(A) * op2(C)
     !! where op2 is determined by CMODE as follows
     !! CMODE =  1    op2(C) = C
     !! CMODE =  0    op2(C) = I
     !! CMODE = -1    op2(C) = inv(C)
     !! The Skeel condition number  cond(A) = norminf( |inv(A)||A| )
     !! is computed by computing scaling factors R such that
     !! diag(R)*A*op2(C) is row equilibrated and computing the standard
     !! infinity-norm condition number.
               
        ! -- 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(in) :: n, lda, ldaf, cmode
           integer(${ik}$), intent(out) :: info
           real(sp), intent(in) :: a(lda,*), af(ldaf,*), c(*)
           real(sp), intent(out) :: work(*)
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: kase, i, j
           real(sp) :: ainvnm, tmp
           logical(lk) :: up
           ! Array Arguments 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           stdlib${ii}$_sla_porcond = zero
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -2_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SLA_PORCOND', -info )
              return
           end if
           if( n==0_${ik}$ ) then
              stdlib${ii}$_sla_porcond = one
              return
           end if
           up = .false.
           if ( stdlib_lsame( uplo, 'U' ) ) up = .true.
           ! compute the equilibration matrix r such that
           ! inv(r)*a*c has unit 1-norm.
           if ( up ) then
              do i = 1, n
                 tmp = zero
                 if ( cmode == 1_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( j, i ) * c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) * c( j ) )
                    end do
                 else if ( cmode == 0_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( j, i ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) )
                    end do
                 else
                    do j = 1, i
                       tmp = tmp + abs( a( j ,i ) / c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) / c( j ) )
                    end do
                 end if
                 work( 2_${ik}$*n+i ) = tmp
              end do
           else
              do i = 1, n
                 tmp = zero
                 if ( cmode == 1_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) * c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) * c( j ) )
                    end do
                 else if ( cmode == 0_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) )
                    end do
                 else
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) / c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) / c( j ) )
                    end do
                 end if
                 work( 2_${ik}$*n+i ) = tmp
              end do
           endif
           ! estimate the norm of inv(op(a)).
           ainvnm = zero
           kase = 0_${ik}$
           10 continue
           call stdlib${ii}$_slacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( kase==2_${ik}$ ) then
                 ! multiply by r.
                 do i = 1, n
                    work( i ) = work( i ) * work( 2_${ik}$*n+i )
                 end do
                 if (up) then
                    call stdlib${ii}$_spotrs( 'UPPER', n, 1_${ik}$, af, ldaf, work, n, info )
                 else
                    call stdlib${ii}$_spotrs( 'LOWER', n, 1_${ik}$, af, ldaf, work, n, info )
                 endif
                 ! multiply by inv(c).
                 if ( cmode == 1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) / c( i )
                    end do
                 else if ( cmode == -1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) * c( i )
                    end do
                 end if
              else
                 ! multiply by inv(c**t).
                 if ( cmode == 1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) / c( i )
                    end do
                 else if ( cmode == -1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) * c( i )
                    end do
                 end if
                 if ( up ) then
                    call stdlib${ii}$_spotrs( 'UPPER', n, 1_${ik}$, af, ldaf, work, n, info )
                 else
                    call stdlib${ii}$_spotrs( 'LOWER', n, 1_${ik}$, af, ldaf, work, n, info )
                 endif
                 ! multiply by r.
                 do i = 1, n
                    work( i ) = work( i ) * work( 2_${ik}$*n+i )
                 end do
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm /= 0.0_sp )stdlib${ii}$_sla_porcond = ( one / ainvnm )
           return
     end function stdlib${ii}$_sla_porcond

     real(dp) module function stdlib${ii}$_dla_porcond( uplo, n, a, lda, af, ldaf,cmode, c, info, work,iwork )
     !! DLA_PORCOND Estimates the Skeel condition number of  op(A) * op2(C)
     !! where op2 is determined by CMODE as follows
     !! CMODE =  1    op2(C) = C
     !! CMODE =  0    op2(C) = I
     !! CMODE = -1    op2(C) = inv(C)
     !! The Skeel condition number  cond(A) = norminf( |inv(A)||A| )
     !! is computed by computing scaling factors R such that
     !! diag(R)*A*op2(C) is row equilibrated and computing the standard
     !! infinity-norm condition number.
               
        ! -- 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(in) :: n, lda, ldaf, cmode
           integer(${ik}$), intent(out) :: info
           real(dp), intent(in) :: a(lda,*), af(ldaf,*), c(*)
           real(dp), intent(out) :: work(*)
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: kase, i, j
           real(dp) :: ainvnm, tmp
           logical(lk) :: up
           ! Array Arguments 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           stdlib${ii}$_dla_porcond = zero
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -2_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DLA_PORCOND', -info )
              return
           end if
           if( n==0_${ik}$ ) then
              stdlib${ii}$_dla_porcond = one
              return
           end if
           up = .false.
           if ( stdlib_lsame( uplo, 'U' ) ) up = .true.
           ! compute the equilibration matrix r such that
           ! inv(r)*a*c has unit 1-norm.
           if ( up ) then
              do i = 1, n
                 tmp = zero
                 if ( cmode == 1_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( j, i ) * c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) * c( j ) )
                    end do
                 else if ( cmode == 0_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( j, i ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) )
                    end do
                 else
                    do j = 1, i
                       tmp = tmp + abs( a( j ,i ) / c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) / c( j ) )
                    end do
                 end if
                 work( 2_${ik}$*n+i ) = tmp
              end do
           else
              do i = 1, n
                 tmp = zero
                 if ( cmode == 1_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) * c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) * c( j ) )
                    end do
                 else if ( cmode == 0_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) )
                    end do
                 else
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) / c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) / c( j ) )
                    end do
                 end if
                 work( 2_${ik}$*n+i ) = tmp
              end do
           endif
           ! estimate the norm of inv(op(a)).
           ainvnm = zero
           kase = 0_${ik}$
           10 continue
           call stdlib${ii}$_dlacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( kase==2_${ik}$ ) then
                 ! multiply by r.
                 do i = 1, n
                    work( i ) = work( i ) * work( 2_${ik}$*n+i )
                 end do
                 if (up) then
                    call stdlib${ii}$_dpotrs( 'UPPER', n, 1_${ik}$, af, ldaf, work, n, info )
                 else
                    call stdlib${ii}$_dpotrs( 'LOWER', n, 1_${ik}$, af, ldaf, work, n, info )
                 endif
                 ! multiply by inv(c).
                 if ( cmode == 1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) / c( i )
                    end do
                 else if ( cmode == -1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) * c( i )
                    end do
                 end if
              else
                 ! multiply by inv(c**t).
                 if ( cmode == 1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) / c( i )
                    end do
                 else if ( cmode == -1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) * c( i )
                    end do
                 end if
                 if ( up ) then
                    call stdlib${ii}$_dpotrs( 'UPPER', n, 1_${ik}$, af, ldaf, work, n, info )
                 else
                    call stdlib${ii}$_dpotrs( 'LOWER', n, 1_${ik}$, af, ldaf, work, n, info )
                 endif
                 ! multiply by r.
                 do i = 1, n
                    work( i ) = work( i ) * work( 2_${ik}$*n+i )
                 end do
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm /= zero )stdlib${ii}$_dla_porcond = ( one / ainvnm )
           return
     end function stdlib${ii}$_dla_porcond

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     real(${rk}$) module function stdlib${ii}$_${ri}$la_porcond( uplo, n, a, lda, af, ldaf,cmode, c, info, work,iwork )
     !! DLA_PORCOND: Estimates the Skeel condition number of  op(A) * op2(C)
     !! where op2 is determined by CMODE as follows
     !! CMODE =  1    op2(C) = C
     !! CMODE =  0    op2(C) = I
     !! CMODE = -1    op2(C) = inv(C)
     !! The Skeel condition number  cond(A) = norminf( |inv(A)||A| )
     !! is computed by computing scaling factors R such that
     !! diag(R)*A*op2(C) is row equilibrated and computing the standard
     !! infinity-norm condition number.
               
        ! -- 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(in) :: n, lda, ldaf, cmode
           integer(${ik}$), intent(out) :: info
           real(${rk}$), intent(in) :: a(lda,*), af(ldaf,*), c(*)
           real(${rk}$), intent(out) :: work(*)
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: kase, i, j
           real(${rk}$) :: ainvnm, tmp
           logical(lk) :: up
           ! Array Arguments 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Executable Statements 
           stdlib${ii}$_${ri}$la_porcond = zero
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -2_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DLA_PORCOND', -info )
              return
           end if
           if( n==0_${ik}$ ) then
              stdlib${ii}$_${ri}$la_porcond = one
              return
           end if
           up = .false.
           if ( stdlib_lsame( uplo, 'U' ) ) up = .true.
           ! compute the equilibration matrix r such that
           ! inv(r)*a*c has unit 1-norm.
           if ( up ) then
              do i = 1, n
                 tmp = zero
                 if ( cmode == 1_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( j, i ) * c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) * c( j ) )
                    end do
                 else if ( cmode == 0_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( j, i ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) )
                    end do
                 else
                    do j = 1, i
                       tmp = tmp + abs( a( j ,i ) / c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( i, j ) / c( j ) )
                    end do
                 end if
                 work( 2_${ik}$*n+i ) = tmp
              end do
           else
              do i = 1, n
                 tmp = zero
                 if ( cmode == 1_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) * c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) * c( j ) )
                    end do
                 else if ( cmode == 0_${ik}$ ) then
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) )
                    end do
                 else
                    do j = 1, i
                       tmp = tmp + abs( a( i, j ) / c( j ) )
                    end do
                    do j = i+1, n
                       tmp = tmp + abs( a( j, i ) / c( j ) )
                    end do
                 end if
                 work( 2_${ik}$*n+i ) = tmp
              end do
           endif
           ! estimate the norm of inv(op(a)).
           ainvnm = zero
           kase = 0_${ik}$
           10 continue
           call stdlib${ii}$_${ri}$lacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( kase==2_${ik}$ ) then
                 ! multiply by r.
                 do i = 1, n
                    work( i ) = work( i ) * work( 2_${ik}$*n+i )
                 end do
                 if (up) then
                    call stdlib${ii}$_${ri}$potrs( 'UPPER', n, 1_${ik}$, af, ldaf, work, n, info )
                 else
                    call stdlib${ii}$_${ri}$potrs( 'LOWER', n, 1_${ik}$, af, ldaf, work, n, info )
                 endif
                 ! multiply by inv(c).
                 if ( cmode == 1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) / c( i )
                    end do
                 else if ( cmode == -1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) * c( i )
                    end do
                 end if
              else
                 ! multiply by inv(c**t).
                 if ( cmode == 1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) / c( i )
                    end do
                 else if ( cmode == -1_${ik}$ ) then
                    do i = 1, n
                       work( i ) = work( i ) * c( i )
                    end do
                 end if
                 if ( up ) then
                    call stdlib${ii}$_${ri}$potrs( 'UPPER', n, 1_${ik}$, af, ldaf, work, n, info )
                 else
                    call stdlib${ii}$_${ri}$potrs( 'LOWER', n, 1_${ik}$, af, ldaf, work, n, info )
                 endif
                 ! multiply by r.
                 do i = 1, n
                    work( i ) = work( i ) * work( 2_${ik}$*n+i )
                 end do
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm /= zero )stdlib${ii}$_${ri}$la_porcond = ( one / ainvnm )
           return
     end function stdlib${ii}$_${ri}$la_porcond

#:endif
#:endfor



     real(sp) module function stdlib${ii}$_sla_porpvgrw( uplo, ncols, a, lda, af, ldaf, work )
     !! SLA_PORPVGRW computes the reciprocal pivot growth factor
     !! norm(A)/norm(U). The "max absolute element" norm is used. If this is
     !! much less than 1, the stability of the LU factorization of the
     !! (equilibrated) matrix A could be poor. This also means that the
     !! solution X, estimated condition numbers, and error bounds could be
     !! unreliable.
        ! -- 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(in) :: ncols, lda, ldaf
           ! Array Arguments 
           real(sp), intent(in) :: a(lda,*), af(ldaf,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(sp) :: amax, umax, rpvgrw
           logical(lk) :: upper
           ! Intrinsic Functions 
           ! Executable Statements 
           upper = stdlib_lsame( 'UPPER', uplo )
           ! stdlib${ii}$_spotrf will have factored only the ncolsxncols leading minor, so
           ! we restrict the growth search to that minor and use only the first
           ! 2*ncols workspace entries.
           rpvgrw = one
           do i = 1, 2*ncols
              work( i ) = zero
           end do
           ! find the max magnitude entry of each column.
           if ( upper ) then
              do j = 1, ncols
                 do i = 1, j
                    work( ncols+j ) =max( abs( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( ncols+j ) =max( abs( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           end if
           ! now find the max magnitude entry of each column of the factor in
           ! af.  no pivoting, so no permutations.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do j = 1, ncols
                 do i = 1, j
                    work( j ) = max( abs( af( i, j ) ), work( j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( j ) = max( abs( af( i, j ) ), work( j ) )
                 end do
              end do
           end if
           ! compute the *inverse* of the max element growth factor.  dividing
           ! by zero would imply the largest entry of the factor's column is
           ! zero.  than can happen when either the column of a is zero or
           ! massive pivots made the factor underflow to zero.  neither counts
           ! as growth in itself, so simply ignore terms with zero
           ! denominators.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= 0.0_sp ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           else
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= 0.0_sp ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           end if
           stdlib${ii}$_sla_porpvgrw = rpvgrw
     end function stdlib${ii}$_sla_porpvgrw

     real(dp) module function stdlib${ii}$_dla_porpvgrw( uplo, ncols, a, lda, af,ldaf, work )
     !! DLA_PORPVGRW computes the reciprocal pivot growth factor
     !! norm(A)/norm(U). The "max absolute element" norm is used. If this is
     !! much less than 1, the stability of the LU factorization of the
     !! (equilibrated) matrix A could be poor. This also means that the
     !! solution X, estimated condition numbers, and error bounds could be
     !! unreliable.
        ! -- 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(in) :: ncols, lda, ldaf
           ! Array Arguments 
           real(dp), intent(in) :: a(lda,*), af(ldaf,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(dp) :: amax, umax, rpvgrw
           logical(lk) :: upper
           ! Intrinsic Functions 
           ! Executable Statements 
           upper = stdlib_lsame( 'UPPER', uplo )
           ! stdlib${ii}$_dpotrf will have factored only the ncolsxncols leading minor, so
           ! we restrict the growth search to that minor and use only the first
           ! 2*ncols workspace entries.
           rpvgrw = one
           do i = 1, 2*ncols
              work( i ) = zero
           end do
           ! find the max magnitude entry of each column.
           if ( upper ) then
              do j = 1, ncols
                 do i = 1, j
                    work( ncols+j ) =max( abs( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( ncols+j ) =max( abs( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           end if
           ! now find the max magnitude entry of each column of the factor in
           ! af.  no pivoting, so no permutations.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do j = 1, ncols
                 do i = 1, j
                    work( j ) = max( abs( af( i, j ) ), work( j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( j ) = max( abs( af( i, j ) ), work( j ) )
                 end do
              end do
           end if
           ! compute the *inverse* of the max element growth factor.  dividing
           ! by zero would imply the largest entry of the factor's column is
           ! zero.  than can happen when either the column of a is zero or
           ! massive pivots made the factor underflow to zero.  neither counts
           ! as growth in itself, so simply ignore terms with zero
           ! denominators.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           else
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           end if
           stdlib${ii}$_dla_porpvgrw = rpvgrw
     end function stdlib${ii}$_dla_porpvgrw

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     real(${rk}$) module function stdlib${ii}$_${ri}$la_porpvgrw( uplo, ncols, a, lda, af,ldaf, work )
     !! DLA_PORPVGRW: computes the reciprocal pivot growth factor
     !! norm(A)/norm(U). The "max absolute element" norm is used. If this is
     !! much less than 1, the stability of the LU factorization of the
     !! (equilibrated) matrix A could be poor. This also means that the
     !! solution X, estimated condition numbers, and error bounds could be
     !! unreliable.
        ! -- 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(in) :: ncols, lda, ldaf
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(lda,*), af(ldaf,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(${rk}$) :: amax, umax, rpvgrw
           logical(lk) :: upper
           ! Intrinsic Functions 
           ! Executable Statements 
           upper = stdlib_lsame( 'UPPER', uplo )
           ! stdlib${ii}$_${ri}$potrf will have factored only the ncolsxncols leading minor, so
           ! we restrict the growth search to that minor and use only the first
           ! 2*ncols workspace entries.
           rpvgrw = one
           do i = 1, 2*ncols
              work( i ) = zero
           end do
           ! find the max magnitude entry of each column.
           if ( upper ) then
              do j = 1, ncols
                 do i = 1, j
                    work( ncols+j ) =max( abs( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( ncols+j ) =max( abs( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           end if
           ! now find the max magnitude entry of each column of the factor in
           ! af.  no pivoting, so no permutations.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do j = 1, ncols
                 do i = 1, j
                    work( j ) = max( abs( af( i, j ) ), work( j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( j ) = max( abs( af( i, j ) ), work( j ) )
                 end do
              end do
           end if
           ! compute the *inverse* of the max element growth factor.  dividing
           ! by zero would imply the largest entry of the factor's column is
           ! zero.  than can happen when either the column of a is zero or
           ! massive pivots made the factor underflow to zero.  neither counts
           ! as growth in itself, so simply ignore terms with zero
           ! denominators.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           else
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           end if
           stdlib${ii}$_${ri}$la_porpvgrw = rpvgrw
     end function stdlib${ii}$_${ri}$la_porpvgrw

#:endif
#:endfor

     real(sp) module function stdlib${ii}$_cla_porpvgrw( uplo, ncols, a, lda, af, ldaf, work )
     !! CLA_PORPVGRW computes the reciprocal pivot growth factor
     !! norm(A)/norm(U). The "max absolute element" norm is used. If this is
     !! much less than 1, the stability of the LU factorization of the
     !! (equilibrated) matrix A could be poor. This also means that the
     !! solution X, estimated condition numbers, and error bounds could be
     !! unreliable.
        ! -- 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(in) :: ncols, lda, ldaf
           ! Array Arguments 
           complex(sp), intent(in) :: a(lda,*), af(ldaf,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(sp) :: amax, umax, rpvgrw
           logical(lk) :: upper
           complex(sp) :: zdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! Executable Statements 
           upper = stdlib_lsame( 'UPPER', uplo )
           ! stdlib${ii}$_spotrf will have factored only the ncolsxncols leading minor, so
           ! we restrict the growth search to that minor and use only the first
           ! 2*ncols workspace entries.
           rpvgrw = one
           do i = 1, 2*ncols
              work( i ) = zero
           end do
           ! find the max magnitude entry of each column.
           if ( upper ) then
              do j = 1, ncols
                 do i = 1, j
                    work( ncols+j ) =max( cabs1( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( ncols+j ) =max( cabs1( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           end if
           ! now find the max magnitude entry of each column of the factor in
           ! af.  no pivoting, so no permutations.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do j = 1, ncols
                 do i = 1, j
                    work( j ) = max( cabs1( af( i, j ) ), work( j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( j ) = max( cabs1( af( i, j ) ), work( j ) )
                 end do
              end do
           end if
           ! compute the *inverse* of the max element growth factor.  dividing
           ! by zero would imply the largest entry of the factor's column is
           ! zero.  than can happen when either the column of a is zero or
           ! massive pivots made the factor underflow to zero.  neither counts
           ! as growth in itself, so simply ignore terms with zero
           ! denominators.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= 0.0_sp ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           else
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= 0.0_sp ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           end if
           stdlib${ii}$_cla_porpvgrw = rpvgrw
     end function stdlib${ii}$_cla_porpvgrw

     real(dp) module function stdlib${ii}$_zla_porpvgrw( uplo, ncols, a, lda, af,ldaf, work )
     !! ZLA_PORPVGRW computes the reciprocal pivot growth factor
     !! norm(A)/norm(U). The "max absolute element" norm is used. If this is
     !! much less than 1, the stability of the LU factorization of the
     !! (equilibrated) matrix A could be poor. This also means that the
     !! solution X, estimated condition numbers, and error bounds could be
     !! unreliable.
        ! -- 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(in) :: ncols, lda, ldaf
           ! Array Arguments 
           complex(dp), intent(in) :: a(lda,*), af(ldaf,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(dp) :: amax, umax, rpvgrw
           logical(lk) :: upper
           complex(dp) :: zdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! Executable Statements 
           upper = stdlib_lsame( 'UPPER', uplo )
           ! stdlib${ii}$_dpotrf will have factored only the ncolsxncols leading minor, so
           ! we restrict the growth search to that minor and use only the first
           ! 2*ncols workspace entries.
           rpvgrw = one
           do i = 1, 2*ncols
              work( i ) = zero
           end do
           ! find the max magnitude entry of each column.
           if ( upper ) then
              do j = 1, ncols
                 do i = 1, j
                    work( ncols+j ) =max( cabs1( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( ncols+j ) =max( cabs1( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           end if
           ! now find the max magnitude entry of each column of the factor in
           ! af.  no pivoting, so no permutations.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do j = 1, ncols
                 do i = 1, j
                    work( j ) = max( cabs1( af( i, j ) ), work( j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( j ) = max( cabs1( af( i, j ) ), work( j ) )
                 end do
              end do
           end if
           ! compute the *inverse* of the max element growth factor.  dividing
           ! by zero would imply the largest entry of the factor's column is
           ! zero.  than can happen when either the column of a is zero or
           ! massive pivots made the factor underflow to zero.  neither counts
           ! as growth in itself, so simply ignore terms with zero
           ! denominators.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           else
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           end if
           stdlib${ii}$_zla_porpvgrw = rpvgrw
     end function stdlib${ii}$_zla_porpvgrw

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     real(${ck}$) module function stdlib${ii}$_${ci}$la_porpvgrw( uplo, ncols, a, lda, af,ldaf, work )
     !! ZLA_PORPVGRW: computes the reciprocal pivot growth factor
     !! norm(A)/norm(U). The "max absolute element" norm is used. If this is
     !! much less than 1, the stability of the LU factorization of the
     !! (equilibrated) matrix A could be poor. This also means that the
     !! solution X, estimated condition numbers, and error bounds could be
     !! unreliable.
        ! -- 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(in) :: ncols, lda, ldaf
           ! Array Arguments 
           complex(${ck}$), intent(in) :: a(lda,*), af(ldaf,*)
           real(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(${ck}$) :: amax, umax, rpvgrw
           logical(lk) :: upper
           complex(${ck}$) :: zdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! Executable Statements 
           upper = stdlib_lsame( 'UPPER', uplo )
           ! stdlib${ii}$_${ci}$otrf will have factored only the ncolsxncols leading minor, so
           ! we restrict the growth search to that minor and use only the first
           ! 2*ncols workspace entries.
           rpvgrw = one
           do i = 1, 2*ncols
              work( i ) = zero
           end do
           ! find the max magnitude entry of each column.
           if ( upper ) then
              do j = 1, ncols
                 do i = 1, j
                    work( ncols+j ) =max( cabs1( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( ncols+j ) =max( cabs1( a( i, j ) ), work( ncols+j ) )
                 end do
              end do
           end if
           ! now find the max magnitude entry of each column of the factor in
           ! af.  no pivoting, so no permutations.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do j = 1, ncols
                 do i = 1, j
                    work( j ) = max( cabs1( af( i, j ) ), work( j ) )
                 end do
              end do
           else
              do j = 1, ncols
                 do i = j, ncols
                    work( j ) = max( cabs1( af( i, j ) ), work( j ) )
                 end do
              end do
           end if
           ! compute the *inverse* of the max element growth factor.  dividing
           ! by zero would imply the largest entry of the factor's column is
           ! zero.  than can happen when either the column of a is zero or
           ! massive pivots made the factor underflow to zero.  neither counts
           ! as growth in itself, so simply ignore terms with zero
           ! denominators.
           if ( stdlib_lsame( 'UPPER', uplo ) ) then
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           else
              do i = 1, ncols
                 umax = work( i )
                 amax = work( ncols+i )
                 if ( umax /= zero ) then
                    rpvgrw = min( amax / umax, rpvgrw )
                 end if
              end do
           end if
           stdlib${ii}$_${ci}$la_porpvgrw = rpvgrw
     end function stdlib${ii}$_${ci}$la_porpvgrw

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sppcon( uplo, n, ap, anorm, rcond, work, iwork, info )
     !! SPPCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite packed matrix using
     !! the Cholesky factorization A = U**T*U or A = L*L**T computed by
     !! SPPTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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) :: n
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(in) :: ap(*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(sp) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPPCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_slacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_slatps( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,ap, work, scalel,&
                            work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_slatps( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_slatps( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_slatps( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n,ap, work, scaleu,&
                            work( 2_${ik}$*n+1 ), info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_srscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_sppcon

     pure module subroutine stdlib${ii}$_dppcon( uplo, n, ap, anorm, rcond, work, iwork, info )
     !! DPPCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite packed matrix using
     !! the Cholesky factorization A = U**T*U or A = L*L**T computed by
     !! DPPTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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) :: n
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(in) :: ap(*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(dp) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_dlacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_dlatps( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,ap, work, scalel,&
                            work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_dlatps( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_dlatps( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_dlatps( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n,ap, work, scaleu,&
                            work( 2_${ik}$*n+1 ), info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_drscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_dppcon

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$ppcon( uplo, n, ap, anorm, rcond, work, iwork, info )
     !! DPPCON: estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite packed matrix using
     !! the Cholesky factorization A = U**T*U or A = L*L**T computed by
     !! DPPTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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) :: n
           real(${rk}$), intent(in) :: anorm
           real(${rk}$), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(in) :: ap(*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(${rk}$) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_${ri}$lacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_${ri}$latps( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,ap, work, scalel,&
                            work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_${ri}$latps( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scaleu, work( 2_${ik}$*n+1 ), info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_${ri}$latps( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scalel, work( 2_${ik}$*n+1 ), info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_${ri}$latps( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n,ap, work, scaleu,&
                            work( 2_${ik}$*n+1 ), info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_i${ri}$amax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_${ri}$rscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_${ri}$ppcon

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cppcon( uplo, n, ap, anorm, rcond, work, rwork, info )
     !! CPPCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite packed matrix using
     !! the Cholesky factorization A = U**H*U or A = L*L**H computed by
     !! CPPTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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) :: n
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(in) :: ap(*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(sp) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(sp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPPCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_clacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_clatps( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, ap, &
                           work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_clatps( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_clatps( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_clatps( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, ap, &
                           work, scaleu, rwork, info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_icamax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_csrscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_cppcon

     pure module subroutine stdlib${ii}$_zppcon( uplo, n, ap, anorm, rcond, work, rwork, info )
     !! ZPPCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite packed matrix using
     !! the Cholesky factorization A = U**H*U or A = L*L**H computed by
     !! ZPPTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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) :: n
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(in) :: ap(*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(dp) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(dp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_zlatps( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, ap, &
                           work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_zlatps( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_zlatps( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_zlatps( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, ap, &
                           work, scaleu, rwork, info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_izamax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_zdrscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_zppcon

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ppcon( uplo, n, ap, anorm, rcond, work, rwork, info )
     !! ZPPCON: estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite packed matrix using
     !! the Cholesky factorization A = U**H*U or A = L*L**H computed by
     !! ZPPTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- 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) :: n
           real(${ck}$), intent(in) :: anorm
           real(${ck}$), intent(out) :: rcond
           ! Array Arguments 
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(in) :: ap(*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(${ck}$) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(${ck}$) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_${ci}$latps( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, ap, &
                           work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_${ci}$latps( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_${ci}$latps( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,ap, work, &
                           scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_${ci}$latps( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, ap, &
                           work, scaleu, rwork, info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_i${ci}$amax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_${ci}$drscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_${ci}$ppcon

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spptrf( uplo, n, ap, info )
     !! SPPTRF computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A stored in packed format.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: n
           ! Array Arguments 
           real(sp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj
           real(sp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPPTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**t*u.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 ! compute elements 1:j-1 of column j.
                 if( j>1_${ik}$ )call stdlib${ii}$_stpsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', j-1, ap,ap( jc ), &
                           1_${ik}$ )
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = ap( jj ) - stdlib${ii}$_sdot( j-1, ap( jc ), 1_${ik}$, ap( jc ), 1_${ik}$ )
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ap( jj ) = sqrt( ajj )
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              jj = 1_${ik}$
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = ap( jj )
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ap( jj ) = ajj
                 ! compute elements j+1:n of column j and update the trailing
                 ! submatrix.
                 if( j<n ) then
                    call stdlib${ii}$_sscal( n-j, one / ajj, ap( jj+1 ), 1_${ik}$ )
                    call stdlib${ii}$_sspr( 'LOWER', n-j, -one, ap( jj+1 ), 1_${ik}$,ap( jj+n-j+1 ) )
                    jj = jj + n - j + 1_${ik}$
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_spptrf

     pure module subroutine stdlib${ii}$_dpptrf( uplo, n, ap, info )
     !! DPPTRF computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A stored in packed format.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: n
           ! Array Arguments 
           real(dp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj
           real(dp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**t*u.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 ! compute elements 1:j-1 of column j.
                 if( j>1_${ik}$ )call stdlib${ii}$_dtpsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', j-1, ap,ap( jc ), &
                           1_${ik}$ )
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = ap( jj ) - stdlib${ii}$_ddot( j-1, ap( jc ), 1_${ik}$, ap( jc ), 1_${ik}$ )
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ap( jj ) = sqrt( ajj )
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              jj = 1_${ik}$
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = ap( jj )
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ap( jj ) = ajj
                 ! compute elements j+1:n of column j and update the trailing
                 ! submatrix.
                 if( j<n ) then
                    call stdlib${ii}$_dscal( n-j, one / ajj, ap( jj+1 ), 1_${ik}$ )
                    call stdlib${ii}$_dspr( 'LOWER', n-j, -one, ap( jj+1 ), 1_${ik}$,ap( jj+n-j+1 ) )
                    jj = jj + n - j + 1_${ik}$
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_dpptrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pptrf( uplo, n, ap, info )
     !! DPPTRF: computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A stored in packed format.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj
           real(${rk}$) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**t*u.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 ! compute elements 1:j-1 of column j.
                 if( j>1_${ik}$ )call stdlib${ii}$_${ri}$tpsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', j-1, ap,ap( jc ), &
                           1_${ik}$ )
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = ap( jj ) - stdlib${ii}$_${ri}$dot( j-1, ap( jc ), 1_${ik}$, ap( jc ), 1_${ik}$ )
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ap( jj ) = sqrt( ajj )
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              jj = 1_${ik}$
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = ap( jj )
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ap( jj ) = ajj
                 ! compute elements j+1:n of column j and update the trailing
                 ! submatrix.
                 if( j<n ) then
                    call stdlib${ii}$_${ri}$scal( n-j, one / ajj, ap( jj+1 ), 1_${ik}$ )
                    call stdlib${ii}$_${ri}$spr( 'LOWER', n-j, -one, ap( jj+1 ), 1_${ik}$,ap( jj+n-j+1 ) )
                    jj = jj + n - j + 1_${ik}$
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_${ri}$pptrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpptrf( uplo, n, ap, info )
     !! CPPTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A stored in packed format.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: n
           ! Array Arguments 
           complex(sp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj
           real(sp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPPTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**h * u.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 ! compute elements 1:j-1 of column j.
                 if( j>1_${ik}$ )call stdlib${ii}$_ctpsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',j-1, ap, &
                           ap( jc ), 1_${ik}$ )
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( real( ap( jj ),KIND=sp) - stdlib${ii}$_cdotc( j-1,ap( jc ), 1_${ik}$, ap( jc ), 1_${ik}$ &
                           ),KIND=sp)
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ap( jj ) = sqrt( ajj )
              end do
           else
              ! compute the cholesky factorization a = l * l**h.
              jj = 1_${ik}$
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( ap( jj ),KIND=sp)
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ap( jj ) = ajj
                 ! compute elements j+1:n of column j and update the trailing
                 ! submatrix.
                 if( j<n ) then
                    call stdlib${ii}$_csscal( n-j, one / ajj, ap( jj+1 ), 1_${ik}$ )
                    call stdlib${ii}$_chpr( 'LOWER', n-j, -one, ap( jj+1 ), 1_${ik}$,ap( jj+n-j+1 ) )
                    jj = jj + n - j + 1_${ik}$
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_cpptrf

     pure module subroutine stdlib${ii}$_zpptrf( uplo, n, ap, info )
     !! ZPPTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A stored in packed format.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: n
           ! Array Arguments 
           complex(dp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj
           real(dp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**h * u.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 ! compute elements 1:j-1 of column j.
                 if( j>1_${ik}$ )call stdlib${ii}$_ztpsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',j-1, ap, &
                           ap( jc ), 1_${ik}$ )
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( ap( jj ),KIND=dp) - real( stdlib${ii}$_zdotc( j-1,ap( jc ), 1_${ik}$, ap( jc ), 1_${ik}$ &
                           ),KIND=dp)
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ap( jj ) = sqrt( ajj )
              end do
           else
              ! compute the cholesky factorization a = l * l**h.
              jj = 1_${ik}$
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( ap( jj ),KIND=dp)
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ap( jj ) = ajj
                 ! compute elements j+1:n of column j and update the trailing
                 ! submatrix.
                 if( j<n ) then
                    call stdlib${ii}$_zdscal( n-j, one / ajj, ap( jj+1 ), 1_${ik}$ )
                    call stdlib${ii}$_zhpr( 'LOWER', n-j, -one, ap( jj+1 ), 1_${ik}$,ap( jj+n-j+1 ) )
                    jj = jj + n - j + 1_${ik}$
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_zpptrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pptrf( uplo, n, ap, info )
     !! ZPPTRF: computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A stored in packed format.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj
           real(${ck}$) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           if( upper ) then
              ! compute the cholesky factorization a = u**h * u.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 ! compute elements 1:j-1 of column j.
                 if( j>1_${ik}$ )call stdlib${ii}$_${ci}$tpsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',j-1, ap, &
                           ap( jc ), 1_${ik}$ )
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( ap( jj ),KIND=${ck}$) - real( stdlib${ii}$_${ci}$dotc( j-1,ap( jc ), 1_${ik}$, ap( jc ), 1_${ik}$ &
                           ),KIND=${ck}$)
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ap( jj ) = sqrt( ajj )
              end do
           else
              ! compute the cholesky factorization a = l * l**h.
              jj = 1_${ik}$
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( ap( jj ),KIND=${ck}$)
                 if( ajj<=zero ) then
                    ap( jj ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ap( jj ) = ajj
                 ! compute elements j+1:n of column j and update the trailing
                 ! submatrix.
                 if( j<n ) then
                    call stdlib${ii}$_${ci}$dscal( n-j, one / ajj, ap( jj+1 ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$hpr( 'LOWER', n-j, -one, ap( jj+1 ), 1_${ik}$,ap( jj+n-j+1 ) )
                    jj = jj + n - j + 1_${ik}$
                 end if
              end do
           end if
           go to 40
           30 continue
           info = j
           40 continue
           return
     end subroutine stdlib${ii}$_${ci}$pptrf

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spptrs( uplo, n, nrhs, ap, b, ldb, info )
     !! SPPTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A in packed storage using the Cholesky
     !! factorization A = U**T*U or A = L*L**T computed by SPPTRF.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: ap(*)
           real(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPPTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t * u.
              do i = 1, nrhs
                 ! solve u**t *x = b, overwriting b with x.
                 call stdlib${ii}$_stpsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_stpsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
              end do
           else
              ! solve a*x = b where a = l * l**t.
              do i = 1, nrhs
                 ! solve l*y = b, overwriting b with x.
                 call stdlib${ii}$_stpsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
                 ! solve l**t *x = y, overwriting b with x.
                 call stdlib${ii}$_stpsv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_spptrs

     pure module subroutine stdlib${ii}$_dpptrs( uplo, n, nrhs, ap, b, ldb, info )
     !! DPPTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A in packed storage using the Cholesky
     !! factorization A = U**T*U or A = L*L**T computed by DPPTRF.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: ap(*)
           real(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t * u.
              do i = 1, nrhs
                 ! solve u**t *x = b, overwriting b with x.
                 call stdlib${ii}$_dtpsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_dtpsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
              end do
           else
              ! solve a*x = b where a = l * l**t.
              do i = 1, nrhs
                 ! solve l*y = b, overwriting b with x.
                 call stdlib${ii}$_dtpsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
                 ! solve l**t *x = y, overwriting b with x.
                 call stdlib${ii}$_dtpsv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_dpptrs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pptrs( uplo, n, nrhs, ap, b, ldb, info )
     !! DPPTRS: solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A in packed storage using the Cholesky
     !! factorization A = U**T*U or A = L*L**T computed by DPPTRF.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(in) :: ap(*)
           real(${rk}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t * u.
              do i = 1, nrhs
                 ! solve u**t *x = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tpsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tpsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
              end do
           else
              ! solve a*x = b where a = l * l**t.
              do i = 1, nrhs
                 ! solve l*y = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tpsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
                 ! solve l**t *x = y, overwriting b with x.
                 call stdlib${ii}$_${ri}$tpsv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pptrs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpptrs( uplo, n, nrhs, ap, b, ldb, info )
     !! CPPTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A in packed storage using the Cholesky
     !! factorization A = U**H*U or A = L*L**H computed by CPPTRF.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           complex(sp), intent(in) :: ap(*)
           complex(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPPTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h * u.
              do i = 1, nrhs
                 ! solve u**h *x = b, overwriting b with x.
                 call stdlib${ii}$_ctpsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,ap, b( 1_${ik}$, i ), &
                           1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_ctpsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
              end do
           else
              ! solve a*x = b where a = l * l**h.
              do i = 1, nrhs
                 ! solve l*y = b, overwriting b with x.
                 call stdlib${ii}$_ctpsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
                 ! solve l**h *x = y, overwriting b with x.
                 call stdlib${ii}$_ctpsv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,ap, b( 1_${ik}$, i ), &
                           1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_cpptrs

     pure module subroutine stdlib${ii}$_zpptrs( uplo, n, nrhs, ap, b, ldb, info )
     !! ZPPTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A in packed storage using the Cholesky
     !! factorization A = U**H * U or A = L * L**H computed by ZPPTRF.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           complex(dp), intent(in) :: ap(*)
           complex(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h * u.
              do i = 1, nrhs
                 ! solve u**h *x = b, overwriting b with x.
                 call stdlib${ii}$_ztpsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,ap, b( 1_${ik}$, i ), &
                           1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_ztpsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
              end do
           else
              ! solve a*x = b where a = l * l**h.
              do i = 1, nrhs
                 ! solve l*y = b, overwriting b with x.
                 call stdlib${ii}$_ztpsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
                 ! solve l**h *x = y, overwriting b with x.
                 call stdlib${ii}$_ztpsv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,ap, b( 1_${ik}$, i ), &
                           1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_zpptrs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pptrs( uplo, n, nrhs, ap, b, ldb, info )
     !! ZPPTRS: solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A in packed storage using the Cholesky
     !! factorization A = U**H * U or A = L * L**H computed by ZPPTRF.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           complex(${ck}$), intent(in) :: ap(*)
           complex(${ck}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h * u.
              do i = 1, nrhs
                 ! solve u**h *x = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tpsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,ap, b( 1_${ik}$, i ), &
                           1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tpsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
              end do
           else
              ! solve a*x = b where a = l * l**h.
              do i = 1, nrhs
                 ! solve l*y = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tpsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, ap,b( 1_${ik}$, i ), 1_${ik}$ )
                           
                 ! solve l**h *x = y, overwriting b with x.
                 call stdlib${ii}$_${ci}$tpsv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,ap, b( 1_${ik}$, i ), &
                           1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pptrs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spptri( uplo, n, ap, info )
     !! SPPTRI computes the inverse of a real symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by SPPTRF.
        ! -- 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) :: n
           ! Array Arguments 
           real(sp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj, jjn
           real(sp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPPTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_stptri( uplo, 'NON-UNIT', n, ap, info )
           if( info>0 )return
           if( upper ) then
              ! compute the product inv(u) * inv(u)**t.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 if( j>1_${ik}$ )call stdlib${ii}$_sspr( 'UPPER', j-1, one, ap( jc ), 1_${ik}$, ap )
                 ajj = ap( jj )
                 call stdlib${ii}$_sscal( j, ajj, ap( jc ), 1_${ik}$ )
              end do
           else
              ! compute the product inv(l)**t * inv(l).
              jj = 1_${ik}$
              do j = 1, n
                 jjn = jj + n - j + 1_${ik}$
                 ap( jj ) = stdlib${ii}$_sdot( n-j+1, ap( jj ), 1_${ik}$, ap( jj ), 1_${ik}$ )
                 if( j<n )call stdlib${ii}$_stpmv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n-j,ap( jjn ), ap( &
                           jj+1 ), 1_${ik}$ )
                 jj = jjn
              end do
           end if
           return
     end subroutine stdlib${ii}$_spptri

     pure module subroutine stdlib${ii}$_dpptri( uplo, n, ap, info )
     !! DPPTRI computes the inverse of a real symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by DPPTRF.
        ! -- 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) :: n
           ! Array Arguments 
           real(dp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj, jjn
           real(dp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_dtptri( uplo, 'NON-UNIT', n, ap, info )
           if( info>0 )return
           if( upper ) then
              ! compute the product inv(u) * inv(u)**t.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 if( j>1_${ik}$ )call stdlib${ii}$_dspr( 'UPPER', j-1, one, ap( jc ), 1_${ik}$, ap )
                 ajj = ap( jj )
                 call stdlib${ii}$_dscal( j, ajj, ap( jc ), 1_${ik}$ )
              end do
           else
              ! compute the product inv(l)**t * inv(l).
              jj = 1_${ik}$
              do j = 1, n
                 jjn = jj + n - j + 1_${ik}$
                 ap( jj ) = stdlib${ii}$_ddot( n-j+1, ap( jj ), 1_${ik}$, ap( jj ), 1_${ik}$ )
                 if( j<n )call stdlib${ii}$_dtpmv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n-j,ap( jjn ), ap( &
                           jj+1 ), 1_${ik}$ )
                 jj = jjn
              end do
           end if
           return
     end subroutine stdlib${ii}$_dpptri

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pptri( uplo, n, ap, info )
     !! DPPTRI: computes the inverse of a real symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by DPPTRF.
        ! -- 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) :: n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj, jjn
           real(${rk}$) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_${ri}$tptri( uplo, 'NON-UNIT', n, ap, info )
           if( info>0 )return
           if( upper ) then
              ! compute the product inv(u) * inv(u)**t.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 if( j>1_${ik}$ )call stdlib${ii}$_${ri}$spr( 'UPPER', j-1, one, ap( jc ), 1_${ik}$, ap )
                 ajj = ap( jj )
                 call stdlib${ii}$_${ri}$scal( j, ajj, ap( jc ), 1_${ik}$ )
              end do
           else
              ! compute the product inv(l)**t * inv(l).
              jj = 1_${ik}$
              do j = 1, n
                 jjn = jj + n - j + 1_${ik}$
                 ap( jj ) = stdlib${ii}$_${ri}$dot( n-j+1, ap( jj ), 1_${ik}$, ap( jj ), 1_${ik}$ )
                 if( j<n )call stdlib${ii}$_${ri}$tpmv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n-j,ap( jjn ), ap( &
                           jj+1 ), 1_${ik}$ )
                 jj = jjn
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pptri

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpptri( uplo, n, ap, info )
     !! CPPTRI computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by CPPTRF.
        ! -- 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) :: n
           ! Array Arguments 
           complex(sp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj, jjn
           real(sp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPPTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_ctptri( uplo, 'NON-UNIT', n, ap, info )
           if( info>0 )return
           if( upper ) then
              ! compute the product inv(u) * inv(u)**h.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 if( j>1_${ik}$ )call stdlib${ii}$_chpr( 'UPPER', j-1, one, ap( jc ), 1_${ik}$, ap )
                 ajj = real( ap( jj ),KIND=sp)
                 call stdlib${ii}$_csscal( j, ajj, ap( jc ), 1_${ik}$ )
              end do
           else
              ! compute the product inv(l)**h * inv(l).
              jj = 1_${ik}$
              do j = 1, n
                 jjn = jj + n - j + 1_${ik}$
                 ap( jj ) = real( stdlib${ii}$_cdotc( n-j+1, ap( jj ), 1_${ik}$, ap( jj ), 1_${ik}$ ),KIND=sp)
                 if( j<n )call stdlib${ii}$_ctpmv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n-j, ap( &
                           jjn ), ap( jj+1 ), 1_${ik}$ )
                 jj = jjn
              end do
           end if
           return
     end subroutine stdlib${ii}$_cpptri

     pure module subroutine stdlib${ii}$_zpptri( uplo, n, ap, info )
     !! ZPPTRI computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by ZPPTRF.
        ! -- 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) :: n
           ! Array Arguments 
           complex(dp), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj, jjn
           real(dp) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_ztptri( uplo, 'NON-UNIT', n, ap, info )
           if( info>0 )return
           if( upper ) then
              ! compute the product inv(u) * inv(u)**h.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 if( j>1_${ik}$ )call stdlib${ii}$_zhpr( 'UPPER', j-1, one, ap( jc ), 1_${ik}$, ap )
                 ajj = real( ap( jj ),KIND=dp)
                 call stdlib${ii}$_zdscal( j, ajj, ap( jc ), 1_${ik}$ )
              end do
           else
              ! compute the product inv(l)**h * inv(l).
              jj = 1_${ik}$
              do j = 1, n
                 jjn = jj + n - j + 1_${ik}$
                 ap( jj ) = real( stdlib${ii}$_zdotc( n-j+1, ap( jj ), 1_${ik}$, ap( jj ), 1_${ik}$ ),KIND=dp)
                 if( j<n )call stdlib${ii}$_ztpmv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n-j, ap( &
                           jjn ), ap( jj+1 ), 1_${ik}$ )
                 jj = jjn
              end do
           end if
           return
     end subroutine stdlib${ii}$_zpptri

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pptri( uplo, n, ap, info )
     !! ZPPTRI: computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by ZPPTRF.
        ! -- 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) :: n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, jc, jj, jjn
           real(${ck}$) :: ajj
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_${ci}$tptri( uplo, 'NON-UNIT', n, ap, info )
           if( info>0 )return
           if( upper ) then
              ! compute the product inv(u) * inv(u)**h.
              jj = 0_${ik}$
              do j = 1, n
                 jc = jj + 1_${ik}$
                 jj = jj + j
                 if( j>1_${ik}$ )call stdlib${ii}$_${ci}$hpr( 'UPPER', j-1, one, ap( jc ), 1_${ik}$, ap )
                 ajj = real( ap( jj ),KIND=${ck}$)
                 call stdlib${ii}$_${ci}$dscal( j, ajj, ap( jc ), 1_${ik}$ )
              end do
           else
              ! compute the product inv(l)**h * inv(l).
              jj = 1_${ik}$
              do j = 1, n
                 jjn = jj + n - j + 1_${ik}$
                 ap( jj ) = real( stdlib${ii}$_${ci}$dotc( n-j+1, ap( jj ), 1_${ik}$, ap( jj ), 1_${ik}$ ),KIND=${ck}$)
                 if( j<n )call stdlib${ii}$_${ci}$tpmv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',n-j, ap( &
                           jjn ), ap( jj+1 ), 1_${ik}$ )
                 jj = jjn
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pptri

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spprfs( uplo, n, nrhs, ap, afp, b, ldb, x, ldx, ferr,berr, work, &
     !! SPPRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and packed, and provides error bounds and backward error estimates
     !! for the solution.
               iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(in) :: afp(*), ap(*), b(ldb,*)
           real(sp), intent(out) :: berr(*), ferr(*), work(*)
           real(sp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ik, j, k, kase, kk, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPPRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_scopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_sspmv( uplo, n, -one, ap, x( 1_${ik}$, j ), 1_${ik}$, one, work( n+1 ),1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              kk = 1_${ik}$
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    ik = kk
                    do i = 1, k - 1
                       work( i ) = work( i ) + abs( ap( ik ) )*xk
                       s = s + abs( ap( ik ) )*abs( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    work( k ) = work( k ) + abs( ap( kk+k-1 ) )*xk + s
                    kk = kk + k
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( ap( kk ) )*xk
                    ik = kk + 1_${ik}$
                    do i = k + 1, n
                       work( i ) = work( i ) + abs( ap( ik ) )*xk
                       s = s + abs( ap( ik ) )*abs( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    work( k ) = work( k ) + s
                    kk = kk + ( n-k+1 )
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_spptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                 call stdlib${ii}$_saxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_slacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_slacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_spptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                    call stdlib${ii}$_spptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_spprfs

     pure module subroutine stdlib${ii}$_dpprfs( uplo, n, nrhs, ap, afp, b, ldb, x, ldx, ferr,berr, work, &
     !! DPPRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and packed, and provides error bounds and backward error estimates
     !! for the solution.
               iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(in) :: afp(*), ap(*), b(ldb,*)
           real(dp), intent(out) :: berr(*), ferr(*), work(*)
           real(dp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ik, j, k, kase, kk, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_dcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_dspmv( uplo, n, -one, ap, x( 1_${ik}$, j ), 1_${ik}$, one, work( n+1 ),1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              kk = 1_${ik}$
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    ik = kk
                    do i = 1, k - 1
                       work( i ) = work( i ) + abs( ap( ik ) )*xk
                       s = s + abs( ap( ik ) )*abs( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    work( k ) = work( k ) + abs( ap( kk+k-1 ) )*xk + s
                    kk = kk + k
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( ap( kk ) )*xk
                    ik = kk + 1_${ik}$
                    do i = k + 1, n
                       work( i ) = work( i ) + abs( ap( ik ) )*xk
                       s = s + abs( ap( ik ) )*abs( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    work( k ) = work( k ) + s
                    kk = kk + ( n-k+1 )
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_dpptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                 call stdlib${ii}$_daxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_dlacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_dlacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_dpptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                    call stdlib${ii}$_dpptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_dpprfs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pprfs( uplo, n, nrhs, ap, afp, b, ldb, x, ldx, ferr,berr, work, &
     !! DPPRFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and packed, and provides error bounds and backward error estimates
     !! for the solution.
               iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(in) :: afp(*), ap(*), b(ldb,*)
           real(${rk}$), intent(out) :: berr(*), ferr(*), work(*)
           real(${rk}$), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ik, j, k, kase, kk, nz
           real(${rk}$) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_${ri}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_${ri}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_${ri}$spmv( uplo, n, -one, ap, x( 1_${ik}$, j ), 1_${ik}$, one, work( n+1 ),1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              kk = 1_${ik}$
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    ik = kk
                    do i = 1, k - 1
                       work( i ) = work( i ) + abs( ap( ik ) )*xk
                       s = s + abs( ap( ik ) )*abs( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    work( k ) = work( k ) + abs( ap( kk+k-1 ) )*xk + s
                    kk = kk + k
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( ap( kk ) )*xk
                    ik = kk + 1_${ik}$
                    do i = k + 1, n
                       work( i ) = work( i ) + abs( ap( ik ) )*xk
                       s = s + abs( ap( ik ) )*abs( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    work( k ) = work( k ) + s
                    kk = kk + ( n-k+1 )
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ri}$pptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                 call stdlib${ii}$_${ri}$axpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_${ri}$lacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_${ri}$lacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_${ri}$pptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( i )*work( n+i )
                    end do
                    call stdlib${ii}$_${ri}$pptrs( uplo, n, 1_${ik}$, afp, work( n+1 ), n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_${ri}$pprfs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpprfs( uplo, n, nrhs, ap, afp, b, ldb, x, ldx, ferr,berr, work, &
     !! CPPRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and packed, and provides error bounds and backward error estimates
     !! for the solution.
               rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(sp), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(sp), intent(in) :: afp(*), ap(*), b(ldb,*)
           complex(sp), intent(out) :: work(*)
           complex(sp), intent(inout) :: x(ldx,*)
        ! ====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ik, j, k, kase, kk, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(sp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPPRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_ccopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_chpmv( uplo, n, -cone, ap, x( 1_${ik}$, j ), 1_${ik}$, cone, work, 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              kk = 1_${ik}$
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    ik = kk
                    do i = 1, k - 1
                       rwork( i ) = rwork( i ) + cabs1( ap( ik ) )*xk
                       s = s + cabs1( ap( ik ) )*cabs1( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    rwork( k ) = rwork( k ) + abs( real( ap( kk+k-1 ),KIND=sp) )*xk + s
                    kk = kk + k
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( ap( kk ),KIND=sp) )*xk
                    ik = kk + 1_${ik}$
                    do i = k + 1, n
                       rwork( i ) = rwork( i ) + cabs1( ap( ik ) )*xk
                       s = s + cabs1( ap( ik ) )*cabs1( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    rwork( k ) = rwork( k ) + s
                    kk = kk + ( n-k+1 )
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_cpptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                 call stdlib${ii}$_caxpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_clacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_clacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_cpptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_cpptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_cpprfs

     pure module subroutine stdlib${ii}$_zpprfs( uplo, n, nrhs, ap, afp, b, ldb, x, ldx, ferr,berr, work, &
     !! ZPPRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and packed, and provides error bounds and backward error estimates
     !! for the solution.
               rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(dp), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(dp), intent(in) :: afp(*), ap(*), b(ldb,*)
           complex(dp), intent(out) :: work(*)
           complex(dp), intent(inout) :: x(ldx,*)
        ! ====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ik, j, k, kase, kk, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(dp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_zcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_zhpmv( uplo, n, -cone, ap, x( 1_${ik}$, j ), 1_${ik}$, cone, work, 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              kk = 1_${ik}$
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    ik = kk
                    do i = 1, k - 1
                       rwork( i ) = rwork( i ) + cabs1( ap( ik ) )*xk
                       s = s + cabs1( ap( ik ) )*cabs1( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    rwork( k ) = rwork( k ) + abs( real( ap( kk+k-1 ),KIND=dp) )*xk + s
                    kk = kk + k
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( ap( kk ),KIND=dp) )*xk
                    ik = kk + 1_${ik}$
                    do i = k + 1, n
                       rwork( i ) = rwork( i ) + cabs1( ap( ik ) )*xk
                       s = s + cabs1( ap( ik ) )*cabs1( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    rwork( k ) = rwork( k ) + s
                    kk = kk + ( n-k+1 )
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_zpptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                 call stdlib${ii}$_zaxpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_zlacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_zpptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_zpptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_zpprfs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pprfs( uplo, n, nrhs, ap, afp, b, ldb, x, ldx, ferr,berr, work, &
     !! ZPPRFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and packed, and provides error bounds and backward error estimates
     !! for the solution.
               rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(${ck}$), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(${ck}$), intent(in) :: afp(*), ap(*), b(ldb,*)
           complex(${ck}$), intent(out) :: work(*)
           complex(${ck}$), intent(inout) :: x(ldx,*)
        ! ====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ik, j, k, kase, kk, nz
           real(${ck}$) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(${ck}$) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = n + 1_${ik}$
           eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_${ci}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_${ci}$hpmv( uplo, n, -cone, ap, x( 1_${ik}$, j ), 1_${ik}$, cone, work, 1_${ik}$ )
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              kk = 1_${ik}$
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    ik = kk
                    do i = 1, k - 1
                       rwork( i ) = rwork( i ) + cabs1( ap( ik ) )*xk
                       s = s + cabs1( ap( ik ) )*cabs1( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    rwork( k ) = rwork( k ) + abs( real( ap( kk+k-1 ),KIND=${ck}$) )*xk + s
                    kk = kk + k
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( ap( kk ),KIND=${ck}$) )*xk
                    ik = kk + 1_${ik}$
                    do i = k + 1, n
                       rwork( i ) = rwork( i ) + cabs1( ap( ik ) )*xk
                       s = s + cabs1( ap( ik ) )*cabs1( x( i, j ) )
                       ik = ik + 1_${ik}$
                    end do
                    rwork( k ) = rwork( k ) + s
                    kk = kk + ( n-k+1 )
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ci}$pptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                 call stdlib${ii}$_${ci}$axpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_${ci}$lacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_${ci}$pptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_${ci}$pptrs( uplo, n, 1_${ik}$, afp, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_${ci}$pprfs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sppequ( uplo, n, ap, s, scond, amax, info )
     !! SPPEQU computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A in packed storage and reduce
     !! its condition number (with respect to the two-norm).  S contains the
     !! scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix
     !! B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.
     !! This choice of S puts the condition number of B within a factor N of
     !! the smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: ap(*)
           real(sp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, jj
           real(sp) :: smin
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPPEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = ap( 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           if( upper ) then
              ! uplo = 'u':  upper triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + i
                 s( i ) = ap( jj )
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           else
              ! uplo = 'l':  lower triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + n - i + 2_${ik}$
                 s( i ) = ap( jj )
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           end if
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_sppequ

     pure module subroutine stdlib${ii}$_dppequ( uplo, n, ap, s, scond, amax, info )
     !! DPPEQU computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A in packed storage and reduce
     !! its condition number (with respect to the two-norm).  S contains the
     !! scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix
     !! B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.
     !! This choice of S puts the condition number of B within a factor N of
     !! the smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: ap(*)
           real(dp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, jj
           real(dp) :: smin
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = ap( 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           if( upper ) then
              ! uplo = 'u':  upper triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + i
                 s( i ) = ap( jj )
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           else
              ! uplo = 'l':  lower triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + n - i + 2_${ik}$
                 s( i ) = ap( jj )
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           end if
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_dppequ

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$ppequ( uplo, n, ap, s, scond, amax, info )
     !! DPPEQU: computes row and column scalings intended to equilibrate a
     !! symmetric positive definite matrix A in packed storage and reduce
     !! its condition number (with respect to the two-norm).  S contains the
     !! scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix
     !! B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.
     !! This choice of S puts the condition number of B within a factor N of
     !! the smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: n
           real(${rk}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${rk}$), intent(in) :: ap(*)
           real(${rk}$), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, jj
           real(${rk}$) :: smin
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPPEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = ap( 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           if( upper ) then
              ! uplo = 'u':  upper triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + i
                 s( i ) = ap( jj )
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           else
              ! uplo = 'l':  lower triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + n - i + 2_${ik}$
                 s( i ) = ap( jj )
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           end if
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$ppequ

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cppequ( uplo, n, ap, s, scond, amax, info )
     !! CPPEQU computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A in packed storage and reduce
     !! its condition number (with respect to the two-norm).  S contains the
     !! scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix
     !! B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.
     !! This choice of S puts the condition number of B within a factor N of
     !! the smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(out) :: s(*)
           complex(sp), intent(in) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, jj
           real(sp) :: smin
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPPEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = real( ap( 1_${ik}$ ),KIND=sp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           if( upper ) then
              ! uplo = 'u':  upper triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + i
                 s( i ) = real( ap( jj ),KIND=sp)
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           else
              ! uplo = 'l':  lower triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + n - i + 2_${ik}$
                 s( i ) = real( ap( jj ),KIND=sp)
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           end if
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_cppequ

     pure module subroutine stdlib${ii}$_zppequ( uplo, n, ap, s, scond, amax, info )
     !! ZPPEQU computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A in packed storage and reduce
     !! its condition number (with respect to the two-norm).  S contains the
     !! scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix
     !! B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.
     !! This choice of S puts the condition number of B within a factor N of
     !! the smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(out) :: s(*)
           complex(dp), intent(in) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, jj
           real(dp) :: smin
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = real( ap( 1_${ik}$ ),KIND=dp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           if( upper ) then
              ! uplo = 'u':  upper triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + i
                 s( i ) = real( ap( jj ),KIND=dp)
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           else
              ! uplo = 'l':  lower triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + n - i + 2_${ik}$
                 s( i ) = real( ap( jj ),KIND=dp)
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           end if
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_zppequ

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ppequ( uplo, n, ap, s, scond, amax, info )
     !! ZPPEQU: computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite matrix A in packed storage and reduce
     !! its condition number (with respect to the two-norm).  S contains the
     !! scale factors, S(i)=1/sqrt(A(i,i)), chosen so that the scaled matrix
     !! B with elements B(i,j)=S(i)*A(i,j)*S(j) has ones on the diagonal.
     !! This choice of S puts the condition number of B within a factor N of
     !! the smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: n
           real(${ck}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(out) :: s(*)
           complex(${ck}$), intent(in) :: ap(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, jj
           real(${ck}$) :: smin
           ! 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}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPPEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = real( ap( 1_${ik}$ ),KIND=${ck}$)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           if( upper ) then
              ! uplo = 'u':  upper triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + i
                 s( i ) = real( ap( jj ),KIND=${ck}$)
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           else
              ! uplo = 'l':  lower triangle of a is stored.
              ! find the minimum and maximum diagonal elements.
              jj = 1_${ik}$
              do i = 2, n
                 jj = jj + n - i + 2_${ik}$
                 s( i ) = real( ap( jj ),KIND=${ck}$)
                 smin = min( smin, s( i ) )
                 amax = max( amax, s( i ) )
              end do
           end if
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ci}$ppequ

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_claqhp( uplo, n, ap, s, scond, amax, equed )
     !! CLAQHP equilibrates a Hermitian matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(sp), intent(in) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: s(*)
           complex(sp), intent(inout) :: ap(*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: thresh = 0.1e+0_sp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(sp) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_slamch( 'SAFE MINIMUM' ) / stdlib${ii}$_slamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j - 1
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    ap( jc+j-1 ) = cj*cj*real( ap( jc+j-1 ),KIND=sp)
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    ap( jc ) = cj*cj*real( ap( jc ),KIND=sp)
                    do i = j + 1, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_claqhp

     pure module subroutine stdlib${ii}$_zlaqhp( uplo, n, ap, s, scond, amax, equed )
     !! ZLAQHP equilibrates a Hermitian matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(dp), intent(in) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: s(*)
           complex(dp), intent(inout) :: ap(*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: thresh = 0.1e+0_dp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(dp) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_dlamch( 'SAFE MINIMUM' ) / stdlib${ii}$_dlamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j - 1
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    ap( jc+j-1 ) = cj*cj*real( ap( jc+j-1 ),KIND=dp)
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    ap( jc ) = cj*cj*real( ap( jc ),KIND=dp)
                    do i = j + 1, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_zlaqhp

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$laqhp( uplo, n, ap, s, scond, amax, equed )
     !! ZLAQHP: equilibrates a Hermitian matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(${ck}$), intent(in) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(in) :: s(*)
           complex(${ck}$), intent(inout) :: ap(*)
        ! =====================================================================
           ! Parameters 
           real(${ck}$), parameter :: thresh = 0.1e+0_${ck}$
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(${ck}$) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' ) / stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j - 1
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    ap( jc+j-1 ) = cj*cj*real( ap( jc+j-1 ),KIND=${ck}$)
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    ap( jc ) = cj*cj*real( ap( jc ),KIND=${ck}$)
                    do i = j + 1, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_${ci}$laqhp

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spftrf( transr, uplo, n, a, info )
     !! SPFTRF computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(in) :: n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           real(sp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPFTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution: there are eight cases
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                   ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                   ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                   ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_spotrf( 'L', n1, a( 0_${ik}$ ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'R', 'L', 'T', 'N', n2, n1, one, a( 0_${ik}$ ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_ssyrk( 'U', 'N', n2, n1, -one, a( n1 ), n, one,a( n ), n )
                    call stdlib${ii}$_spotrf( 'U', n2, a( n ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                   ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                   ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                   ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_spotrf( 'L', n1, a( n2 ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'L', 'L', 'N', 'N', n1, n2, one, a( n2 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_ssyrk( 'U', 'T', n2, n1, -one, a( 0_${ik}$ ), n, one,a( n1 ), n )
                    call stdlib${ii}$_spotrf( 'U', n2, a( n1 ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              else
                 ! n is odd and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose and n is odd
                    ! t1 -> a(0,0) , t2 -> a(1,0) , s -> a(0,n1)
                    ! t1 -> a(0+0) , t2 -> a(1+0) , s -> a(0+n1*n1); lda=n1
                    call stdlib${ii}$_spotrf( 'U', n1, a( 0_${ik}$ ), n1, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'L', 'U', 'T', 'N', n1, n2, one, a( 0_${ik}$ ), n1,a( n1*n1 ), n1 &
                              )
                    call stdlib${ii}$_ssyrk( 'L', 'T', n2, n1, -one, a( n1*n1 ), n1, one,a( 1_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_spotrf( 'L', n2, a( 1_${ik}$ ), n1, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                    ! srpa for upper, transpose and n is odd
                    ! t1 -> a(0,n1+1), t2 -> a(0,n1), s -> a(0,0)
                    ! t1 -> a(n2*n2), t2 -> a(n1*n2), s -> a(0); lda = n2
                    call stdlib${ii}$_spotrf( 'U', n1, a( n2*n2 ), n2, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'R', 'U', 'N', 'N', n2, n1, one, a( n2*n2 ),n2, a( 0_${ik}$ ), n2 &
                              )
                    call stdlib${ii}$_ssyrk( 'L', 'N', n2, n1, -one, a( 0_${ik}$ ), n2, one,a( n1*n2 ), n2 )
                              
                    call stdlib${ii}$_spotrf( 'L', n2, a( n1*n2 ), n2, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_spotrf( 'L', k, a( 1_${ik}$ ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'R', 'L', 'T', 'N', k, k, one, a( 1_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_ssyrk( 'U', 'N', k, k, -one, a( k+1 ), n+1, one,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_spotrf( 'U', k, a( 0_${ik}$ ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_spotrf( 'L', k, a( k+1 ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'L', 'L', 'N', 'N', k, k, one, a( k+1 ),n+1, a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_ssyrk( 'U', 'T', k, k, -one, a( 0_${ik}$ ), n+1, one,a( k ), n+1 )
                              
                    call stdlib${ii}$_spotrf( 'U', k, a( k ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              else
                 ! n is even and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1)
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_spotrf( 'U', k, a( 0_${ik}$+k ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'L', 'U', 'T', 'N', k, k, one, a( k ), n1,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_ssyrk( 'L', 'T', k, k, -one, a( k*( k+1 ) ), k, one,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_spotrf( 'L', k, a( 0_${ik}$ ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, transpose and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0)
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_spotrf( 'U', k, a( k*( k+1 ) ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_strsm( 'R', 'U', 'N', 'N', k, k, one,a( k*( k+1 ) ), k, a( 0_${ik}$ ), k &
                              )
                    call stdlib${ii}$_ssyrk( 'L', 'N', k, k, -one, a( 0_${ik}$ ), k, one,a( k*k ), k )
                    call stdlib${ii}$_spotrf( 'L', k, a( k*k ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_spftrf

     pure module subroutine stdlib${ii}$_dpftrf( transr, uplo, n, a, info )
     !! DPFTRF computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(in) :: n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           real(dp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPFTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution: there are eight cases
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                   ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                   ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                   ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_dpotrf( 'L', n1, a( 0_${ik}$ ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'R', 'L', 'T', 'N', n2, n1, one, a( 0_${ik}$ ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_dsyrk( 'U', 'N', n2, n1, -one, a( n1 ), n, one,a( n ), n )
                    call stdlib${ii}$_dpotrf( 'U', n2, a( n ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                   ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                   ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                   ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_dpotrf( 'L', n1, a( n2 ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'L', 'L', 'N', 'N', n1, n2, one, a( n2 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_dsyrk( 'U', 'T', n2, n1, -one, a( 0_${ik}$ ), n, one,a( n1 ), n )
                    call stdlib${ii}$_dpotrf( 'U', n2, a( n1 ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              else
                 ! n is odd and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose and n is odd
                    ! t1 -> a(0,0) , t2 -> a(1,0) , s -> a(0,n1)
                    ! t1 -> a(0+0) , t2 -> a(1+0) , s -> a(0+n1*n1); lda=n1
                    call stdlib${ii}$_dpotrf( 'U', n1, a( 0_${ik}$ ), n1, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'L', 'U', 'T', 'N', n1, n2, one, a( 0_${ik}$ ), n1,a( n1*n1 ), n1 &
                              )
                    call stdlib${ii}$_dsyrk( 'L', 'T', n2, n1, -one, a( n1*n1 ), n1, one,a( 1_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_dpotrf( 'L', n2, a( 1_${ik}$ ), n1, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                    ! srpa for upper, transpose and n is odd
                    ! t1 -> a(0,n1+1), t2 -> a(0,n1), s -> a(0,0)
                    ! t1 -> a(n2*n2), t2 -> a(n1*n2), s -> a(0); lda = n2
                    call stdlib${ii}$_dpotrf( 'U', n1, a( n2*n2 ), n2, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'R', 'U', 'N', 'N', n2, n1, one, a( n2*n2 ),n2, a( 0_${ik}$ ), n2 &
                              )
                    call stdlib${ii}$_dsyrk( 'L', 'N', n2, n1, -one, a( 0_${ik}$ ), n2, one,a( n1*n2 ), n2 )
                              
                    call stdlib${ii}$_dpotrf( 'L', n2, a( n1*n2 ), n2, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_dpotrf( 'L', k, a( 1_${ik}$ ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'R', 'L', 'T', 'N', k, k, one, a( 1_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_dsyrk( 'U', 'N', k, k, -one, a( k+1 ), n+1, one,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_dpotrf( 'U', k, a( 0_${ik}$ ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_dpotrf( 'L', k, a( k+1 ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'L', 'L', 'N', 'N', k, k, one, a( k+1 ),n+1, a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_dsyrk( 'U', 'T', k, k, -one, a( 0_${ik}$ ), n+1, one,a( k ), n+1 )
                              
                    call stdlib${ii}$_dpotrf( 'U', k, a( k ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              else
                 ! n is even and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1)
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_dpotrf( 'U', k, a( 0_${ik}$+k ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'L', 'U', 'T', 'N', k, k, one, a( k ), n1,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_dsyrk( 'L', 'T', k, k, -one, a( k*( k+1 ) ), k, one,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_dpotrf( 'L', k, a( 0_${ik}$ ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, transpose and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0)
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_dpotrf( 'U', k, a( k*( k+1 ) ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_dtrsm( 'R', 'U', 'N', 'N', k, k, one,a( k*( k+1 ) ), k, a( 0_${ik}$ ), k &
                              )
                    call stdlib${ii}$_dsyrk( 'L', 'N', k, k, -one, a( 0_${ik}$ ), k, one,a( k*k ), k )
                    call stdlib${ii}$_dpotrf( 'L', k, a( k*k ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_dpftrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pftrf( transr, uplo, n, a, info )
     !! DPFTRF: computes the Cholesky factorization of a real symmetric
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(in) :: n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPFTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution: there are eight cases
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                   ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                   ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                   ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_${ri}$potrf( 'L', n1, a( 0_${ik}$ ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'R', 'L', 'T', 'N', n2, n1, one, a( 0_${ik}$ ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_${ri}$syrk( 'U', 'N', n2, n1, -one, a( n1 ), n, one,a( n ), n )
                    call stdlib${ii}$_${ri}$potrf( 'U', n2, a( n ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                   ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                   ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                   ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_${ri}$potrf( 'L', n1, a( n2 ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'L', 'L', 'N', 'N', n1, n2, one, a( n2 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_${ri}$syrk( 'U', 'T', n2, n1, -one, a( 0_${ik}$ ), n, one,a( n1 ), n )
                    call stdlib${ii}$_${ri}$potrf( 'U', n2, a( n1 ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              else
                 ! n is odd and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose and n is odd
                    ! t1 -> a(0,0) , t2 -> a(1,0) , s -> a(0,n1)
                    ! t1 -> a(0+0) , t2 -> a(1+0) , s -> a(0+n1*n1); lda=n1
                    call stdlib${ii}$_${ri}$potrf( 'U', n1, a( 0_${ik}$ ), n1, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'L', 'U', 'T', 'N', n1, n2, one, a( 0_${ik}$ ), n1,a( n1*n1 ), n1 &
                              )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'T', n2, n1, -one, a( n1*n1 ), n1, one,a( 1_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_${ri}$potrf( 'L', n2, a( 1_${ik}$ ), n1, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                    ! srpa for upper, transpose and n is odd
                    ! t1 -> a(0,n1+1), t2 -> a(0,n1), s -> a(0,0)
                    ! t1 -> a(n2*n2), t2 -> a(n1*n2), s -> a(0); lda = n2
                    call stdlib${ii}$_${ri}$potrf( 'U', n1, a( n2*n2 ), n2, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'R', 'U', 'N', 'N', n2, n1, one, a( n2*n2 ),n2, a( 0_${ik}$ ), n2 &
                              )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'N', n2, n1, -one, a( 0_${ik}$ ), n2, one,a( n1*n2 ), n2 )
                              
                    call stdlib${ii}$_${ri}$potrf( 'L', n2, a( n1*n2 ), n2, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_${ri}$potrf( 'L', k, a( 1_${ik}$ ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'R', 'L', 'T', 'N', k, k, one, a( 1_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_${ri}$syrk( 'U', 'N', k, k, -one, a( k+1 ), n+1, one,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ri}$potrf( 'U', k, a( 0_${ik}$ ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_${ri}$potrf( 'L', k, a( k+1 ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'L', 'L', 'N', 'N', k, k, one, a( k+1 ),n+1, a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ri}$syrk( 'U', 'T', k, k, -one, a( 0_${ik}$ ), n+1, one,a( k ), n+1 )
                              
                    call stdlib${ii}$_${ri}$potrf( 'U', k, a( k ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              else
                 ! n is even and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1)
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_${ri}$potrf( 'U', k, a( 0_${ik}$+k ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'L', 'U', 'T', 'N', k, k, one, a( k ), n1,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'T', k, k, -one, a( k*( k+1 ) ), k, one,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_${ri}$potrf( 'L', k, a( 0_${ik}$ ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, transpose and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0)
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_${ri}$potrf( 'U', k, a( k*( k+1 ) ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ri}$trsm( 'R', 'U', 'N', 'N', k, k, one,a( k*( k+1 ) ), k, a( 0_${ik}$ ), k &
                              )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'N', k, k, -one, a( 0_${ik}$ ), k, one,a( k*k ), k )
                    call stdlib${ii}$_${ri}$potrf( 'L', k, a( k*k ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pftrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpftrf( transr, uplo, n, a, info )
     !! CPFTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(in) :: n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           complex(sp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPFTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution: there are eight cases
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                   ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                   ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                   ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_cpotrf( 'L', n1, a( 0_${ik}$ ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'R', 'L', 'C', 'N', n2, n1, cone, a( 0_${ik}$ ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_cherk( 'U', 'N', n2, n1, -one, a( n1 ), n, one,a( n ), n )
                    call stdlib${ii}$_cpotrf( 'U', n2, a( n ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                   ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                   ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                   ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_cpotrf( 'L', n1, a( n2 ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'L', 'L', 'N', 'N', n1, n2, cone, a( n2 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_cherk( 'U', 'C', n2, n1, -one, a( 0_${ik}$ ), n, one,a( n1 ), n )
                    call stdlib${ii}$_cpotrf( 'U', n2, a( n1 ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              else
                 ! n is odd and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose and n is odd
                    ! t1 -> a(0,0) , t2 -> a(1,0) , s -> a(0,n1)
                    ! t1 -> a(0+0) , t2 -> a(1+0) , s -> a(0+n1*n1); lda=n1
                    call stdlib${ii}$_cpotrf( 'U', n1, a( 0_${ik}$ ), n1, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'L', 'U', 'C', 'N', n1, n2, cone, a( 0_${ik}$ ), n1,a( n1*n1 ), &
                              n1 )
                    call stdlib${ii}$_cherk( 'L', 'C', n2, n1, -one, a( n1*n1 ), n1, one,a( 1_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_cpotrf( 'L', n2, a( 1_${ik}$ ), n1, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                    ! srpa for upper, transpose and n is odd
                    ! t1 -> a(0,n1+1), t2 -> a(0,n1), s -> a(0,0)
                    ! t1 -> a(n2*n2), t2 -> a(n1*n2), s -> a(0); lda = n2
                    call stdlib${ii}$_cpotrf( 'U', n1, a( n2*n2 ), n2, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'R', 'U', 'N', 'N', n2, n1, cone, a( n2*n2 ),n2, a( 0_${ik}$ ), &
                              n2 )
                    call stdlib${ii}$_cherk( 'L', 'N', n2, n1, -one, a( 0_${ik}$ ), n2, one,a( n1*n2 ), n2 )
                              
                    call stdlib${ii}$_cpotrf( 'L', n2, a( n1*n2 ), n2, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_cpotrf( 'L', k, a( 1_${ik}$ ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'R', 'L', 'C', 'N', k, k, cone, a( 1_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_cherk( 'U', 'N', k, k, -one, a( k+1 ), n+1, one,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_cpotrf( 'U', k, a( 0_${ik}$ ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_cpotrf( 'L', k, a( k+1 ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'L', 'L', 'N', 'N', k, k, cone, a( k+1 ),n+1, a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_cherk( 'U', 'C', k, k, -one, a( 0_${ik}$ ), n+1, one,a( k ), n+1 )
                              
                    call stdlib${ii}$_cpotrf( 'U', k, a( k ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              else
                 ! n is even and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1)
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_cpotrf( 'U', k, a( 0_${ik}$+k ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'L', 'U', 'C', 'N', k, k, cone, a( k ), n1,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_cherk( 'L', 'C', k, k, -one, a( k*( k+1 ) ), k, one,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_cpotrf( 'L', k, a( 0_${ik}$ ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, transpose and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0)
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_cpotrf( 'U', k, a( k*( k+1 ) ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_ctrsm( 'R', 'U', 'N', 'N', k, k, cone,a( k*( k+1 ) ), k, a( 0_${ik}$ ), &
                              k )
                    call stdlib${ii}$_cherk( 'L', 'N', k, k, -one, a( 0_${ik}$ ), k, one,a( k*k ), k )
                    call stdlib${ii}$_cpotrf( 'L', k, a( k*k ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_cpftrf

     pure module subroutine stdlib${ii}$_zpftrf( transr, uplo, n, a, info )
     !! ZPFTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(in) :: n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           complex(dp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPFTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution: there are eight cases
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                   ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                   ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                   ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_zpotrf( 'L', n1, a( 0_${ik}$ ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'R', 'L', 'C', 'N', n2, n1, cone, a( 0_${ik}$ ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_zherk( 'U', 'N', n2, n1, -one, a( n1 ), n, one,a( n ), n )
                    call stdlib${ii}$_zpotrf( 'U', n2, a( n ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                   ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                   ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                   ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_zpotrf( 'L', n1, a( n2 ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'L', 'L', 'N', 'N', n1, n2, cone, a( n2 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_zherk( 'U', 'C', n2, n1, -one, a( 0_${ik}$ ), n, one,a( n1 ), n )
                    call stdlib${ii}$_zpotrf( 'U', n2, a( n1 ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              else
                 ! n is odd and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose and n is odd
                    ! t1 -> a(0,0) , t2 -> a(1,0) , s -> a(0,n1)
                    ! t1 -> a(0+0) , t2 -> a(1+0) , s -> a(0+n1*n1); lda=n1
                    call stdlib${ii}$_zpotrf( 'U', n1, a( 0_${ik}$ ), n1, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'L', 'U', 'C', 'N', n1, n2, cone, a( 0_${ik}$ ), n1,a( n1*n1 ), &
                              n1 )
                    call stdlib${ii}$_zherk( 'L', 'C', n2, n1, -one, a( n1*n1 ), n1, one,a( 1_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_zpotrf( 'L', n2, a( 1_${ik}$ ), n1, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                    ! srpa for upper, transpose and n is odd
                    ! t1 -> a(0,n1+1), t2 -> a(0,n1), s -> a(0,0)
                    ! t1 -> a(n2*n2), t2 -> a(n1*n2), s -> a(0); lda = n2
                    call stdlib${ii}$_zpotrf( 'U', n1, a( n2*n2 ), n2, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'R', 'U', 'N', 'N', n2, n1, cone, a( n2*n2 ),n2, a( 0_${ik}$ ), &
                              n2 )
                    call stdlib${ii}$_zherk( 'L', 'N', n2, n1, -one, a( 0_${ik}$ ), n2, one,a( n1*n2 ), n2 )
                              
                    call stdlib${ii}$_zpotrf( 'L', n2, a( n1*n2 ), n2, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_zpotrf( 'L', k, a( 1_${ik}$ ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'R', 'L', 'C', 'N', k, k, cone, a( 1_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_zherk( 'U', 'N', k, k, -one, a( k+1 ), n+1, one,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_zpotrf( 'U', k, a( 0_${ik}$ ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_zpotrf( 'L', k, a( k+1 ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'L', 'L', 'N', 'N', k, k, cone, a( k+1 ),n+1, a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_zherk( 'U', 'C', k, k, -one, a( 0_${ik}$ ), n+1, one,a( k ), n+1 )
                              
                    call stdlib${ii}$_zpotrf( 'U', k, a( k ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              else
                 ! n is even and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1)
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_zpotrf( 'U', k, a( 0_${ik}$+k ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'L', 'U', 'C', 'N', k, k, cone, a( k ), n1,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_zherk( 'L', 'C', k, k, -one, a( k*( k+1 ) ), k, one,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_zpotrf( 'L', k, a( 0_${ik}$ ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, transpose and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0)
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_zpotrf( 'U', k, a( k*( k+1 ) ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_ztrsm( 'R', 'U', 'N', 'N', k, k, cone,a( k*( k+1 ) ), k, a( 0_${ik}$ ), &
                              k )
                    call stdlib${ii}$_zherk( 'L', 'N', k, k, -one, a( 0_${ik}$ ), k, one,a( k*k ), k )
                    call stdlib${ii}$_zpotrf( 'L', k, a( k*k ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_zpftrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pftrf( transr, uplo, n, a, info )
     !! ZPFTRF: computes the Cholesky factorization of a complex Hermitian
     !! positive definite matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
     !! This is the block version of the algorithm, calling Level 3 BLAS.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(in) :: n
           integer(${ik}$), intent(out) :: info
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPFTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution: there are eight cases
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                   ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                   ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                   ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_${ci}$potrf( 'L', n1, a( 0_${ik}$ ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'R', 'L', 'C', 'N', n2, n1, cone, a( 0_${ik}$ ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_${ci}$herk( 'U', 'N', n2, n1, -one, a( n1 ), n, one,a( n ), n )
                    call stdlib${ii}$_${ci}$potrf( 'U', n2, a( n ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                   ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                   ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                   ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_${ci}$potrf( 'L', n1, a( n2 ), n, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'L', 'L', 'N', 'N', n1, n2, cone, a( n2 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_${ci}$herk( 'U', 'C', n2, n1, -one, a( 0_${ik}$ ), n, one,a( n1 ), n )
                    call stdlib${ii}$_${ci}$potrf( 'U', n2, a( n1 ), n, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              else
                 ! n is odd and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose and n is odd
                    ! t1 -> a(0,0) , t2 -> a(1,0) , s -> a(0,n1)
                    ! t1 -> a(0+0) , t2 -> a(1+0) , s -> a(0+n1*n1); lda=n1
                    call stdlib${ii}$_${ci}$potrf( 'U', n1, a( 0_${ik}$ ), n1, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'L', 'U', 'C', 'N', n1, n2, cone, a( 0_${ik}$ ), n1,a( n1*n1 ), &
                              n1 )
                    call stdlib${ii}$_${ci}$herk( 'L', 'C', n2, n1, -one, a( n1*n1 ), n1, one,a( 1_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_${ci}$potrf( 'L', n2, a( 1_${ik}$ ), n1, info )
                    if( info>0_${ik}$ )info = info + n1
                 else
                    ! srpa for upper, transpose and n is odd
                    ! t1 -> a(0,n1+1), t2 -> a(0,n1), s -> a(0,0)
                    ! t1 -> a(n2*n2), t2 -> a(n1*n2), s -> a(0); lda = n2
                    call stdlib${ii}$_${ci}$potrf( 'U', n1, a( n2*n2 ), n2, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'R', 'U', 'N', 'N', n2, n1, cone, a( n2*n2 ),n2, a( 0_${ik}$ ), &
                              n2 )
                    call stdlib${ii}$_${ci}$herk( 'L', 'N', n2, n1, -one, a( 0_${ik}$ ), n2, one,a( n1*n2 ), n2 )
                              
                    call stdlib${ii}$_${ci}$potrf( 'L', n2, a( n1*n2 ), n2, info )
                    if( info>0_${ik}$ )info = info + n1
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_${ci}$potrf( 'L', k, a( 1_${ik}$ ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'R', 'L', 'C', 'N', k, k, cone, a( 1_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_${ci}$herk( 'U', 'N', k, k, -one, a( k+1 ), n+1, one,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ci}$potrf( 'U', k, a( 0_${ik}$ ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_${ci}$potrf( 'L', k, a( k+1 ), n+1, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'L', 'L', 'N', 'N', k, k, cone, a( k+1 ),n+1, a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ci}$herk( 'U', 'C', k, k, -one, a( 0_${ik}$ ), n+1, one,a( k ), n+1 )
                              
                    call stdlib${ii}$_${ci}$potrf( 'U', k, a( k ), n+1, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              else
                 ! n is even and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1)
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_${ci}$potrf( 'U', k, a( 0_${ik}$+k ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'L', 'U', 'C', 'N', k, k, cone, a( k ), n1,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_${ci}$herk( 'L', 'C', k, k, -one, a( k*( k+1 ) ), k, one,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_${ci}$potrf( 'L', k, a( 0_${ik}$ ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 else
                    ! srpa for upper, transpose and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0)
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_${ci}$potrf( 'U', k, a( k*( k+1 ) ), k, info )
                    if( info>0 )return
                    call stdlib${ii}$_${ci}$trsm( 'R', 'U', 'N', 'N', k, k, cone,a( k*( k+1 ) ), k, a( 0_${ik}$ ), &
                              k )
                    call stdlib${ii}$_${ci}$herk( 'L', 'N', k, k, -one, a( 0_${ik}$ ), k, one,a( k*k ), k )
                    call stdlib${ii}$_${ci}$potrf( 'L', k, a( k*k ), k, info )
                    if( info>0_${ik}$ )info = info + k
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pftrf

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spftrs( transr, uplo, n, nrhs, a, b, ldb, info )
     !! SPFTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by SPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: a(0_${ik}$:*)
           real(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, normaltransr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPFTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! start execution: there are two triangular solves
           if( lower ) then
              call stdlib${ii}$_stfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, one, a, b,ldb )
              call stdlib${ii}$_stfsm( transr, 'L', uplo, 'T', 'N', n, nrhs, one, a, b,ldb )
           else
              call stdlib${ii}$_stfsm( transr, 'L', uplo, 'T', 'N', n, nrhs, one, a, b,ldb )
              call stdlib${ii}$_stfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, one, a, b,ldb )
           end if
           return
     end subroutine stdlib${ii}$_spftrs

     pure module subroutine stdlib${ii}$_dpftrs( transr, uplo, n, nrhs, a, b, ldb, info )
     !! DPFTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by DPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: a(0_${ik}$:*)
           real(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, normaltransr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPFTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! start execution: there are two triangular solves
           if( lower ) then
              call stdlib${ii}$_dtfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, one, a, b,ldb )
              call stdlib${ii}$_dtfsm( transr, 'L', uplo, 'T', 'N', n, nrhs, one, a, b,ldb )
           else
              call stdlib${ii}$_dtfsm( transr, 'L', uplo, 'T', 'N', n, nrhs, one, a, b,ldb )
              call stdlib${ii}$_dtfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, one, a, b,ldb )
           end if
           return
     end subroutine stdlib${ii}$_dpftrs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pftrs( transr, uplo, n, nrhs, a, b, ldb, info )
     !! DPFTRS: solves a system of linear equations A*X = B with a symmetric
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by DPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(in) :: a(0_${ik}$:*)
           real(${rk}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, normaltransr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPFTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! start execution: there are two triangular solves
           if( lower ) then
              call stdlib${ii}$_${ri}$tfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, one, a, b,ldb )
              call stdlib${ii}$_${ri}$tfsm( transr, 'L', uplo, 'T', 'N', n, nrhs, one, a, b,ldb )
           else
              call stdlib${ii}$_${ri}$tfsm( transr, 'L', uplo, 'T', 'N', n, nrhs, one, a, b,ldb )
              call stdlib${ii}$_${ri}$tfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, one, a, b,ldb )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pftrs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpftrs( transr, uplo, n, nrhs, a, b, ldb, info )
     !! CPFTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**H*U or A = L*L**H computed by CPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           complex(sp), intent(in) :: a(0_${ik}$:*)
           complex(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, normaltransr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPFTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! start execution: there are two triangular solves
           if( lower ) then
              call stdlib${ii}$_ctfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, cone, a, b,ldb )
              call stdlib${ii}$_ctfsm( transr, 'L', uplo, 'C', 'N', n, nrhs, cone, a, b,ldb )
           else
              call stdlib${ii}$_ctfsm( transr, 'L', uplo, 'C', 'N', n, nrhs, cone, a, b,ldb )
              call stdlib${ii}$_ctfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, cone, a, b,ldb )
           end if
           return
     end subroutine stdlib${ii}$_cpftrs

     pure module subroutine stdlib${ii}$_zpftrs( transr, uplo, n, nrhs, a, b, ldb, info )
     !! ZPFTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**H*U or A = L*L**H computed by ZPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           complex(dp), intent(in) :: a(0_${ik}$:*)
           complex(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, normaltransr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPFTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! start execution: there are two triangular solves
           if( lower ) then
              call stdlib${ii}$_ztfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, cone, a, b,ldb )
              call stdlib${ii}$_ztfsm( transr, 'L', uplo, 'C', 'N', n, nrhs, cone, a, b,ldb )
           else
              call stdlib${ii}$_ztfsm( transr, 'L', uplo, 'C', 'N', n, nrhs, cone, a, b,ldb )
              call stdlib${ii}$_ztfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, cone, a, b,ldb )
           end if
           return
     end subroutine stdlib${ii}$_zpftrs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pftrs( transr, uplo, n, nrhs, a, b, ldb, info )
     !! ZPFTRS: solves a system of linear equations A*X = B with a Hermitian
     !! positive definite matrix A using the Cholesky factorization
     !! A = U**H*U or A = L*L**H computed by ZPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           complex(${ck}$), intent(in) :: a(0_${ik}$:*)
           complex(${ck}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, normaltransr
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPFTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! start execution: there are two triangular solves
           if( lower ) then
              call stdlib${ii}$_${ci}$tfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, cone, a, b,ldb )
              call stdlib${ii}$_${ci}$tfsm( transr, 'L', uplo, 'C', 'N', n, nrhs, cone, a, b,ldb )
           else
              call stdlib${ii}$_${ci}$tfsm( transr, 'L', uplo, 'C', 'N', n, nrhs, cone, a, b,ldb )
              call stdlib${ii}$_${ci}$tfsm( transr, 'L', uplo, 'N', 'N', n, nrhs, cone, a, b,ldb )
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pftrs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spftri( transr, uplo, n, a, info )
     !! SPFTRI computes the inverse of a real (symmetric) positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by SPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(sp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPFTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_stftri( transr, uplo, 'N', n, a, info )
           if( info>0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution of triangular matrix multiply: inv(u)*inv(u)^c or
           ! inv(l)^c*inv(l). there are eight cases.
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                    ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                    ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_slauum( 'L', n1, a( 0_${ik}$ ), n, info )
                    call stdlib${ii}$_ssyrk( 'L', 'T', n1, n2, one, a( n1 ), n, one,a( 0_${ik}$ ), n )
                    call stdlib${ii}$_strmm( 'L', 'U', 'N', 'N', n2, n1, one, a( n ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_slauum( 'U', n2, a( n ), n, info )
                 else
                    ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                    ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                    ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_slauum( 'L', n1, a( n2 ), n, info )
                    call stdlib${ii}$_ssyrk( 'L', 'N', n1, n2, one, a( 0_${ik}$ ), n, one,a( n2 ), n )
                    call stdlib${ii}$_strmm( 'R', 'U', 'T', 'N', n1, n2, one, a( n1 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_slauum( 'U', n2, a( n1 ), n, info )
                 end if
              else
                 ! n is odd and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is odd
                    ! t1 -> a(0), t2 -> a(1), s -> a(0+n1*n1)
                    call stdlib${ii}$_slauum( 'U', n1, a( 0_${ik}$ ), n1, info )
                    call stdlib${ii}$_ssyrk( 'U', 'N', n1, n2, one, a( n1*n1 ), n1, one,a( 0_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_strmm( 'R', 'L', 'N', 'N', n1, n2, one, a( 1_${ik}$ ), n1,a( n1*n1 ), n1 &
                              )
                    call stdlib${ii}$_slauum( 'L', n2, a( 1_${ik}$ ), n1, info )
                 else
                    ! srpa for upper, transpose, and n is odd
                    ! t1 -> a(0+n2*n2), t2 -> a(0+n1*n2), s -> a(0)
                    call stdlib${ii}$_slauum( 'U', n1, a( n2*n2 ), n2, info )
                    call stdlib${ii}$_ssyrk( 'U', 'T', n1, n2, one, a( 0_${ik}$ ), n2, one,a( n2*n2 ), n2 )
                              
                    call stdlib${ii}$_strmm( 'L', 'L', 'T', 'N', n2, n1, one, a( n1*n2 ),n2, a( 0_${ik}$ ), n2 &
                              )
                    call stdlib${ii}$_slauum( 'L', n2, a( n1*n2 ), n2, info )
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_slauum( 'L', k, a( 1_${ik}$ ), n+1, info )
                    call stdlib${ii}$_ssyrk( 'L', 'T', k, k, one, a( k+1 ), n+1, one,a( 1_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_strmm( 'L', 'U', 'N', 'N', k, k, one, a( 0_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_slauum( 'U', k, a( 0_${ik}$ ), n+1, info )
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_slauum( 'L', k, a( k+1 ), n+1, info )
                    call stdlib${ii}$_ssyrk( 'L', 'N', k, k, one, a( 0_${ik}$ ), n+1, one,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_strmm( 'R', 'U', 'T', 'N', k, k, one, a( k ), n+1,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_slauum( 'U', k, a( k ), n+1, info )
                 end if
              else
                 ! n is even and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1),
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_slauum( 'U', k, a( k ), k, info )
                    call stdlib${ii}$_ssyrk( 'U', 'N', k, k, one, a( k*( k+1 ) ), k, one,a( k ), k )
                              
                    call stdlib${ii}$_strmm( 'R', 'L', 'N', 'N', k, k, one, a( 0_${ik}$ ), k,a( k*( k+1 ) ), k &
                              )
                    call stdlib${ii}$_slauum( 'L', k, a( 0_${ik}$ ), k, info )
                 else
                    ! srpa for upper, transpose, and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0),
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_slauum( 'U', k, a( k*( k+1 ) ), k, info )
                    call stdlib${ii}$_ssyrk( 'U', 'T', k, k, one, a( 0_${ik}$ ), k, one,a( k*( k+1 ) ), k )
                              
                    call stdlib${ii}$_strmm( 'L', 'L', 'T', 'N', k, k, one, a( k*k ), k,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_slauum( 'L', k, a( k*k ), k, info )
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_spftri

     pure module subroutine stdlib${ii}$_dpftri( transr, uplo, n, a, info )
     !! DPFTRI computes the inverse of a (real) symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by DPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(dp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPFTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_dtftri( transr, uplo, 'N', n, a, info )
           if( info>0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution of triangular matrix multiply: inv(u)*inv(u)^c or
           ! inv(l)^c*inv(l). there are eight cases.
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                    ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                    ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_dlauum( 'L', n1, a( 0_${ik}$ ), n, info )
                    call stdlib${ii}$_dsyrk( 'L', 'T', n1, n2, one, a( n1 ), n, one,a( 0_${ik}$ ), n )
                    call stdlib${ii}$_dtrmm( 'L', 'U', 'N', 'N', n2, n1, one, a( n ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_dlauum( 'U', n2, a( n ), n, info )
                 else
                    ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                    ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                    ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_dlauum( 'L', n1, a( n2 ), n, info )
                    call stdlib${ii}$_dsyrk( 'L', 'N', n1, n2, one, a( 0_${ik}$ ), n, one,a( n2 ), n )
                    call stdlib${ii}$_dtrmm( 'R', 'U', 'T', 'N', n1, n2, one, a( n1 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_dlauum( 'U', n2, a( n1 ), n, info )
                 end if
              else
                 ! n is odd and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is odd
                    ! t1 -> a(0), t2 -> a(1), s -> a(0+n1*n1)
                    call stdlib${ii}$_dlauum( 'U', n1, a( 0_${ik}$ ), n1, info )
                    call stdlib${ii}$_dsyrk( 'U', 'N', n1, n2, one, a( n1*n1 ), n1, one,a( 0_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_dtrmm( 'R', 'L', 'N', 'N', n1, n2, one, a( 1_${ik}$ ), n1,a( n1*n1 ), n1 &
                              )
                    call stdlib${ii}$_dlauum( 'L', n2, a( 1_${ik}$ ), n1, info )
                 else
                    ! srpa for upper, transpose, and n is odd
                    ! t1 -> a(0+n2*n2), t2 -> a(0+n1*n2), s -> a(0)
                    call stdlib${ii}$_dlauum( 'U', n1, a( n2*n2 ), n2, info )
                    call stdlib${ii}$_dsyrk( 'U', 'T', n1, n2, one, a( 0_${ik}$ ), n2, one,a( n2*n2 ), n2 )
                              
                    call stdlib${ii}$_dtrmm( 'L', 'L', 'T', 'N', n2, n1, one, a( n1*n2 ),n2, a( 0_${ik}$ ), n2 &
                              )
                    call stdlib${ii}$_dlauum( 'L', n2, a( n1*n2 ), n2, info )
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_dlauum( 'L', k, a( 1_${ik}$ ), n+1, info )
                    call stdlib${ii}$_dsyrk( 'L', 'T', k, k, one, a( k+1 ), n+1, one,a( 1_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_dtrmm( 'L', 'U', 'N', 'N', k, k, one, a( 0_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_dlauum( 'U', k, a( 0_${ik}$ ), n+1, info )
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_dlauum( 'L', k, a( k+1 ), n+1, info )
                    call stdlib${ii}$_dsyrk( 'L', 'N', k, k, one, a( 0_${ik}$ ), n+1, one,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_dtrmm( 'R', 'U', 'T', 'N', k, k, one, a( k ), n+1,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_dlauum( 'U', k, a( k ), n+1, info )
                 end if
              else
                 ! n is even and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1),
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_dlauum( 'U', k, a( k ), k, info )
                    call stdlib${ii}$_dsyrk( 'U', 'N', k, k, one, a( k*( k+1 ) ), k, one,a( k ), k )
                              
                    call stdlib${ii}$_dtrmm( 'R', 'L', 'N', 'N', k, k, one, a( 0_${ik}$ ), k,a( k*( k+1 ) ), k &
                              )
                    call stdlib${ii}$_dlauum( 'L', k, a( 0_${ik}$ ), k, info )
                 else
                    ! srpa for upper, transpose, and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0),
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_dlauum( 'U', k, a( k*( k+1 ) ), k, info )
                    call stdlib${ii}$_dsyrk( 'U', 'T', k, k, one, a( 0_${ik}$ ), k, one,a( k*( k+1 ) ), k )
                              
                    call stdlib${ii}$_dtrmm( 'L', 'L', 'T', 'N', k, k, one, a( k*k ), k,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_dlauum( 'L', k, a( k*k ), k, info )
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_dpftri

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pftri( transr, uplo, n, a, info )
     !! DPFTRI: computes the inverse of a (real) symmetric positive definite
     !! matrix A using the Cholesky factorization A = U**T*U or A = L*L**T
     !! computed by DPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'T' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPFTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_${ri}$tftri( transr, uplo, 'N', n, a, info )
           if( info>0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution of triangular matrix multiply: inv(u)*inv(u)^c or
           ! inv(l)^c*inv(l). there are eight cases.
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                    ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                    ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_${ri}$lauum( 'L', n1, a( 0_${ik}$ ), n, info )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'T', n1, n2, one, a( n1 ), n, one,a( 0_${ik}$ ), n )
                    call stdlib${ii}$_${ri}$trmm( 'L', 'U', 'N', 'N', n2, n1, one, a( n ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_${ri}$lauum( 'U', n2, a( n ), n, info )
                 else
                    ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                    ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                    ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_${ri}$lauum( 'L', n1, a( n2 ), n, info )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'N', n1, n2, one, a( 0_${ik}$ ), n, one,a( n2 ), n )
                    call stdlib${ii}$_${ri}$trmm( 'R', 'U', 'T', 'N', n1, n2, one, a( n1 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_${ri}$lauum( 'U', n2, a( n1 ), n, info )
                 end if
              else
                 ! n is odd and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is odd
                    ! t1 -> a(0), t2 -> a(1), s -> a(0+n1*n1)
                    call stdlib${ii}$_${ri}$lauum( 'U', n1, a( 0_${ik}$ ), n1, info )
                    call stdlib${ii}$_${ri}$syrk( 'U', 'N', n1, n2, one, a( n1*n1 ), n1, one,a( 0_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_${ri}$trmm( 'R', 'L', 'N', 'N', n1, n2, one, a( 1_${ik}$ ), n1,a( n1*n1 ), n1 &
                              )
                    call stdlib${ii}$_${ri}$lauum( 'L', n2, a( 1_${ik}$ ), n1, info )
                 else
                    ! srpa for upper, transpose, and n is odd
                    ! t1 -> a(0+n2*n2), t2 -> a(0+n1*n2), s -> a(0)
                    call stdlib${ii}$_${ri}$lauum( 'U', n1, a( n2*n2 ), n2, info )
                    call stdlib${ii}$_${ri}$syrk( 'U', 'T', n1, n2, one, a( 0_${ik}$ ), n2, one,a( n2*n2 ), n2 )
                              
                    call stdlib${ii}$_${ri}$trmm( 'L', 'L', 'T', 'N', n2, n1, one, a( n1*n2 ),n2, a( 0_${ik}$ ), n2 &
                              )
                    call stdlib${ii}$_${ri}$lauum( 'L', n2, a( n1*n2 ), n2, info )
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_${ri}$lauum( 'L', k, a( 1_${ik}$ ), n+1, info )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'T', k, k, one, a( k+1 ), n+1, one,a( 1_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ri}$trmm( 'L', 'U', 'N', 'N', k, k, one, a( 0_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_${ri}$lauum( 'U', k, a( 0_${ik}$ ), n+1, info )
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_${ri}$lauum( 'L', k, a( k+1 ), n+1, info )
                    call stdlib${ii}$_${ri}$syrk( 'L', 'N', k, k, one, a( 0_${ik}$ ), n+1, one,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_${ri}$trmm( 'R', 'U', 'T', 'N', k, k, one, a( k ), n+1,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ri}$lauum( 'U', k, a( k ), n+1, info )
                 end if
              else
                 ! n is even and transr = 't'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1),
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_${ri}$lauum( 'U', k, a( k ), k, info )
                    call stdlib${ii}$_${ri}$syrk( 'U', 'N', k, k, one, a( k*( k+1 ) ), k, one,a( k ), k )
                              
                    call stdlib${ii}$_${ri}$trmm( 'R', 'L', 'N', 'N', k, k, one, a( 0_${ik}$ ), k,a( k*( k+1 ) ), k &
                              )
                    call stdlib${ii}$_${ri}$lauum( 'L', k, a( 0_${ik}$ ), k, info )
                 else
                    ! srpa for upper, transpose, and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0),
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_${ri}$lauum( 'U', k, a( k*( k+1 ) ), k, info )
                    call stdlib${ii}$_${ri}$syrk( 'U', 'T', k, k, one, a( 0_${ik}$ ), k, one,a( k*( k+1 ) ), k )
                              
                    call stdlib${ii}$_${ri}$trmm( 'L', 'L', 'T', 'N', k, k, one, a( k*k ), k,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_${ri}$lauum( 'L', k, a( k*k ), k, info )
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pftri

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpftri( transr, uplo, n, a, info )
     !! CPFTRI computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by CPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           complex(sp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPFTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_ctftri( transr, uplo, 'N', n, a, info )
           if( info>0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution of triangular matrix multiply: inv(u)*inv(u)^c or
           ! inv(l)^c*inv(l). there are eight cases.
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                    ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                    ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_clauum( 'L', n1, a( 0_${ik}$ ), n, info )
                    call stdlib${ii}$_cherk( 'L', 'C', n1, n2, one, a( n1 ), n, one,a( 0_${ik}$ ), n )
                    call stdlib${ii}$_ctrmm( 'L', 'U', 'N', 'N', n2, n1, cone, a( n ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_clauum( 'U', n2, a( n ), n, info )
                 else
                    ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                    ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                    ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_clauum( 'L', n1, a( n2 ), n, info )
                    call stdlib${ii}$_cherk( 'L', 'N', n1, n2, one, a( 0_${ik}$ ), n, one,a( n2 ), n )
                    call stdlib${ii}$_ctrmm( 'R', 'U', 'C', 'N', n1, n2, cone, a( n1 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_clauum( 'U', n2, a( n1 ), n, info )
                 end if
              else
                 ! n is odd and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is odd
                    ! t1 -> a(0), t2 -> a(1), s -> a(0+n1*n1)
                    call stdlib${ii}$_clauum( 'U', n1, a( 0_${ik}$ ), n1, info )
                    call stdlib${ii}$_cherk( 'U', 'N', n1, n2, one, a( n1*n1 ), n1, one,a( 0_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_ctrmm( 'R', 'L', 'N', 'N', n1, n2, cone, a( 1_${ik}$ ), n1,a( n1*n1 ), &
                              n1 )
                    call stdlib${ii}$_clauum( 'L', n2, a( 1_${ik}$ ), n1, info )
                 else
                    ! srpa for upper, transpose, and n is odd
                    ! t1 -> a(0+n2*n2), t2 -> a(0+n1*n2), s -> a(0)
                    call stdlib${ii}$_clauum( 'U', n1, a( n2*n2 ), n2, info )
                    call stdlib${ii}$_cherk( 'U', 'C', n1, n2, one, a( 0_${ik}$ ), n2, one,a( n2*n2 ), n2 )
                              
                    call stdlib${ii}$_ctrmm( 'L', 'L', 'C', 'N', n2, n1, cone, a( n1*n2 ),n2, a( 0_${ik}$ ), &
                              n2 )
                    call stdlib${ii}$_clauum( 'L', n2, a( n1*n2 ), n2, info )
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_clauum( 'L', k, a( 1_${ik}$ ), n+1, info )
                    call stdlib${ii}$_cherk( 'L', 'C', k, k, one, a( k+1 ), n+1, one,a( 1_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_ctrmm( 'L', 'U', 'N', 'N', k, k, cone, a( 0_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_clauum( 'U', k, a( 0_${ik}$ ), n+1, info )
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_clauum( 'L', k, a( k+1 ), n+1, info )
                    call stdlib${ii}$_cherk( 'L', 'N', k, k, one, a( 0_${ik}$ ), n+1, one,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_ctrmm( 'R', 'U', 'C', 'N', k, k, cone, a( k ), n+1,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_clauum( 'U', k, a( k ), n+1, info )
                 end if
              else
                 ! n is even and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1),
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_clauum( 'U', k, a( k ), k, info )
                    call stdlib${ii}$_cherk( 'U', 'N', k, k, one, a( k*( k+1 ) ), k, one,a( k ), k )
                              
                    call stdlib${ii}$_ctrmm( 'R', 'L', 'N', 'N', k, k, cone, a( 0_${ik}$ ), k,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_clauum( 'L', k, a( 0_${ik}$ ), k, info )
                 else
                    ! srpa for upper, transpose, and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0),
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_clauum( 'U', k, a( k*( k+1 ) ), k, info )
                    call stdlib${ii}$_cherk( 'U', 'C', k, k, one, a( 0_${ik}$ ), k, one,a( k*( k+1 ) ), k )
                              
                    call stdlib${ii}$_ctrmm( 'L', 'L', 'C', 'N', k, k, cone, a( k*k ), k,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_clauum( 'L', k, a( k*k ), k, info )
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_cpftri

     pure module subroutine stdlib${ii}$_zpftri( transr, uplo, n, a, info )
     !! ZPFTRI computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by ZPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           complex(dp), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPFTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_ztftri( transr, uplo, 'N', n, a, info )
           if( info>0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution of triangular matrix multiply: inv(u)*inv(u)^c or
           ! inv(l)^c*inv(l). there are eight cases.
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                    ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                    ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_zlauum( 'L', n1, a( 0_${ik}$ ), n, info )
                    call stdlib${ii}$_zherk( 'L', 'C', n1, n2, one, a( n1 ), n, one,a( 0_${ik}$ ), n )
                    call stdlib${ii}$_ztrmm( 'L', 'U', 'N', 'N', n2, n1, cone, a( n ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_zlauum( 'U', n2, a( n ), n, info )
                 else
                    ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                    ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                    ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_zlauum( 'L', n1, a( n2 ), n, info )
                    call stdlib${ii}$_zherk( 'L', 'N', n1, n2, one, a( 0_${ik}$ ), n, one,a( n2 ), n )
                    call stdlib${ii}$_ztrmm( 'R', 'U', 'C', 'N', n1, n2, cone, a( n1 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_zlauum( 'U', n2, a( n1 ), n, info )
                 end if
              else
                 ! n is odd and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is odd
                    ! t1 -> a(0), t2 -> a(1), s -> a(0+n1*n1)
                    call stdlib${ii}$_zlauum( 'U', n1, a( 0_${ik}$ ), n1, info )
                    call stdlib${ii}$_zherk( 'U', 'N', n1, n2, one, a( n1*n1 ), n1, one,a( 0_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_ztrmm( 'R', 'L', 'N', 'N', n1, n2, cone, a( 1_${ik}$ ), n1,a( n1*n1 ), &
                              n1 )
                    call stdlib${ii}$_zlauum( 'L', n2, a( 1_${ik}$ ), n1, info )
                 else
                    ! srpa for upper, transpose, and n is odd
                    ! t1 -> a(0+n2*n2), t2 -> a(0+n1*n2), s -> a(0)
                    call stdlib${ii}$_zlauum( 'U', n1, a( n2*n2 ), n2, info )
                    call stdlib${ii}$_zherk( 'U', 'C', n1, n2, one, a( 0_${ik}$ ), n2, one,a( n2*n2 ), n2 )
                              
                    call stdlib${ii}$_ztrmm( 'L', 'L', 'C', 'N', n2, n1, cone, a( n1*n2 ),n2, a( 0_${ik}$ ), &
                              n2 )
                    call stdlib${ii}$_zlauum( 'L', n2, a( n1*n2 ), n2, info )
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_zlauum( 'L', k, a( 1_${ik}$ ), n+1, info )
                    call stdlib${ii}$_zherk( 'L', 'C', k, k, one, a( k+1 ), n+1, one,a( 1_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_ztrmm( 'L', 'U', 'N', 'N', k, k, cone, a( 0_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_zlauum( 'U', k, a( 0_${ik}$ ), n+1, info )
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_zlauum( 'L', k, a( k+1 ), n+1, info )
                    call stdlib${ii}$_zherk( 'L', 'N', k, k, one, a( 0_${ik}$ ), n+1, one,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_ztrmm( 'R', 'U', 'C', 'N', k, k, cone, a( k ), n+1,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_zlauum( 'U', k, a( k ), n+1, info )
                 end if
              else
                 ! n is even and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1),
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_zlauum( 'U', k, a( k ), k, info )
                    call stdlib${ii}$_zherk( 'U', 'N', k, k, one, a( k*( k+1 ) ), k, one,a( k ), k )
                              
                    call stdlib${ii}$_ztrmm( 'R', 'L', 'N', 'N', k, k, cone, a( 0_${ik}$ ), k,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_zlauum( 'L', k, a( 0_${ik}$ ), k, info )
                 else
                    ! srpa for upper, transpose, and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0),
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_zlauum( 'U', k, a( k*( k+1 ) ), k, info )
                    call stdlib${ii}$_zherk( 'U', 'C', k, k, one, a( 0_${ik}$ ), k, one,a( k*( k+1 ) ), k )
                              
                    call stdlib${ii}$_ztrmm( 'L', 'L', 'C', 'N', k, k, cone, a( k*k ), k,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_zlauum( 'L', k, a( k*k ), k, info )
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_zpftri

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pftri( transr, uplo, n, a, info )
     !! ZPFTRI: computes the inverse of a complex Hermitian positive definite
     !! matrix A using the Cholesky factorization A = U**H*U or A = L*L**H
     !! computed by ZPFTRF.
        ! -- 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) :: transr, uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: a(0_${ik}$:*)
        ! =====================================================================
           
           
           ! Local Scalars 
           logical(lk) :: lower, nisodd, normaltransr
           integer(${ik}$) :: n1, n2, k
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           normaltransr = stdlib_lsame( transr, 'N' )
           lower = stdlib_lsame( uplo, 'L' )
           if( .not.normaltransr .and. .not.stdlib_lsame( transr, 'C' ) ) then
              info = -1_${ik}$
           else if( .not.lower .and. .not.stdlib_lsame( uplo, 'U' ) ) then
              info = -2_${ik}$
           else if( n<0_${ik}$ ) then
              info = -3_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPFTRI', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! invert the triangular cholesky factor u or l.
           call stdlib${ii}$_${ci}$tftri( transr, uplo, 'N', n, a, info )
           if( info>0 )return
           ! if n is odd, set nisodd = .true.
           ! if n is even, set k = n/2 and nisodd = .false.
           if( mod( n, 2_${ik}$ )==0_${ik}$ ) then
              k = n / 2_${ik}$
              nisodd = .false.
           else
              nisodd = .true.
           end if
           ! set n1 and n2 depending on lower
           if( lower ) then
              n2 = n / 2_${ik}$
              n1 = n - n2
           else
              n1 = n / 2_${ik}$
              n2 = n - n1
           end if
           ! start execution of triangular matrix multiply: inv(u)*inv(u)^c or
           ! inv(l)^c*inv(l). there are eight cases.
           if( nisodd ) then
              ! n is odd
              if( normaltransr ) then
                 ! n is odd and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal and n is odd ( a(0:n-1,0:n1-1) )
                    ! t1 -> a(0,0), t2 -> a(0,1), s -> a(n1,0)
                    ! t1 -> a(0), t2 -> a(n), s -> a(n1)
                    call stdlib${ii}$_${ci}$lauum( 'L', n1, a( 0_${ik}$ ), n, info )
                    call stdlib${ii}$_${ci}$herk( 'L', 'C', n1, n2, one, a( n1 ), n, one,a( 0_${ik}$ ), n )
                    call stdlib${ii}$_${ci}$trmm( 'L', 'U', 'N', 'N', n2, n1, cone, a( n ), n,a( n1 ), n )
                              
                    call stdlib${ii}$_${ci}$lauum( 'U', n2, a( n ), n, info )
                 else
                    ! srpa for upper, normal and n is odd ( a(0:n-1,0:n2-1)
                    ! t1 -> a(n1+1,0), t2 -> a(n1,0), s -> a(0,0)
                    ! t1 -> a(n2), t2 -> a(n1), s -> a(0)
                    call stdlib${ii}$_${ci}$lauum( 'L', n1, a( n2 ), n, info )
                    call stdlib${ii}$_${ci}$herk( 'L', 'N', n1, n2, one, a( 0_${ik}$ ), n, one,a( n2 ), n )
                    call stdlib${ii}$_${ci}$trmm( 'R', 'U', 'C', 'N', n1, n2, cone, a( n1 ), n,a( 0_${ik}$ ), n )
                              
                    call stdlib${ii}$_${ci}$lauum( 'U', n2, a( n1 ), n, info )
                 end if
              else
                 ! n is odd and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is odd
                    ! t1 -> a(0), t2 -> a(1), s -> a(0+n1*n1)
                    call stdlib${ii}$_${ci}$lauum( 'U', n1, a( 0_${ik}$ ), n1, info )
                    call stdlib${ii}$_${ci}$herk( 'U', 'N', n1, n2, one, a( n1*n1 ), n1, one,a( 0_${ik}$ ), n1 )
                              
                    call stdlib${ii}$_${ci}$trmm( 'R', 'L', 'N', 'N', n1, n2, cone, a( 1_${ik}$ ), n1,a( n1*n1 ), &
                              n1 )
                    call stdlib${ii}$_${ci}$lauum( 'L', n2, a( 1_${ik}$ ), n1, info )
                 else
                    ! srpa for upper, transpose, and n is odd
                    ! t1 -> a(0+n2*n2), t2 -> a(0+n1*n2), s -> a(0)
                    call stdlib${ii}$_${ci}$lauum( 'U', n1, a( n2*n2 ), n2, info )
                    call stdlib${ii}$_${ci}$herk( 'U', 'C', n1, n2, one, a( 0_${ik}$ ), n2, one,a( n2*n2 ), n2 )
                              
                    call stdlib${ii}$_${ci}$trmm( 'L', 'L', 'C', 'N', n2, n1, cone, a( n1*n2 ),n2, a( 0_${ik}$ ), &
                              n2 )
                    call stdlib${ii}$_${ci}$lauum( 'L', n2, a( n1*n2 ), n2, info )
                 end if
              end if
           else
              ! n is even
              if( normaltransr ) then
                 ! n is even and transr = 'n'
                 if( lower ) then
                    ! srpa for lower, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(1,0), t2 -> a(0,0), s -> a(k+1,0)
                    ! t1 -> a(1), t2 -> a(0), s -> a(k+1)
                    call stdlib${ii}$_${ci}$lauum( 'L', k, a( 1_${ik}$ ), n+1, info )
                    call stdlib${ii}$_${ci}$herk( 'L', 'C', k, k, one, a( k+1 ), n+1, one,a( 1_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ci}$trmm( 'L', 'U', 'N', 'N', k, k, cone, a( 0_${ik}$ ), n+1,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_${ci}$lauum( 'U', k, a( 0_${ik}$ ), n+1, info )
                 else
                    ! srpa for upper, normal, and n is even ( a(0:n,0:k-1) )
                    ! t1 -> a(k+1,0) ,  t2 -> a(k,0),   s -> a(0,0)
                    ! t1 -> a(k+1), t2 -> a(k), s -> a(0)
                    call stdlib${ii}$_${ci}$lauum( 'L', k, a( k+1 ), n+1, info )
                    call stdlib${ii}$_${ci}$herk( 'L', 'N', k, k, one, a( 0_${ik}$ ), n+1, one,a( k+1 ), n+1 )
                              
                    call stdlib${ii}$_${ci}$trmm( 'R', 'U', 'C', 'N', k, k, cone, a( k ), n+1,a( 0_${ik}$ ), n+1 )
                              
                    call stdlib${ii}$_${ci}$lauum( 'U', k, a( k ), n+1, info )
                 end if
              else
                 ! n is even and transr = 'c'
                 if( lower ) then
                    ! srpa for lower, transpose, and n is even (see paper)
                    ! t1 -> b(0,1), t2 -> b(0,0), s -> b(0,k+1),
                    ! t1 -> a(0+k), t2 -> a(0+0), s -> a(0+k*(k+1)); lda=k
                    call stdlib${ii}$_${ci}$lauum( 'U', k, a( k ), k, info )
                    call stdlib${ii}$_${ci}$herk( 'U', 'N', k, k, one, a( k*( k+1 ) ), k, one,a( k ), k )
                              
                    call stdlib${ii}$_${ci}$trmm( 'R', 'L', 'N', 'N', k, k, cone, a( 0_${ik}$ ), k,a( k*( k+1 ) ), &
                              k )
                    call stdlib${ii}$_${ci}$lauum( 'L', k, a( 0_${ik}$ ), k, info )
                 else
                    ! srpa for upper, transpose, and n is even (see paper)
                    ! t1 -> b(0,k+1),     t2 -> b(0,k),   s -> b(0,0),
                    ! t1 -> a(0+k*(k+1)), t2 -> a(0+k*k), s -> a(0+0)); lda=k
                    call stdlib${ii}$_${ci}$lauum( 'U', k, a( k*( k+1 ) ), k, info )
                    call stdlib${ii}$_${ci}$herk( 'U', 'C', k, k, one, a( 0_${ik}$ ), k, one,a( k*( k+1 ) ), k )
                              
                    call stdlib${ii}$_${ci}$trmm( 'L', 'L', 'C', 'N', k, k, cone, a( k*k ), k,a( 0_${ik}$ ), k )
                              
                    call stdlib${ii}$_${ci}$lauum( 'L', k, a( k*k ), k, info )
                 end if
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pftri

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spbcon( uplo, n, kd, ab, ldab, anorm, rcond, work,iwork, info )
     !! SPBCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite band matrix using the
     !! Cholesky factorization A = U**T*U or A = L*L**T computed by SPBTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
               
        ! -- 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) :: kd, ldab, n
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(in) :: ab(ldab,*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(sp) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           else if( anorm<zero ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPBCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_slacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_slatbs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, work( 2_${ik}$*n+1 ),info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_slatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, work( 2_${ik}$*n+1 ),info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_slatbs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, work( 2_${ik}$*n+1 ),info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_slatbs( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, work( 2_${ik}$*n+1 ),info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_srscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_spbcon

     pure module subroutine stdlib${ii}$_dpbcon( uplo, n, kd, ab, ldab, anorm, rcond, work,iwork, info )
     !! DPBCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite band matrix using the
     !! Cholesky factorization A = U**T*U or A = L*L**T computed by DPBTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
               
        ! -- 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) :: kd, ldab, n
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(in) :: ab(ldab,*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(dp) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           else if( anorm<zero ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_dlacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_dlatbs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, work( 2_${ik}$*n+1 ),info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_dlatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, work( 2_${ik}$*n+1 ),info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_dlatbs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, work( 2_${ik}$*n+1 ),info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_dlatbs( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, work( 2_${ik}$*n+1 ),info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_drscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_dpbcon

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pbcon( uplo, n, kd, ab, ldab, anorm, rcond, work,iwork, info )
     !! DPBCON: estimates the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite band matrix using the
     !! Cholesky factorization A = U**T*U or A = L*L**T computed by DPBTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
               
        ! -- 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) :: kd, ldab, n
           real(${rk}$), intent(in) :: anorm
           real(${rk}$), intent(out) :: rcond
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(in) :: ab(ldab,*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(${rk}$) :: ainvnm, scale, scalel, scaleu, smlnum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           else if( anorm<zero ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_${ri}$lacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**t).
                 call stdlib${ii}$_${ri}$latbs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, work( 2_${ik}$*n+1 ),info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_${ri}$latbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, work( 2_${ik}$*n+1 ),info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_${ri}$latbs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, work( 2_${ik}$*n+1 ),info )
                 normin = 'Y'
                 ! multiply by inv(l**t).
                 call stdlib${ii}$_${ri}$latbs( 'LOWER', 'TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, work( 2_${ik}$*n+1 ),info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_i${ri}$amax( n, work, 1_${ik}$ )
                 if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_${ri}$rscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_${ri}$pbcon

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpbcon( uplo, n, kd, ab, ldab, anorm, rcond, work,rwork, info )
     !! CPBCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite band matrix using
     !! the Cholesky factorization A = U**H*U or A = L*L**H computed by
     !! CPBTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
               
        ! -- 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) :: kd, ldab, n
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(in) :: ab(ldab,*)
           complex(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(sp) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(sp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           else if( anorm<zero ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPBCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_clacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_clatbs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kd, ab,&
                            ldab, work, scalel, rwork,info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_clatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_clatbs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_clatbs( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kd, ab,&
                            ldab, work, scaleu, rwork,info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_icamax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_csrscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_cpbcon

     pure module subroutine stdlib${ii}$_zpbcon( uplo, n, kd, ab, ldab, anorm, rcond, work,rwork, info )
     !! ZPBCON estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite band matrix using
     !! the Cholesky factorization A = U**H*U or A = L*L**H computed by
     !! ZPBTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
               
        ! -- 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) :: kd, ldab, n
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(in) :: ab(ldab,*)
           complex(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(dp) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(dp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           else if( anorm<zero ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_zlatbs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kd, ab,&
                            ldab, work, scalel, rwork,info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_zlatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_zlatbs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_zlatbs( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kd, ab,&
                            ldab, work, scaleu, rwork,info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_izamax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_zdrscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_zpbcon

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pbcon( uplo, n, kd, ab, ldab, anorm, rcond, work,rwork, info )
     !! ZPBCON: estimates the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite band matrix using
     !! the Cholesky factorization A = U**H*U or A = L*L**H computed by
     !! ZPBTRF.
     !! An estimate is obtained for norm(inv(A)), and the reciprocal of the
     !! condition number is computed as RCOND = 1 / (ANORM * norm(inv(A))).
               
        ! -- 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) :: kd, ldab, n
           real(${ck}$), intent(in) :: anorm
           real(${ck}$), intent(out) :: rcond
           ! Array Arguments 
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(in) :: ab(ldab,*)
           complex(${ck}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           character :: normin
           integer(${ik}$) :: ix, kase
           real(${ck}$) :: ainvnm, scale, scalel, scaleu, smlnum
           complex(${ck}$) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           else if( anorm<zero ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           ! estimate the 1-norm of the inverse.
           kase = 0_${ik}$
           normin = 'N'
           10 continue
           call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ainvnm, kase, isave )
           if( kase/=0_${ik}$ ) then
              if( upper ) then
                 ! multiply by inv(u**h).
                 call stdlib${ii}$_${ci}$latbs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kd, ab,&
                            ldab, work, scalel, rwork,info )
                 normin = 'Y'
                 ! multiply by inv(u).
                 call stdlib${ii}$_${ci}$latbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scaleu, rwork, info )
              else
                 ! multiply by inv(l).
                 call stdlib${ii}$_${ci}$latbs( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kd, ab, ldab, &
                           work, scalel, rwork, info )
                 normin = 'Y'
                 ! multiply by inv(l**h).
                 call stdlib${ii}$_${ci}$latbs( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kd, ab,&
                            ldab, work, scaleu, rwork,info )
              end if
              ! multiply by 1/scale if doing so will not cause overflow.
              scale = scalel*scaleu
              if( scale/=one ) then
                 ix = stdlib${ii}$_i${ci}$amax( n, work, 1_${ik}$ )
                 if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 20
                 call stdlib${ii}$_${ci}$drscl( n, scale, work, 1_${ik}$ )
              end if
              go to 10
           end if
           ! compute the estimate of the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           20 continue
           return
     end subroutine stdlib${ii}$_${ci}$pbcon

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spbtrf( uplo, n, kd, ab, ldab, info )
     !! SPBTRF computes the Cholesky factorization of a real symmetric
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           real(sp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 32_${ik}$
           integer(${ik}$), parameter :: ldwork = nbmax+1
           
           
           ! Local Scalars 
           integer(${ik}$) :: i, i2, i3, ib, ii, j, jj, nb
           ! Local Arrays 
           real(sp) :: work(ldwork,nbmax)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( ( .not.stdlib_lsame( uplo, 'U' ) ) .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( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPBTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SPBTRF', uplo, n, kd, -1_${ik}$, -1_${ik}$ )
           ! the block size must not exceed the semi-bandwidth kd, and must not
           ! exceed the limit set by the size of the local array work.
           nb = min( nb, nbmax )
           if( nb<=1_${ik}$ .or. nb>kd ) then
              ! use unblocked code
              call stdlib${ii}$_spbtf2( uplo, n, kd, ab, ldab, info )
           else
              ! use blocked code
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! compute the cholesky factorization of a symmetric band
                 ! matrix, given the upper triangle of the matrix in band
                 ! storage.
                 ! zero the upper triangle of the work array.
                 do j = 1, nb
                    do i = 1, j - 1
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_70: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_spotf2( uplo, ib, ab( kd+1, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11   a12   a13
                                ! a22   a23
                                      ! a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a12, a22 and
                       ! a23 are empty if ib = kd. the upper triangle of a13
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a12
                          call stdlib${ii}$_strsm( 'LEFT', 'UPPER', 'TRANSPOSE','NON-UNIT', ib, i2, one,&
                                     ab( kd+1, i ),ldab-1, ab( kd+1-ib, i+ib ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_ssyrk( 'UPPER', 'TRANSPOSE', i2, ib, -one,ab( kd+1-ib, i+ib &
                                    ), ldab-1, one,ab( kd+1, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the lower triangle of a13 into the work array.
                          do jj = 1, i3
                             do ii = jj, ib
                                work( ii, jj ) = ab( ii-jj+1, jj+i+kd-1 )
                             end do
                          end do
                          ! update a13 (in the work array).
                          call stdlib${ii}$_strsm( 'LEFT', 'UPPER', 'TRANSPOSE','NON-UNIT', ib, i3, one,&
                                     ab( kd+1, i ),ldab-1, work, ldwork )
                          ! update a23
                          if( i2>0_${ik}$ )call stdlib${ii}$_sgemm( 'TRANSPOSE', 'NO TRANSPOSE', i2, i3,ib, -&
                          one, ab( kd+1-ib, i+ib ),ldab-1, work, ldwork, one,ab( 1_${ik}$+ib, i+kd ), &
                                    ldab-1 )
                          ! update a33
                          call stdlib${ii}$_ssyrk( 'UPPER', 'TRANSPOSE', i3, ib, -one,work, ldwork, one,&
                                     ab( kd+1, i+kd ),ldab-1 )
                          ! copy the lower triangle of a13 back into place.
                          do jj = 1, i3
                             do ii = jj, ib
                                ab( ii-jj+1, jj+i+kd-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_70
              else
                 ! compute the cholesky factorization of a symmetric band
                 ! matrix, given the lower triangle of the matrix in band
                 ! storage.
                 ! zero the lower triangle of the work array.
                 do j = 1, nb
                    do i = j + 1, nb
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_140: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_spotf2( uplo, ib, ab( 1_${ik}$, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11
                          ! a21   a22
                          ! a31   a32   a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a21, a22 and
                       ! a32 are empty if ib = kd. the lower triangle of a31
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a21
                          call stdlib${ii}$_strsm( 'RIGHT', 'LOWER', 'TRANSPOSE','NON-UNIT', i2, ib, &
                                    one, ab( 1_${ik}$, i ),ldab-1, ab( 1_${ik}$+ib, i ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_ssyrk( 'LOWER', 'NO TRANSPOSE', i2, ib, -one,ab( 1_${ik}$+ib, i ), &
                                    ldab-1, one,ab( 1_${ik}$, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the upper triangle of a31 into the work array.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                work( ii, jj ) = ab( kd+1-jj+ii, jj+i-1 )
                             end do
                          end do
                          ! update a31 (in the work array).
                          call stdlib${ii}$_strsm( 'RIGHT', 'LOWER', 'TRANSPOSE','NON-UNIT', i3, ib, &
                                    one, ab( 1_${ik}$, i ),ldab-1, work, ldwork )
                          ! update a32
                          if( i2>0_${ik}$ )call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'TRANSPOSE', i3, i2,ib, -&
                          one, work, ldwork,ab( 1_${ik}$+ib, i ), ldab-1, one,ab( 1_${ik}$+kd-ib, i+ib ), ldab-&
                                    1_${ik}$ )
                          ! update a33
                          call stdlib${ii}$_ssyrk( 'LOWER', 'NO TRANSPOSE', i3, ib, -one,work, ldwork, &
                                    one, ab( 1_${ik}$, i+kd ),ldab-1 )
                          ! copy the upper triangle of a31 back into place.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                ab( kd+1-jj+ii, jj+i-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_140
              end if
           end if
           return
           150 continue
           return
     end subroutine stdlib${ii}$_spbtrf

     pure module subroutine stdlib${ii}$_dpbtrf( uplo, n, kd, ab, ldab, info )
     !! DPBTRF computes the Cholesky factorization of a real symmetric
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           real(dp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 32_${ik}$
           integer(${ik}$), parameter :: ldwork = nbmax+1
           
           
           ! Local Scalars 
           integer(${ik}$) :: i, i2, i3, ib, ii, j, jj, nb
           ! Local Arrays 
           real(dp) :: work(ldwork,nbmax)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( ( .not.stdlib_lsame( uplo, 'U' ) ) .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( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DPBTRF', uplo, n, kd, -1_${ik}$, -1_${ik}$ )
           ! the block size must not exceed the semi-bandwidth kd, and must not
           ! exceed the limit set by the size of the local array work.
           nb = min( nb, nbmax )
           if( nb<=1_${ik}$ .or. nb>kd ) then
              ! use unblocked code
              call stdlib${ii}$_dpbtf2( uplo, n, kd, ab, ldab, info )
           else
              ! use blocked code
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! compute the cholesky factorization of a symmetric band
                 ! matrix, given the upper triangle of the matrix in band
                 ! storage.
                 ! zero the upper triangle of the work array.
                 do j = 1, nb
                    do i = 1, j - 1
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_70: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_dpotf2( uplo, ib, ab( kd+1, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11   a12   a13
                                ! a22   a23
                                      ! a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a12, a22 and
                       ! a23 are empty if ib = kd. the upper triangle of a13
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a12
                          call stdlib${ii}$_dtrsm( 'LEFT', 'UPPER', 'TRANSPOSE','NON-UNIT', ib, i2, one,&
                                     ab( kd+1, i ),ldab-1, ab( kd+1-ib, i+ib ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_dsyrk( 'UPPER', 'TRANSPOSE', i2, ib, -one,ab( kd+1-ib, i+ib &
                                    ), ldab-1, one,ab( kd+1, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the lower triangle of a13 into the work array.
                          do jj = 1, i3
                             do ii = jj, ib
                                work( ii, jj ) = ab( ii-jj+1, jj+i+kd-1 )
                             end do
                          end do
                          ! update a13 (in the work array).
                          call stdlib${ii}$_dtrsm( 'LEFT', 'UPPER', 'TRANSPOSE','NON-UNIT', ib, i3, one,&
                                     ab( kd+1, i ),ldab-1, work, ldwork )
                          ! update a23
                          if( i2>0_${ik}$ )call stdlib${ii}$_dgemm( 'TRANSPOSE', 'NO TRANSPOSE', i2, i3,ib, -&
                          one, ab( kd+1-ib, i+ib ),ldab-1, work, ldwork, one,ab( 1_${ik}$+ib, i+kd ), &
                                    ldab-1 )
                          ! update a33
                          call stdlib${ii}$_dsyrk( 'UPPER', 'TRANSPOSE', i3, ib, -one,work, ldwork, one,&
                                     ab( kd+1, i+kd ),ldab-1 )
                          ! copy the lower triangle of a13 back into place.
                          do jj = 1, i3
                             do ii = jj, ib
                                ab( ii-jj+1, jj+i+kd-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_70
              else
                 ! compute the cholesky factorization of a symmetric band
                 ! matrix, given the lower triangle of the matrix in band
                 ! storage.
                 ! zero the lower triangle of the work array.
                 do j = 1, nb
                    do i = j + 1, nb
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_140: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_dpotf2( uplo, ib, ab( 1_${ik}$, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11
                          ! a21   a22
                          ! a31   a32   a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a21, a22 and
                       ! a32 are empty if ib = kd. the lower triangle of a31
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a21
                          call stdlib${ii}$_dtrsm( 'RIGHT', 'LOWER', 'TRANSPOSE','NON-UNIT', i2, ib, &
                                    one, ab( 1_${ik}$, i ),ldab-1, ab( 1_${ik}$+ib, i ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_dsyrk( 'LOWER', 'NO TRANSPOSE', i2, ib, -one,ab( 1_${ik}$+ib, i ), &
                                    ldab-1, one,ab( 1_${ik}$, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the upper triangle of a31 into the work array.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                work( ii, jj ) = ab( kd+1-jj+ii, jj+i-1 )
                             end do
                          end do
                          ! update a31 (in the work array).
                          call stdlib${ii}$_dtrsm( 'RIGHT', 'LOWER', 'TRANSPOSE','NON-UNIT', i3, ib, &
                                    one, ab( 1_${ik}$, i ),ldab-1, work, ldwork )
                          ! update a32
                          if( i2>0_${ik}$ )call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'TRANSPOSE', i3, i2,ib, -&
                          one, work, ldwork,ab( 1_${ik}$+ib, i ), ldab-1, one,ab( 1_${ik}$+kd-ib, i+ib ), ldab-&
                                    1_${ik}$ )
                          ! update a33
                          call stdlib${ii}$_dsyrk( 'LOWER', 'NO TRANSPOSE', i3, ib, -one,work, ldwork, &
                                    one, ab( 1_${ik}$, i+kd ),ldab-1 )
                          ! copy the upper triangle of a31 back into place.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                ab( kd+1-jj+ii, jj+i-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_140
              end if
           end if
           return
           150 continue
           return
     end subroutine stdlib${ii}$_dpbtrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pbtrf( uplo, n, kd, ab, ldab, info )
     !! DPBTRF: computes the Cholesky factorization of a real symmetric
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**T * U,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 32_${ik}$
           integer(${ik}$), parameter :: ldwork = nbmax+1
           
           
           ! Local Scalars 
           integer(${ik}$) :: i, i2, i3, ib, ii, j, jj, nb
           ! Local Arrays 
           real(${rk}$) :: work(ldwork,nbmax)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( ( .not.stdlib_lsame( uplo, 'U' ) ) .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( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DPBTRF', uplo, n, kd, -1_${ik}$, -1_${ik}$ )
           ! the block size must not exceed the semi-bandwidth kd, and must not
           ! exceed the limit set by the size of the local array work.
           nb = min( nb, nbmax )
           if( nb<=1_${ik}$ .or. nb>kd ) then
              ! use unblocked code
              call stdlib${ii}$_${ri}$pbtf2( uplo, n, kd, ab, ldab, info )
           else
              ! use blocked code
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! compute the cholesky factorization of a symmetric band
                 ! matrix, given the upper triangle of the matrix in band
                 ! storage.
                 ! zero the upper triangle of the work array.
                 do j = 1, nb
                    do i = 1, j - 1
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_70: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_${ri}$potf2( uplo, ib, ab( kd+1, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11   a12   a13
                                ! a22   a23
                                      ! a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a12, a22 and
                       ! a23 are empty if ib = kd. the upper triangle of a13
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a12
                          call stdlib${ii}$_${ri}$trsm( 'LEFT', 'UPPER', 'TRANSPOSE','NON-UNIT', ib, i2, one,&
                                     ab( kd+1, i ),ldab-1, ab( kd+1-ib, i+ib ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_${ri}$syrk( 'UPPER', 'TRANSPOSE', i2, ib, -one,ab( kd+1-ib, i+ib &
                                    ), ldab-1, one,ab( kd+1, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the lower triangle of a13 into the work array.
                          do jj = 1, i3
                             do ii = jj, ib
                                work( ii, jj ) = ab( ii-jj+1, jj+i+kd-1 )
                             end do
                          end do
                          ! update a13 (in the work array).
                          call stdlib${ii}$_${ri}$trsm( 'LEFT', 'UPPER', 'TRANSPOSE','NON-UNIT', ib, i3, one,&
                                     ab( kd+1, i ),ldab-1, work, ldwork )
                          ! update a23
                          if( i2>0_${ik}$ )call stdlib${ii}$_${ri}$gemm( 'TRANSPOSE', 'NO TRANSPOSE', i2, i3,ib, -&
                          one, ab( kd+1-ib, i+ib ),ldab-1, work, ldwork, one,ab( 1_${ik}$+ib, i+kd ), &
                                    ldab-1 )
                          ! update a33
                          call stdlib${ii}$_${ri}$syrk( 'UPPER', 'TRANSPOSE', i3, ib, -one,work, ldwork, one,&
                                     ab( kd+1, i+kd ),ldab-1 )
                          ! copy the lower triangle of a13 back into place.
                          do jj = 1, i3
                             do ii = jj, ib
                                ab( ii-jj+1, jj+i+kd-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_70
              else
                 ! compute the cholesky factorization of a symmetric band
                 ! matrix, given the lower triangle of the matrix in band
                 ! storage.
                 ! zero the lower triangle of the work array.
                 do j = 1, nb
                    do i = j + 1, nb
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_140: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_${ri}$potf2( uplo, ib, ab( 1_${ik}$, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11
                          ! a21   a22
                          ! a31   a32   a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a21, a22 and
                       ! a32 are empty if ib = kd. the lower triangle of a31
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a21
                          call stdlib${ii}$_${ri}$trsm( 'RIGHT', 'LOWER', 'TRANSPOSE','NON-UNIT', i2, ib, &
                                    one, ab( 1_${ik}$, i ),ldab-1, ab( 1_${ik}$+ib, i ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_${ri}$syrk( 'LOWER', 'NO TRANSPOSE', i2, ib, -one,ab( 1_${ik}$+ib, i ), &
                                    ldab-1, one,ab( 1_${ik}$, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the upper triangle of a31 into the work array.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                work( ii, jj ) = ab( kd+1-jj+ii, jj+i-1 )
                             end do
                          end do
                          ! update a31 (in the work array).
                          call stdlib${ii}$_${ri}$trsm( 'RIGHT', 'LOWER', 'TRANSPOSE','NON-UNIT', i3, ib, &
                                    one, ab( 1_${ik}$, i ),ldab-1, work, ldwork )
                          ! update a32
                          if( i2>0_${ik}$ )call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'TRANSPOSE', i3, i2,ib, -&
                          one, work, ldwork,ab( 1_${ik}$+ib, i ), ldab-1, one,ab( 1_${ik}$+kd-ib, i+ib ), ldab-&
                                    1_${ik}$ )
                          ! update a33
                          call stdlib${ii}$_${ri}$syrk( 'LOWER', 'NO TRANSPOSE', i3, ib, -one,work, ldwork, &
                                    one, ab( 1_${ik}$, i+kd ),ldab-1 )
                          ! copy the upper triangle of a31 back into place.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                ab( kd+1-jj+ii, jj+i-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_140
              end if
           end if
           return
           150 continue
           return
     end subroutine stdlib${ii}$_${ri}$pbtrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpbtrf( uplo, n, kd, ab, ldab, info )
     !! CPBTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           complex(sp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 32_${ik}$
           integer(${ik}$), parameter :: ldwork = nbmax+1
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: i, i2, i3, ib, ii, j, jj, nb
           ! Local Arrays 
           complex(sp) :: work(ldwork,nbmax)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( ( .not.stdlib_lsame( uplo, 'U' ) ) .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( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPBTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CPBTRF', uplo, n, kd, -1_${ik}$, -1_${ik}$ )
           ! the block size must not exceed the semi-bandwidth kd, and must not
           ! exceed the limit set by the size of the local array work.
           nb = min( nb, nbmax )
           if( nb<=1_${ik}$ .or. nb>kd ) then
              ! use unblocked code
              call stdlib${ii}$_cpbtf2( uplo, n, kd, ab, ldab, info )
           else
              ! use blocked code
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! compute the cholesky factorization of a hermitian band
                 ! matrix, given the upper triangle of the matrix in band
                 ! storage.
                 ! zero the upper triangle of the work array.
                 do j = 1, nb
                    do i = 1, j - 1
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_70: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_cpotf2( uplo, ib, ab( kd+1, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11   a12   a13
                                ! a22   a23
                                      ! a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a12, a22 and
                       ! a23 are empty if ib = kd. the upper triangle of a13
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a12
                          call stdlib${ii}$_ctrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', &
                                    ib, i2, cone,ab( kd+1, i ), ldab-1,ab( kd+1-ib, i+ib ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_cherk( 'UPPER', 'CONJUGATE TRANSPOSE', i2, ib,-one, ab( kd+&
                                    1_${ik}$-ib, i+ib ), ldab-1, one,ab( kd+1, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the lower triangle of a13 into the work array.
                          do jj = 1, i3
                             do ii = jj, ib
                                work( ii, jj ) = ab( ii-jj+1, jj+i+kd-1 )
                             end do
                          end do
                          ! update a13 (in the work array).
                          call stdlib${ii}$_ctrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', &
                                    ib, i3, cone,ab( kd+1, i ), ldab-1, work, ldwork )
                          ! update a23
                          if( i2>0_${ik}$ )call stdlib${ii}$_cgemm( 'CONJUGATE TRANSPOSE','NO TRANSPOSE', i2, &
                          i3, ib, -cone,ab( kd+1-ib, i+ib ), ldab-1, work,ldwork, cone, ab( 1_${ik}$+ib, &
                                    i+kd ),ldab-1 )
                          ! update a33
                          call stdlib${ii}$_cherk( 'UPPER', 'CONJUGATE TRANSPOSE', i3, ib,-one, work, &
                                    ldwork, one,ab( kd+1, i+kd ), ldab-1 )
                          ! copy the lower triangle of a13 back into place.
                          do jj = 1, i3
                             do ii = jj, ib
                                ab( ii-jj+1, jj+i+kd-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_70
              else
                 ! compute the cholesky factorization of a hermitian band
                 ! matrix, given the lower triangle of the matrix in band
                 ! storage.
                 ! zero the lower triangle of the work array.
                 do j = 1, nb
                    do i = j + 1, nb
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_140: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_cpotf2( uplo, ib, ab( 1_${ik}$, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11
                          ! a21   a22
                          ! a31   a32   a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a21, a22 and
                       ! a32 are empty if ib = kd. the lower triangle of a31
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a21
                          call stdlib${ii}$_ctrsm( 'RIGHT', 'LOWER','CONJUGATE TRANSPOSE', 'NON-UNIT', &
                                    i2,ib, cone, ab( 1_${ik}$, i ), ldab-1,ab( 1_${ik}$+ib, i ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_cherk( 'LOWER', 'NO TRANSPOSE', i2, ib, -one,ab( 1_${ik}$+ib, i ), &
                                    ldab-1, one,ab( 1_${ik}$, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the upper triangle of a31 into the work array.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                work( ii, jj ) = ab( kd+1-jj+ii, jj+i-1 )
                             end do
                          end do
                          ! update a31 (in the work array).
                          call stdlib${ii}$_ctrsm( 'RIGHT', 'LOWER','CONJUGATE TRANSPOSE', 'NON-UNIT', &
                                    i3,ib, cone, ab( 1_${ik}$, i ), ldab-1, work,ldwork )
                          ! update a32
                          if( i2>0_${ik}$ )call stdlib${ii}$_cgemm( 'NO TRANSPOSE','CONJUGATE TRANSPOSE', i3, &
                          i2, ib,-cone, work, ldwork, ab( 1_${ik}$+ib, i ),ldab-1, cone, ab( 1_${ik}$+kd-ib, i+&
                                    ib ),ldab-1 )
                          ! update a33
                          call stdlib${ii}$_cherk( 'LOWER', 'NO TRANSPOSE', i3, ib, -one,work, ldwork, &
                                    one, ab( 1_${ik}$, i+kd ),ldab-1 )
                          ! copy the upper triangle of a31 back into place.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                ab( kd+1-jj+ii, jj+i-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_140
              end if
           end if
           return
           150 continue
           return
     end subroutine stdlib${ii}$_cpbtrf

     pure module subroutine stdlib${ii}$_zpbtrf( uplo, n, kd, ab, ldab, info )
     !! ZPBTRF computes the Cholesky factorization of a complex Hermitian
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           complex(dp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 32_${ik}$
           integer(${ik}$), parameter :: ldwork = nbmax+1
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: i, i2, i3, ib, ii, j, jj, nb
           ! Local Arrays 
           complex(dp) :: work(ldwork,nbmax)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( ( .not.stdlib_lsame( uplo, 'U' ) ) .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( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPBTRF', uplo, n, kd, -1_${ik}$, -1_${ik}$ )
           ! the block size must not exceed the semi-bandwidth kd, and must not
           ! exceed the limit set by the size of the local array work.
           nb = min( nb, nbmax )
           if( nb<=1_${ik}$ .or. nb>kd ) then
              ! use unblocked code
              call stdlib${ii}$_zpbtf2( uplo, n, kd, ab, ldab, info )
           else
              ! use blocked code
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! compute the cholesky factorization of a hermitian band
                 ! matrix, given the upper triangle of the matrix in band
                 ! storage.
                 ! zero the upper triangle of the work array.
                 do j = 1, nb
                    do i = 1, j - 1
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_70: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_zpotf2( uplo, ib, ab( kd+1, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11   a12   a13
                                ! a22   a23
                                      ! a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a12, a22 and
                       ! a23 are empty if ib = kd. the upper triangle of a13
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a12
                          call stdlib${ii}$_ztrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', &
                                    ib, i2, cone,ab( kd+1, i ), ldab-1,ab( kd+1-ib, i+ib ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_zherk( 'UPPER', 'CONJUGATE TRANSPOSE', i2, ib,-one, ab( kd+&
                                    1_${ik}$-ib, i+ib ), ldab-1, one,ab( kd+1, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the lower triangle of a13 into the work array.
                          do jj = 1, i3
                             do ii = jj, ib
                                work( ii, jj ) = ab( ii-jj+1, jj+i+kd-1 )
                             end do
                          end do
                          ! update a13 (in the work array).
                          call stdlib${ii}$_ztrsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', &
                                    ib, i3, cone,ab( kd+1, i ), ldab-1, work, ldwork )
                          ! update a23
                          if( i2>0_${ik}$ )call stdlib${ii}$_zgemm( 'CONJUGATE TRANSPOSE','NO TRANSPOSE', i2, &
                          i3, ib, -cone,ab( kd+1-ib, i+ib ), ldab-1, work,ldwork, cone, ab( 1_${ik}$+ib, &
                                    i+kd ),ldab-1 )
                          ! update a33
                          call stdlib${ii}$_zherk( 'UPPER', 'CONJUGATE TRANSPOSE', i3, ib,-one, work, &
                                    ldwork, one,ab( kd+1, i+kd ), ldab-1 )
                          ! copy the lower triangle of a13 back into place.
                          do jj = 1, i3
                             do ii = jj, ib
                                ab( ii-jj+1, jj+i+kd-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_70
              else
                 ! compute the cholesky factorization of a hermitian band
                 ! matrix, given the lower triangle of the matrix in band
                 ! storage.
                 ! zero the lower triangle of the work array.
                 do j = 1, nb
                    do i = j + 1, nb
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_140: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_zpotf2( uplo, ib, ab( 1_${ik}$, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11
                          ! a21   a22
                          ! a31   a32   a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a21, a22 and
                       ! a32 are empty if ib = kd. the lower triangle of a31
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a21
                          call stdlib${ii}$_ztrsm( 'RIGHT', 'LOWER','CONJUGATE TRANSPOSE', 'NON-UNIT', &
                                    i2,ib, cone, ab( 1_${ik}$, i ), ldab-1,ab( 1_${ik}$+ib, i ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_zherk( 'LOWER', 'NO TRANSPOSE', i2, ib, -one,ab( 1_${ik}$+ib, i ), &
                                    ldab-1, one,ab( 1_${ik}$, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the upper triangle of a31 into the work array.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                work( ii, jj ) = ab( kd+1-jj+ii, jj+i-1 )
                             end do
                          end do
                          ! update a31 (in the work array).
                          call stdlib${ii}$_ztrsm( 'RIGHT', 'LOWER','CONJUGATE TRANSPOSE', 'NON-UNIT', &
                                    i3,ib, cone, ab( 1_${ik}$, i ), ldab-1, work,ldwork )
                          ! update a32
                          if( i2>0_${ik}$ )call stdlib${ii}$_zgemm( 'NO TRANSPOSE','CONJUGATE TRANSPOSE', i3, &
                          i2, ib,-cone, work, ldwork, ab( 1_${ik}$+ib, i ),ldab-1, cone, ab( 1_${ik}$+kd-ib, i+&
                                    ib ),ldab-1 )
                          ! update a33
                          call stdlib${ii}$_zherk( 'LOWER', 'NO TRANSPOSE', i3, ib, -one,work, ldwork, &
                                    one, ab( 1_${ik}$, i+kd ),ldab-1 )
                          ! copy the upper triangle of a31 back into place.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                ab( kd+1-jj+ii, jj+i-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_140
              end if
           end if
           return
           150 continue
           return
     end subroutine stdlib${ii}$_zpbtrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pbtrf( uplo, n, kd, ab, ldab, info )
     !! ZPBTRF: computes the Cholesky factorization of a complex Hermitian
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**H * U,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix and L is lower triangular.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: nbmax = 32_${ik}$
           integer(${ik}$), parameter :: ldwork = nbmax+1
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: i, i2, i3, ib, ii, j, jj, nb
           ! Local Arrays 
           complex(${ck}$) :: work(ldwork,nbmax)
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( ( .not.stdlib_lsame( uplo, 'U' ) ) .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( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! determine the block size for this environment
           nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPBTRF', uplo, n, kd, -1_${ik}$, -1_${ik}$ )
           ! the block size must not exceed the semi-bandwidth kd, and must not
           ! exceed the limit set by the size of the local array work.
           nb = min( nb, nbmax )
           if( nb<=1_${ik}$ .or. nb>kd ) then
              ! use unblocked code
              call stdlib${ii}$_${ci}$pbtf2( uplo, n, kd, ab, ldab, info )
           else
              ! use blocked code
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! compute the cholesky factorization of a hermitian band
                 ! matrix, given the upper triangle of the matrix in band
                 ! storage.
                 ! zero the upper triangle of the work array.
                 do j = 1, nb
                    do i = 1, j - 1
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_70: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_${ci}$potf2( uplo, ib, ab( kd+1, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11   a12   a13
                                ! a22   a23
                                      ! a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a12, a22 and
                       ! a23 are empty if ib = kd. the upper triangle of a13
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a12
                          call stdlib${ii}$_${ci}$trsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', &
                                    ib, i2, cone,ab( kd+1, i ), ldab-1,ab( kd+1-ib, i+ib ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_${ci}$herk( 'UPPER', 'CONJUGATE TRANSPOSE', i2, ib,-one, ab( kd+&
                                    1_${ik}$-ib, i+ib ), ldab-1, one,ab( kd+1, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the lower triangle of a13 into the work array.
                          do jj = 1, i3
                             do ii = jj, ib
                                work( ii, jj ) = ab( ii-jj+1, jj+i+kd-1 )
                             end do
                          end do
                          ! update a13 (in the work array).
                          call stdlib${ii}$_${ci}$trsm( 'LEFT', 'UPPER', 'CONJUGATE TRANSPOSE','NON-UNIT', &
                                    ib, i3, cone,ab( kd+1, i ), ldab-1, work, ldwork )
                          ! update a23
                          if( i2>0_${ik}$ )call stdlib${ii}$_${ci}$gemm( 'CONJUGATE TRANSPOSE','NO TRANSPOSE', i2, &
                          i3, ib, -cone,ab( kd+1-ib, i+ib ), ldab-1, work,ldwork, cone, ab( 1_${ik}$+ib, &
                                    i+kd ),ldab-1 )
                          ! update a33
                          call stdlib${ii}$_${ci}$herk( 'UPPER', 'CONJUGATE TRANSPOSE', i3, ib,-one, work, &
                                    ldwork, one,ab( kd+1, i+kd ), ldab-1 )
                          ! copy the lower triangle of a13 back into place.
                          do jj = 1, i3
                             do ii = jj, ib
                                ab( ii-jj+1, jj+i+kd-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_70
              else
                 ! compute the cholesky factorization of a hermitian band
                 ! matrix, given the lower triangle of the matrix in band
                 ! storage.
                 ! zero the lower triangle of the work array.
                 do j = 1, nb
                    do i = j + 1, nb
                       work( i, j ) = zero
                    end do
                 end do
                 ! process the band matrix one diagonal block at a time.
                 loop_140: do i = 1, n, nb
                    ib = min( nb, n-i+1 )
                    ! factorize the diagonal block
                    call stdlib${ii}$_${ci}$potf2( uplo, ib, ab( 1_${ik}$, i ), ldab-1, ii )
                    if( ii/=0_${ik}$ ) then
                       info = i + ii - 1_${ik}$
                       go to 150
                    end if
                    if( i+ib<=n ) then
                       ! update the relevant part of the trailing submatrix.
                       ! if a11 denotes the diagonal block which has just been
                       ! factorized, then we need to update the remaining
                       ! blocks in the diagram:
                          ! a11
                          ! a21   a22
                          ! a31   a32   a33
                       ! the numbers of rows and columns in the partitioning
                       ! are ib, i2, i3 respectively. the blocks a21, a22 and
                       ! a32 are empty if ib = kd. the lower triangle of a31
                       ! lies outside the band.
                       i2 = min( kd-ib, n-i-ib+1 )
                       i3 = min( ib, n-i-kd+1 )
                       if( i2>0_${ik}$ ) then
                          ! update a21
                          call stdlib${ii}$_${ci}$trsm( 'RIGHT', 'LOWER','CONJUGATE TRANSPOSE', 'NON-UNIT', &
                                    i2,ib, cone, ab( 1_${ik}$, i ), ldab-1,ab( 1_${ik}$+ib, i ), ldab-1 )
                          ! update a22
                          call stdlib${ii}$_${ci}$herk( 'LOWER', 'NO TRANSPOSE', i2, ib, -one,ab( 1_${ik}$+ib, i ), &
                                    ldab-1, one,ab( 1_${ik}$, i+ib ), ldab-1 )
                       end if
                       if( i3>0_${ik}$ ) then
                          ! copy the upper triangle of a31 into the work array.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                work( ii, jj ) = ab( kd+1-jj+ii, jj+i-1 )
                             end do
                          end do
                          ! update a31 (in the work array).
                          call stdlib${ii}$_${ci}$trsm( 'RIGHT', 'LOWER','CONJUGATE TRANSPOSE', 'NON-UNIT', &
                                    i3,ib, cone, ab( 1_${ik}$, i ), ldab-1, work,ldwork )
                          ! update a32
                          if( i2>0_${ik}$ )call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE','CONJUGATE TRANSPOSE', i3, &
                          i2, ib,-cone, work, ldwork, ab( 1_${ik}$+ib, i ),ldab-1, cone, ab( 1_${ik}$+kd-ib, i+&
                                    ib ),ldab-1 )
                          ! update a33
                          call stdlib${ii}$_${ci}$herk( 'LOWER', 'NO TRANSPOSE', i3, ib, -one,work, ldwork, &
                                    one, ab( 1_${ik}$, i+kd ),ldab-1 )
                          ! copy the upper triangle of a31 back into place.
                          do jj = 1, ib
                             do ii = 1, min( jj, i3 )
                                ab( kd+1-jj+ii, jj+i-1 ) = work( ii, jj )
                             end do
                          end do
                       end if
                    end if
                 end do loop_140
              end if
           end if
           return
           150 continue
           return
     end subroutine stdlib${ii}$_${ci}$pbtrf

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spbtf2( uplo, n, kd, ab, ldab, info )
     !! SPBTF2 computes the Cholesky factorization of a real symmetric
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**T * U ,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix, U**T is the transpose of U, and
     !! L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           real(sp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, kld, kn
           real(sp) :: ajj
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPBTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           kld = max( 1_${ik}$, ldab-1 )
           if( upper ) then
              ! compute the cholesky factorization a = u**t*u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = ab( kd+1, j )
                 if( ajj<=zero )go to 30
                 ajj = sqrt( ajj )
                 ab( kd+1, j ) = ajj
                 ! compute elements j+1:j+kn of row j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_sscal( kn, one / ajj, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_ssyr( 'UPPER', kn, -one, ab( kd, j+1 ), kld,ab( kd+1, j+1 ), kld )
                              
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = ab( 1_${ik}$, j )
                 if( ajj<=zero )go to 30
                 ajj = sqrt( ajj )
                 ab( 1_${ik}$, j ) = ajj
                 ! compute elements j+1:j+kn of column j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_sscal( kn, one / ajj, ab( 2_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_ssyr( 'LOWER', kn, -one, ab( 2_${ik}$, j ), 1_${ik}$,ab( 1_${ik}$, j+1 ), kld )
                 end if
              end do
           end if
           return
           30 continue
           info = j
           return
     end subroutine stdlib${ii}$_spbtf2

     pure module subroutine stdlib${ii}$_dpbtf2( uplo, n, kd, ab, ldab, info )
     !! DPBTF2 computes the Cholesky factorization of a real symmetric
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**T * U ,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix, U**T is the transpose of U, and
     !! L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           real(dp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, kld, kn
           real(dp) :: ajj
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           kld = max( 1_${ik}$, ldab-1 )
           if( upper ) then
              ! compute the cholesky factorization a = u**t*u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = ab( kd+1, j )
                 if( ajj<=zero )go to 30
                 ajj = sqrt( ajj )
                 ab( kd+1, j ) = ajj
                 ! compute elements j+1:j+kn of row j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_dscal( kn, one / ajj, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_dsyr( 'UPPER', kn, -one, ab( kd, j+1 ), kld,ab( kd+1, j+1 ), kld )
                              
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = ab( 1_${ik}$, j )
                 if( ajj<=zero )go to 30
                 ajj = sqrt( ajj )
                 ab( 1_${ik}$, j ) = ajj
                 ! compute elements j+1:j+kn of column j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_dscal( kn, one / ajj, ab( 2_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_dsyr( 'LOWER', kn, -one, ab( 2_${ik}$, j ), 1_${ik}$,ab( 1_${ik}$, j+1 ), kld )
                 end if
              end do
           end if
           return
           30 continue
           info = j
           return
     end subroutine stdlib${ii}$_dpbtf2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pbtf2( uplo, n, kd, ab, ldab, info )
     !! DPBTF2: computes the Cholesky factorization of a real symmetric
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**T * U ,  if UPLO = 'U', or
     !! A = L  * L**T,  if UPLO = 'L',
     !! where U is an upper triangular matrix, U**T is the transpose of U, and
     !! L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, kld, kn
           real(${rk}$) :: ajj
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           kld = max( 1_${ik}$, ldab-1 )
           if( upper ) then
              ! compute the cholesky factorization a = u**t*u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = ab( kd+1, j )
                 if( ajj<=zero )go to 30
                 ajj = sqrt( ajj )
                 ab( kd+1, j ) = ajj
                 ! compute elements j+1:j+kn of row j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_${ri}$scal( kn, one / ajj, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_${ri}$syr( 'UPPER', kn, -one, ab( kd, j+1 ), kld,ab( kd+1, j+1 ), kld )
                              
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**t.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = ab( 1_${ik}$, j )
                 if( ajj<=zero )go to 30
                 ajj = sqrt( ajj )
                 ab( 1_${ik}$, j ) = ajj
                 ! compute elements j+1:j+kn of column j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_${ri}$scal( kn, one / ajj, ab( 2_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ri}$syr( 'LOWER', kn, -one, ab( 2_${ik}$, j ), 1_${ik}$,ab( 1_${ik}$, j+1 ), kld )
                 end if
              end do
           end if
           return
           30 continue
           info = j
           return
     end subroutine stdlib${ii}$_${ri}$pbtf2

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpbtf2( uplo, n, kd, ab, ldab, info )
     !! CPBTF2 computes the Cholesky factorization of a complex Hermitian
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**H * U ,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix, U**H is the conjugate transpose
     !! of U, and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           complex(sp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, kld, kn
           real(sp) :: ajj
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPBTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           kld = max( 1_${ik}$, ldab-1 )
           if( upper ) then
              ! compute the cholesky factorization a = u**h * u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( ab( kd+1, j ),KIND=sp)
                 if( ajj<=zero ) then
                    ab( kd+1, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ab( kd+1, j ) = ajj
                 ! compute elements j+1:j+kn of row j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_csscal( kn, one / ajj, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_clacgv( kn, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_cher( 'UPPER', kn, -one, ab( kd, j+1 ), kld,ab( kd+1, j+1 ), kld )
                              
                    call stdlib${ii}$_clacgv( kn, ab( kd, j+1 ), kld )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**h.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( ab( 1_${ik}$, j ),KIND=sp)
                 if( ajj<=zero ) then
                    ab( 1_${ik}$, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ab( 1_${ik}$, j ) = ajj
                 ! compute elements j+1:j+kn of column j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_csscal( kn, one / ajj, ab( 2_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_cher( 'LOWER', kn, -one, ab( 2_${ik}$, j ), 1_${ik}$,ab( 1_${ik}$, j+1 ), kld )
                 end if
              end do
           end if
           return
           30 continue
           info = j
           return
     end subroutine stdlib${ii}$_cpbtf2

     pure module subroutine stdlib${ii}$_zpbtf2( uplo, n, kd, ab, ldab, info )
     !! ZPBTF2 computes the Cholesky factorization of a complex Hermitian
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**H * U ,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix, U**H is the conjugate transpose
     !! of U, and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           complex(dp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, kld, kn
           real(dp) :: ajj
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           kld = max( 1_${ik}$, ldab-1 )
           if( upper ) then
              ! compute the cholesky factorization a = u**h * u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( ab( kd+1, j ),KIND=dp)
                 if( ajj<=zero ) then
                    ab( kd+1, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ab( kd+1, j ) = ajj
                 ! compute elements j+1:j+kn of row j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_zdscal( kn, one / ajj, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_zlacgv( kn, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_zher( 'UPPER', kn, -one, ab( kd, j+1 ), kld,ab( kd+1, j+1 ), kld )
                              
                    call stdlib${ii}$_zlacgv( kn, ab( kd, j+1 ), kld )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**h.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( ab( 1_${ik}$, j ),KIND=dp)
                 if( ajj<=zero ) then
                    ab( 1_${ik}$, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ab( 1_${ik}$, j ) = ajj
                 ! compute elements j+1:j+kn of column j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_zdscal( kn, one / ajj, ab( 2_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_zher( 'LOWER', kn, -one, ab( 2_${ik}$, j ), 1_${ik}$,ab( 1_${ik}$, j+1 ), kld )
                 end if
              end do
           end if
           return
           30 continue
           info = j
           return
     end subroutine stdlib${ii}$_zpbtf2

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pbtf2( uplo, n, kd, ab, ldab, info )
     !! ZPBTF2: computes the Cholesky factorization of a complex Hermitian
     !! positive definite band matrix A.
     !! The factorization has the form
     !! A = U**H * U ,  if UPLO = 'U', or
     !! A = L  * L**H,  if UPLO = 'L',
     !! where U is an upper triangular matrix, U**H is the conjugate transpose
     !! of U, and L is lower triangular.
     !! This is the unblocked version of the algorithm, calling Level 2 BLAS.
        ! -- 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) :: kd, ldab, n
           ! Array Arguments 
           complex(${ck}$), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j, kld, kn
           real(${ck}$) :: ajj
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBTF2', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           kld = max( 1_${ik}$, ldab-1 )
           if( upper ) then
              ! compute the cholesky factorization a = u**h * u.
              do j = 1, n
                 ! compute u(j,j) and test for non-positive-definiteness.
                 ajj = real( ab( kd+1, j ),KIND=${ck}$)
                 if( ajj<=zero ) then
                    ab( kd+1, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ab( kd+1, j ) = ajj
                 ! compute elements j+1:j+kn of row j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_${ci}$dscal( kn, one / ajj, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_${ci}$lacgv( kn, ab( kd, j+1 ), kld )
                    call stdlib${ii}$_${ci}$her( 'UPPER', kn, -one, ab( kd, j+1 ), kld,ab( kd+1, j+1 ), kld )
                              
                    call stdlib${ii}$_${ci}$lacgv( kn, ab( kd, j+1 ), kld )
                 end if
              end do
           else
              ! compute the cholesky factorization a = l*l**h.
              do j = 1, n
                 ! compute l(j,j) and test for non-positive-definiteness.
                 ajj = real( ab( 1_${ik}$, j ),KIND=${ck}$)
                 if( ajj<=zero ) then
                    ab( 1_${ik}$, j ) = ajj
                    go to 30
                 end if
                 ajj = sqrt( ajj )
                 ab( 1_${ik}$, j ) = ajj
                 ! compute elements j+1:j+kn of column j and update the
                 ! trailing submatrix within the band.
                 kn = min( kd, n-j )
                 if( kn>0_${ik}$ ) then
                    call stdlib${ii}$_${ci}$dscal( kn, one / ajj, ab( 2_${ik}$, j ), 1_${ik}$ )
                    call stdlib${ii}$_${ci}$her( 'LOWER', kn, -one, ab( 2_${ik}$, j ), 1_${ik}$,ab( 1_${ik}$, j+1 ), kld )
                 end if
              end do
           end if
           return
           30 continue
           info = j
           return
     end subroutine stdlib${ii}$_${ci}$pbtf2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spbtrs( uplo, n, kd, nrhs, ab, ldab, b, ldb, info )
     !! SPBTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite band matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by SPBTRF.
        ! -- 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) :: kd, ldab, ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: ab(ldab,*)
           real(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPBTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t *u.
              do j = 1, nrhs
                 ! solve u**t *x = b, overwriting b with x.
                 call stdlib${ii}$_stbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j ), &
                           1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_stbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
              end do
           else
              ! solve a*x = b where a = l*l**t.
              do j = 1, nrhs
                 ! solve l*x = b, overwriting b with x.
                 call stdlib${ii}$_stbsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
                 ! solve l**t *x = b, overwriting b with x.
                 call stdlib${ii}$_stbsv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j ), &
                           1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_spbtrs

     pure module subroutine stdlib${ii}$_dpbtrs( uplo, n, kd, nrhs, ab, ldab, b, ldb, info )
     !! DPBTRS solves a system of linear equations A*X = B with a symmetric
     !! positive definite band matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by DPBTRF.
        ! -- 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) :: kd, ldab, ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: ab(ldab,*)
           real(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t *u.
              do j = 1, nrhs
                 ! solve u**t *x = b, overwriting b with x.
                 call stdlib${ii}$_dtbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j ), &
                           1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_dtbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
              end do
           else
              ! solve a*x = b where a = l*l**t.
              do j = 1, nrhs
                 ! solve l*x = b, overwriting b with x.
                 call stdlib${ii}$_dtbsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
                 ! solve l**t *x = b, overwriting b with x.
                 call stdlib${ii}$_dtbsv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j ), &
                           1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_dpbtrs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pbtrs( uplo, n, kd, nrhs, ab, ldab, b, ldb, info )
     !! DPBTRS: solves a system of linear equations A*X = B with a symmetric
     !! positive definite band matrix A using the Cholesky factorization
     !! A = U**T*U or A = L*L**T computed by DPBTRF.
        ! -- 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) :: kd, ldab, ldb, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(in) :: ab(ldab,*)
           real(${rk}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**t *u.
              do j = 1, nrhs
                 ! solve u**t *x = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j ), &
                           1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
              end do
           else
              ! solve a*x = b where a = l*l**t.
              do j = 1, nrhs
                 ! solve l*x = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tbsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
                 ! solve l**t *x = b, overwriting b with x.
                 call stdlib${ii}$_${ri}$tbsv( 'LOWER', 'TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j ), &
                           1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pbtrs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpbtrs( uplo, n, kd, nrhs, ab, ldab, b, ldb, info )
     !! CPBTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite band matrix A using the Cholesky factorization
     !! A = U**H*U or A = L*L**H computed by CPBTRF.
        ! -- 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) :: kd, ldab, ldb, n, nrhs
           ! Array Arguments 
           complex(sp), intent(in) :: ab(ldab,*)
           complex(sp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPBTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h *u.
              do j = 1, nrhs
                 ! solve u**h *x = b, overwriting b with x.
                 call stdlib${ii}$_ctbsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kd, ab, ldab, b(&
                            1_${ik}$, j ), 1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_ctbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
              end do
           else
              ! solve a*x = b where a = l*l**h.
              do j = 1, nrhs
                 ! solve l*x = b, overwriting b with x.
                 call stdlib${ii}$_ctbsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
                 ! solve l**h *x = b, overwriting b with x.
                 call stdlib${ii}$_ctbsv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kd, ab, ldab, b(&
                            1_${ik}$, j ), 1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_cpbtrs

     pure module subroutine stdlib${ii}$_zpbtrs( uplo, n, kd, nrhs, ab, ldab, b, ldb, info )
     !! ZPBTRS solves a system of linear equations A*X = B with a Hermitian
     !! positive definite band matrix A using the Cholesky factorization
     !! A = U**H *U or A = L*L**H computed by ZPBTRF.
        ! -- 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) :: kd, ldab, ldb, n, nrhs
           ! Array Arguments 
           complex(dp), intent(in) :: ab(ldab,*)
           complex(dp), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h *u.
              do j = 1, nrhs
                 ! solve u**h *x = b, overwriting b with x.
                 call stdlib${ii}$_ztbsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kd, ab, ldab, b(&
                            1_${ik}$, j ), 1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_ztbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
              end do
           else
              ! solve a*x = b where a = l*l**h.
              do j = 1, nrhs
                 ! solve l*x = b, overwriting b with x.
                 call stdlib${ii}$_ztbsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
                 ! solve l**h *x = b, overwriting b with x.
                 call stdlib${ii}$_ztbsv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kd, ab, ldab, b(&
                            1_${ik}$, j ), 1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_zpbtrs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pbtrs( uplo, n, kd, nrhs, ab, ldab, b, ldb, info )
     !! ZPBTRS: solves a system of linear equations A*X = B with a Hermitian
     !! positive definite band matrix A using the Cholesky factorization
     !! A = U**H *U or A = L*L**H computed by ZPBTRF.
        ! -- 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) :: kd, ldab, ldb, n, nrhs
           ! Array Arguments 
           complex(${ck}$), intent(in) :: ab(ldab,*)
           complex(${ck}$), intent(inout) :: b(ldb,*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: j
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           if( upper ) then
              ! solve a*x = b where a = u**h *u.
              do j = 1, nrhs
                 ! solve u**h *x = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tbsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kd, ab, ldab, b(&
                            1_${ik}$, j ), 1_${ik}$ )
                 ! solve u*x = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
              end do
           else
              ! solve a*x = b where a = l*l**h.
              do j = 1, nrhs
                 ! solve l*x = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tbsv( 'LOWER', 'NO TRANSPOSE', 'NON-UNIT', n, kd, ab,ldab, b( 1_${ik}$, j )&
                           , 1_${ik}$ )
                 ! solve l**h *x = b, overwriting b with x.
                 call stdlib${ii}$_${ci}$tbsv( 'LOWER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kd, ab, ldab, b(&
                            1_${ik}$, j ), 1_${ik}$ )
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pbtrs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spbrfs( uplo, n, kd, nrhs, ab, ldab, afb, ldafb, b,ldb, x, ldx, ferr, &
     !! SPBRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and banded, and provides error bounds and backward error estimates
     !! for the solution.
               berr, work, iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: kd, ldab, ldafb, ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(sp), intent(in) :: ab(ldab,*), afb(ldafb,*), b(ldb,*)
           real(sp), intent(out) :: berr(*), ferr(*), work(*)
           real(sp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, l, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldafb<kd+1 ) then
              info = -8_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPBRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = min( n+1, 2_${ik}$*kd+2 )
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_scopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_ssbmv( uplo, n, kd, -one, ab, ldab, x( 1_${ik}$, j ), 1_${ik}$, one,work( n+1 ), 1_${ik}$ )
                        
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    l = kd + 1_${ik}$ - k
                    do i = max( 1, k-kd ), k - 1
                       work( i ) = work( i ) + abs( ab( l+i, k ) )*xk
                       s = s + abs( ab( l+i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + abs( ab( kd+1, k ) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( ab( 1_${ik}$, k ) )*xk
                    l = 1_${ik}$ - k
                    do i = k + 1, min( n, k+kd )
                       work( i ) = work( i ) + abs( ab( l+i, k ) )*xk
                       s = s + abs( ab( l+i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_spbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                 call stdlib${ii}$_saxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_slacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_slacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_spbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                    do i = 1, n
                       work( n+i ) = work( n+i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( n+i )*work( i )
                    end do
                    call stdlib${ii}$_spbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_spbrfs

     pure module subroutine stdlib${ii}$_dpbrfs( uplo, n, kd, nrhs, ab, ldab, afb, ldafb, b,ldb, x, ldx, ferr, &
     !! DPBRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and banded, and provides error bounds and backward error estimates
     !! for the solution.
               berr, work, iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: kd, ldab, ldafb, ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(dp), intent(in) :: ab(ldab,*), afb(ldafb,*), b(ldb,*)
           real(dp), intent(out) :: berr(*), ferr(*), work(*)
           real(dp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, l, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldafb<kd+1 ) then
              info = -8_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = min( n+1, 2_${ik}$*kd+2 )
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_dcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_dsbmv( uplo, n, kd, -one, ab, ldab, x( 1_${ik}$, j ), 1_${ik}$, one,work( n+1 ), 1_${ik}$ )
                        
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    l = kd + 1_${ik}$ - k
                    do i = max( 1, k-kd ), k - 1
                       work( i ) = work( i ) + abs( ab( l+i, k ) )*xk
                       s = s + abs( ab( l+i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + abs( ab( kd+1, k ) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( ab( 1_${ik}$, k ) )*xk
                    l = 1_${ik}$ - k
                    do i = k + 1, min( n, k+kd )
                       work( i ) = work( i ) + abs( ab( l+i, k ) )*xk
                       s = s + abs( ab( l+i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_dpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                 call stdlib${ii}$_daxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_dlacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_dlacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_dpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                    do i = 1, n
                       work( n+i ) = work( n+i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( n+i )*work( i )
                    end do
                    call stdlib${ii}$_dpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_dpbrfs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pbrfs( uplo, n, kd, nrhs, ab, ldab, afb, ldafb, b,ldb, x, ldx, ferr, &
     !! DPBRFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and banded, and provides error bounds and backward error estimates
     !! for the solution.
               berr, work, iwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: kd, ldab, ldafb, ldb, ldx, n, nrhs
           ! Array Arguments 
           integer(${ik}$), intent(out) :: iwork(*)
           real(${rk}$), intent(in) :: ab(ldab,*), afb(ldafb,*), b(ldb,*)
           real(${rk}$), intent(out) :: berr(*), ferr(*), work(*)
           real(${rk}$), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, l, nz
           real(${rk}$) :: eps, lstres, s, safe1, safe2, safmin, xk
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldafb<kd+1 ) then
              info = -8_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = min( n+1, 2_${ik}$*kd+2 )
           eps = stdlib${ii}$_${ri}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_${ri}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ )
              call stdlib${ii}$_${ri}$sbmv( uplo, n, kd, -one, ab, ldab, x( 1_${ik}$, j ), 1_${ik}$, one,work( n+1 ), 1_${ik}$ )
                        
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 work( i ) = abs( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    l = kd + 1_${ik}$ - k
                    do i = max( 1, k-kd ), k - 1
                       work( i ) = work( i ) + abs( ab( l+i, k ) )*xk
                       s = s + abs( ab( l+i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + abs( ab( kd+1, k ) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = abs( x( k, j ) )
                    work( k ) = work( k ) + abs( ab( 1_${ik}$, k ) )*xk
                    l = 1_${ik}$ - k
                    do i = k + 1, min( n, k+kd )
                       work( i ) = work( i ) + abs( ab( l+i, k ) )*xk
                       s = s + abs( ab( l+i, k ) )*abs( x( i, j ) )
                    end do
                    work( k ) = work( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ri}$pbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                 call stdlib${ii}$_${ri}$axpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_${ri}$lacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_${ri}$lacn2( n, work( 2_${ik}$*n+1 ), work( n+1 ), iwork, ferr( j ),kase, isave )
                        
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**t).
                    call stdlib${ii}$_${ri}$pbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                    do i = 1, n
                       work( n+i ) = work( n+i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( n+i ) = work( n+i )*work( i )
                    end do
                    call stdlib${ii}$_${ri}$pbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work( n+1 ), n,info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_${ri}$pbrfs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpbrfs( uplo, n, kd, nrhs, ab, ldab, afb, ldafb, b,ldb, x, ldx, ferr, &
     !! CPBRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and banded, and provides error bounds and backward error estimates
     !! for the solution.
               berr, work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: kd, ldab, ldafb, ldb, ldx, n, nrhs
           ! Array Arguments 
           real(sp), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(sp), intent(in) :: ab(ldab,*), afb(ldafb,*), b(ldb,*)
           complex(sp), intent(out) :: work(*)
           complex(sp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, l, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(sp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldafb<kd+1 ) then
              info = -8_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPBRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = min( n+1, 2_${ik}$*kd+2 )
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_ccopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_chbmv( uplo, n, kd, -cone, ab, ldab, x( 1_${ik}$, j ), 1_${ik}$, cone,work, 1_${ik}$ )
                        
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    l = kd + 1_${ik}$ - k
                    do i = max( 1, k-kd ), k - 1
                       rwork( i ) = rwork( i ) + cabs1( ab( l+i, k ) )*xk
                       s = s + cabs1( ab( l+i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + abs( real( ab( kd+1, k ),KIND=sp) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( ab( 1_${ik}$, k ),KIND=sp) )*xk
                    l = 1_${ik}$ - k
                    do i = k + 1, min( n, k+kd )
                       rwork( i ) = rwork( i ) + cabs1( ab( l+i, k ) )*xk
                       s = s + cabs1( ab( l+i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_cpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                 call stdlib${ii}$_caxpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_clacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_clacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_cpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_cpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_cpbrfs

     pure module subroutine stdlib${ii}$_zpbrfs( uplo, n, kd, nrhs, ab, ldab, afb, ldafb, b,ldb, x, ldx, ferr, &
     !! ZPBRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and banded, and provides error bounds and backward error estimates
     !! for the solution.
               berr, work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: kd, ldab, ldafb, ldb, ldx, n, nrhs
           ! Array Arguments 
           real(dp), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(dp), intent(in) :: ab(ldab,*), afb(ldafb,*), b(ldb,*)
           complex(dp), intent(out) :: work(*)
           complex(dp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, l, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(dp) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldafb<kd+1 ) then
              info = -8_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = min( n+1, 2_${ik}$*kd+2 )
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_zcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_zhbmv( uplo, n, kd, -cone, ab, ldab, x( 1_${ik}$, j ), 1_${ik}$, cone,work, 1_${ik}$ )
                        
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    l = kd + 1_${ik}$ - k
                    do i = max( 1, k-kd ), k - 1
                       rwork( i ) = rwork( i ) + cabs1( ab( l+i, k ) )*xk
                       s = s + cabs1( ab( l+i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + abs( real( ab( kd+1, k ),KIND=dp) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( ab( 1_${ik}$, k ),KIND=dp) )*xk
                    l = 1_${ik}$ - k
                    do i = k + 1, min( n, k+kd )
                       rwork( i ) = rwork( i ) + cabs1( ab( l+i, k ) )*xk
                       s = s + cabs1( ab( l+i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_zpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                 call stdlib${ii}$_zaxpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_zlacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_zpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_zpbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_zpbrfs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pbrfs( uplo, n, kd, nrhs, ab, ldab, afb, ldafb, b,ldb, x, ldx, ferr, &
     !! ZPBRFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and banded, and provides error bounds and backward error estimates
     !! for the solution.
               berr, work, rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: kd, ldab, ldafb, ldb, ldx, n, nrhs
           ! Array Arguments 
           real(${ck}$), intent(out) :: berr(*), ferr(*), rwork(*)
           complex(${ck}$), intent(in) :: ab(ldab,*), afb(ldafb,*), b(ldb,*)
           complex(${ck}$), intent(out) :: work(*)
           complex(${ck}$), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, j, k, kase, l, nz
           real(${ck}$) :: eps, lstres, s, safe1, safe2, safmin, xk
           complex(${ck}$) :: zdum
           ! Local Arrays 
           integer(${ik}$) :: isave(3_${ik}$)
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -4_${ik}$
           else if( ldab<kd+1 ) then
              info = -6_${ik}$
           else if( ldafb<kd+1 ) then
              info = -8_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -12_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = min( n+1, 2_${ik}$*kd+2 )
           eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_140: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x
              call stdlib${ii}$_${ci}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ )
              call stdlib${ii}$_${ci}$hbmv( uplo, n, kd, -cone, ab, ldab, x( 1_${ik}$, j ), 1_${ik}$, cone,work, 1_${ik}$ )
                        
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              do i = 1, n
                 rwork( i ) = cabs1( b( i, j ) )
              end do
              ! compute abs(a)*abs(x) + abs(b).
              if( upper ) then
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    l = kd + 1_${ik}$ - k
                    do i = max( 1, k-kd ), k - 1
                       rwork( i ) = rwork( i ) + cabs1( ab( l+i, k ) )*xk
                       s = s + cabs1( ab( l+i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + abs( real( ab( kd+1, k ),KIND=${ck}$) )*xk + s
                 end do
              else
                 do k = 1, n
                    s = zero
                    xk = cabs1( x( k, j ) )
                    rwork( k ) = rwork( k ) + abs( real( ab( 1_${ik}$, k ),KIND=${ck}$) )*xk
                    l = 1_${ik}$ - k
                    do i = k + 1, min( n, k+kd )
                       rwork( i ) = rwork( i ) + cabs1( ab( l+i, k ) )*xk
                       s = s + cabs1( ab( l+i, k ) )*cabs1( x( i, j ) )
                    end do
                    rwork( k ) = rwork( k ) + s
                 end do
              end if
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ci}$pbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                 call stdlib${ii}$_${ci}$axpy( n, cone, work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              ! use stdlib_${ci}$lacn2 to estimate the infinity-norm of the matrix
                 ! inv(a) * diag(w),
              ! where w = abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) )))
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              kase = 0_${ik}$
              100 continue
              call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ferr( j ), kase, isave )
              if( kase/=0_${ik}$ ) then
                 if( kase==1_${ik}$ ) then
                    ! multiply by diag(w)*inv(a**h).
                    call stdlib${ii}$_${ci}$pbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                 else if( kase==2_${ik}$ ) then
                    ! multiply by inv(a)*diag(w).
                    do i = 1, n
                       work( i ) = rwork( i )*work( i )
                    end do
                    call stdlib${ii}$_${ci}$pbtrs( uplo, n, kd, 1_${ik}$, afb, ldafb, work, n, info )
                 end if
                 go to 100
              end if
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, cabs1( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_140
           return
     end subroutine stdlib${ii}$_${ci}$pbrfs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spbequ( uplo, n, kd, ab, ldab, s, scond, amax, info )
     !! SPBEQU computes row and column scalings intended to equilibrate a
     !! symmetric positive definite band matrix A and reduce its condition
     !! number (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: kd, ldab, n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: ab(ldab,*)
           real(sp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, j
           real(sp) :: smin
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPBEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           if( upper ) then
              j = kd + 1_${ik}$
           else
              j = 1_${ik}$
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = ab( j, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           ! find the minimum and maximum diagonal elements.
           do i = 2, n
              s( i ) = ab( j, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_spbequ

     pure module subroutine stdlib${ii}$_dpbequ( uplo, n, kd, ab, ldab, s, scond, amax, info )
     !! DPBEQU computes row and column scalings intended to equilibrate a
     !! symmetric positive definite band matrix A and reduce its condition
     !! number (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: kd, ldab, n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: ab(ldab,*)
           real(dp), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, j
           real(dp) :: smin
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           if( upper ) then
              j = kd + 1_${ik}$
           else
              j = 1_${ik}$
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = ab( j, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           ! find the minimum and maximum diagonal elements.
           do i = 2, n
              s( i ) = ab( j, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_dpbequ

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pbequ( uplo, n, kd, ab, ldab, s, scond, amax, info )
     !! DPBEQU: computes row and column scalings intended to equilibrate a
     !! symmetric positive definite band matrix A and reduce its condition
     !! number (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: kd, ldab, n
           real(${rk}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${rk}$), intent(in) :: ab(ldab,*)
           real(${rk}$), intent(out) :: s(*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, j
           real(${rk}$) :: smin
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPBEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           if( upper ) then
              j = kd + 1_${ik}$
           else
              j = 1_${ik}$
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = ab( j, 1_${ik}$ )
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           ! find the minimum and maximum diagonal elements.
           do i = 2, n
              s( i ) = ab( j, i )
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pbequ

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpbequ( uplo, n, kd, ab, ldab, s, scond, amax, info )
     !! CPBEQU computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite band matrix A and reduce its condition
     !! number (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: kd, ldab, n
           real(sp), intent(out) :: amax, scond
           ! Array Arguments 
           real(sp), intent(out) :: s(*)
           complex(sp), intent(in) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, j
           real(sp) :: smin
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPBEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           if( upper ) then
              j = kd + 1_${ik}$
           else
              j = 1_${ik}$
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = real( ab( j, 1_${ik}$ ),KIND=sp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           ! find the minimum and maximum diagonal elements.
           do i = 2, n
              s( i ) = real( ab( j, i ),KIND=sp)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_cpbequ

     pure module subroutine stdlib${ii}$_zpbequ( uplo, n, kd, ab, ldab, s, scond, amax, info )
     !! ZPBEQU computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite band matrix A and reduce its condition
     !! number (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: kd, ldab, n
           real(dp), intent(out) :: amax, scond
           ! Array Arguments 
           real(dp), intent(out) :: s(*)
           complex(dp), intent(in) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, j
           real(dp) :: smin
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           if( upper ) then
              j = kd + 1_${ik}$
           else
              j = 1_${ik}$
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = real( ab( j, 1_${ik}$ ),KIND=dp)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           ! find the minimum and maximum diagonal elements.
           do i = 2, n
              s( i ) = real( ab( j, i ),KIND=dp)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_zpbequ

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pbequ( uplo, n, kd, ab, ldab, s, scond, amax, info )
     !! ZPBEQU: computes row and column scalings intended to equilibrate a
     !! Hermitian positive definite band matrix A and reduce its condition
     !! number (with respect to the two-norm).  S contains the scale factors,
     !! S(i) = 1/sqrt(A(i,i)), chosen so that the scaled matrix B with
     !! elements B(i,j) = S(i)*A(i,j)*S(j) has ones on the diagonal.  This
     !! choice of S puts the condition number of B within a factor N of the
     !! smallest possible condition number over all possible diagonal
     !! scalings.
        ! -- 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) :: kd, ldab, n
           real(${ck}$), intent(out) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(out) :: s(*)
           complex(${ck}$), intent(in) :: ab(ldab,*)
        ! =====================================================================
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: i, j
           real(${ck}$) :: smin
           ! 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( kd<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldab<kd+1 ) then
              info = -5_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPBEQU', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ ) then
              scond = one
              amax = zero
              return
           end if
           if( upper ) then
              j = kd + 1_${ik}$
           else
              j = 1_${ik}$
           end if
           ! initialize smin and amax.
           s( 1_${ik}$ ) = real( ab( j, 1_${ik}$ ),KIND=${ck}$)
           smin = s( 1_${ik}$ )
           amax = s( 1_${ik}$ )
           ! find the minimum and maximum diagonal elements.
           do i = 2, n
              s( i ) = real( ab( j, i ),KIND=${ck}$)
              smin = min( smin, s( i ) )
              amax = max( amax, s( i ) )
           end do
           if( smin<=zero ) then
              ! find the first non-positive diagonal element and return.
              do i = 1, n
                 if( s( i )<=zero ) then
                    info = i
                    return
                 end if
              end do
           else
              ! set the scale factors to the reciprocals
              ! of the diagonal elements.
              do i = 1, n
                 s( i ) = one / sqrt( s( i ) )
              end do
              ! compute scond = min(s(i)) / max(s(i))
              scond = sqrt( smin ) / sqrt( amax )
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pbequ

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_claqhb( uplo, n, kd, ab, ldab, s, scond, amax, equed )
     !! CLAQHB equilibrates an Hermitian band matrix A using the scaling
     !! factors in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: kd, ldab, n
           real(sp), intent(in) :: amax, scond
           ! Array Arguments 
           real(sp), intent(out) :: s(*)
           complex(sp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: thresh = 0.1e+0_sp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(sp) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_slamch( 'SAFE MINIMUM' ) / stdlib${ii}$_slamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored in band format.
                 do j = 1, n
                    cj = s( j )
                    do i = max( 1, j-kd ), j - 1
                       ab( kd+1+i-j, j ) = cj*s( i )*ab( kd+1+i-j, j )
                    end do
                    ab( kd+1, j ) = cj*cj*real( ab( kd+1, j ),KIND=sp)
                 end do
              else
                 ! lower triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    ab( 1_${ik}$, j ) = cj*cj*real( ab( 1_${ik}$, j ),KIND=sp)
                    do i = j + 1, min( n, j+kd )
                       ab( 1_${ik}$+i-j, j ) = cj*s( i )*ab( 1_${ik}$+i-j, j )
                    end do
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_claqhb

     pure module subroutine stdlib${ii}$_zlaqhb( uplo, n, kd, ab, ldab, s, scond, amax, equed )
     !! ZLAQHB equilibrates a Hermitian band matrix A
     !! using the scaling factors in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: kd, ldab, n
           real(dp), intent(in) :: amax, scond
           ! Array Arguments 
           real(dp), intent(out) :: s(*)
           complex(dp), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: thresh = 0.1e+0_dp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(dp) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_dlamch( 'SAFE MINIMUM' ) / stdlib${ii}$_dlamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored in band format.
                 do j = 1, n
                    cj = s( j )
                    do i = max( 1, j-kd ), j - 1
                       ab( kd+1+i-j, j ) = cj*s( i )*ab( kd+1+i-j, j )
                    end do
                    ab( kd+1, j ) = cj*cj*real( ab( kd+1, j ),KIND=dp)
                 end do
              else
                 ! lower triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    ab( 1_${ik}$, j ) = cj*cj*real( ab( 1_${ik}$, j ),KIND=dp)
                    do i = j + 1, min( n, j+kd )
                       ab( 1_${ik}$+i-j, j ) = cj*s( i )*ab( 1_${ik}$+i-j, j )
                    end do
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_zlaqhb

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$laqhb( uplo, n, kd, ab, ldab, s, scond, amax, equed )
     !! ZLAQHB: equilibrates a Hermitian band matrix A
     !! using the scaling factors in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: kd, ldab, n
           real(${ck}$), intent(in) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(out) :: s(*)
           complex(${ck}$), intent(inout) :: ab(ldab,*)
        ! =====================================================================
           ! Parameters 
           real(${ck}$), parameter :: thresh = 0.1e+0_${ck}$
           
           ! Local Scalars 
           integer(${ik}$) :: i, j
           real(${ck}$) :: cj, large, small
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' ) / stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored in band format.
                 do j = 1, n
                    cj = s( j )
                    do i = max( 1, j-kd ), j - 1
                       ab( kd+1+i-j, j ) = cj*s( i )*ab( kd+1+i-j, j )
                    end do
                    ab( kd+1, j ) = cj*cj*real( ab( kd+1, j ),KIND=${ck}$)
                 end do
              else
                 ! lower triangle of a is stored.
                 do j = 1, n
                    cj = s( j )
                    ab( 1_${ik}$, j ) = cj*cj*real( ab( 1_${ik}$, j ),KIND=${ck}$)
                    do i = j + 1, min( n, j+kd )
                       ab( 1_${ik}$+i-j, j ) = cj*s( i )*ab( 1_${ik}$+i-j, j )
                    end do
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_${ci}$laqhb

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sptcon( n, d, e, anorm, rcond, work, info )
     !! SPTCON computes the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite tridiagonal matrix
     !! using the factorization A = L*D*L**T or A = U**T*D*U computed by
     !! SPTTRF.
     !! Norm(inv(A)) is computed by a direct method, and the reciprocal of
     !! the condition number is computed as
     !! RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           real(sp), intent(in) :: d(*), e(*)
           real(sp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, ix
           real(sp) :: ainvnm
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPTCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           ! check that d(1:n) is positive.
           do i = 1, n
              if( d( i )<=zero )return
           end do
           ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
              ! m(i,j) =  abs(a(i,j)), i = j,
              ! m(i,j) = -abs(a(i,j)), i .ne. j,
           ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**t.
           ! solve m(l) * x = e.
           work( 1_${ik}$ ) = one
           do i = 2, n
              work( i ) = one + work( i-1 )*abs( e( i-1 ) )
           end do
           ! solve d * m(l)**t * x = b.
           work( n ) = work( n ) / d( n )
           do i = n - 1, 1, -1
              work( i ) = work( i ) / d( i ) + work( i+1 )*abs( e( i ) )
           end do
           ! compute ainvnm = max(x(i)), 1<=i<=n.
           ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ )
           ainvnm = abs( work( ix ) )
           ! compute the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           return
     end subroutine stdlib${ii}$_sptcon

     pure module subroutine stdlib${ii}$_dptcon( n, d, e, anorm, rcond, work, info )
     !! DPTCON computes the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite tridiagonal matrix
     !! using the factorization A = L*D*L**T or A = U**T*D*U computed by
     !! DPTTRF.
     !! Norm(inv(A)) is computed by a direct method, and the reciprocal of
     !! the condition number is computed as
     !! RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           real(dp), intent(in) :: d(*), e(*)
           real(dp), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, ix
           real(dp) :: ainvnm
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPTCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           ! check that d(1:n) is positive.
           do i = 1, n
              if( d( i )<=zero )return
           end do
           ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
              ! m(i,j) =  abs(a(i,j)), i = j,
              ! m(i,j) = -abs(a(i,j)), i .ne. j,
           ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**t.
           ! solve m(l) * x = e.
           work( 1_${ik}$ ) = one
           do i = 2, n
              work( i ) = one + work( i-1 )*abs( e( i-1 ) )
           end do
           ! solve d * m(l)**t * x = b.
           work( n ) = work( n ) / d( n )
           do i = n - 1, 1, -1
              work( i ) = work( i ) / d( i ) + work( i+1 )*abs( e( i ) )
           end do
           ! compute ainvnm = max(x(i)), 1<=i<=n.
           ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ )
           ainvnm = abs( work( ix ) )
           ! compute the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           return
     end subroutine stdlib${ii}$_dptcon

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$ptcon( n, d, e, anorm, rcond, work, info )
     !! DPTCON: computes the reciprocal of the condition number (in the
     !! 1-norm) of a real symmetric positive definite tridiagonal matrix
     !! using the factorization A = L*D*L**T or A = U**T*D*U computed by
     !! DPTTRF.
     !! Norm(inv(A)) is computed by a direct method, and the reciprocal of
     !! the condition number is computed as
     !! RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           real(${rk}$), intent(in) :: anorm
           real(${rk}$), intent(out) :: rcond
           ! Array Arguments 
           real(${rk}$), intent(in) :: d(*), e(*)
           real(${rk}$), intent(out) :: work(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, ix
           real(${rk}$) :: ainvnm
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPTCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           ! check that d(1:n) is positive.
           do i = 1, n
              if( d( i )<=zero )return
           end do
           ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
              ! m(i,j) =  abs(a(i,j)), i = j,
              ! m(i,j) = -abs(a(i,j)), i .ne. j,
           ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**t.
           ! solve m(l) * x = e.
           work( 1_${ik}$ ) = one
           do i = 2, n
              work( i ) = one + work( i-1 )*abs( e( i-1 ) )
           end do
           ! solve d * m(l)**t * x = b.
           work( n ) = work( n ) / d( n )
           do i = n - 1, 1, -1
              work( i ) = work( i ) / d( i ) + work( i+1 )*abs( e( i ) )
           end do
           ! compute ainvnm = max(x(i)), 1<=i<=n.
           ix = stdlib${ii}$_i${ri}$amax( n, work, 1_${ik}$ )
           ainvnm = abs( work( ix ) )
           ! compute the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           return
     end subroutine stdlib${ii}$_${ri}$ptcon

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cptcon( n, d, e, anorm, rcond, rwork, info )
     !! CPTCON computes the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite tridiagonal matrix
     !! using the factorization A = L*D*L**H or A = U**H*D*U computed by
     !! CPTTRF.
     !! Norm(inv(A)) is computed by a direct method, and the reciprocal of
     !! the condition number is computed as
     !! RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           real(sp), intent(in) :: anorm
           real(sp), intent(out) :: rcond
           ! Array Arguments 
           real(sp), intent(in) :: d(*)
           real(sp), intent(out) :: rwork(*)
           complex(sp), intent(in) :: e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, ix
           real(sp) :: ainvnm
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPTCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           ! check that d(1:n) is positive.
           do i = 1, n
              if( d( i )<=zero )return
           end do
           ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
              ! m(i,j) =  abs(a(i,j)), i = j,
              ! m(i,j) = -abs(a(i,j)), i .ne. j,
           ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**h.
           ! solve m(l) * x = e.
           rwork( 1_${ik}$ ) = one
           do i = 2, n
              rwork( i ) = one + rwork( i-1 )*abs( e( i-1 ) )
           end do
           ! solve d * m(l)**h * x = b.
           rwork( n ) = rwork( n ) / d( n )
           do i = n - 1, 1, -1
              rwork( i ) = rwork( i ) / d( i ) + rwork( i+1 )*abs( e( i ) )
           end do
           ! compute ainvnm = max(x(i)), 1<=i<=n.
           ix = stdlib${ii}$_isamax( n, rwork, 1_${ik}$ )
           ainvnm = abs( rwork( ix ) )
           ! compute the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           return
     end subroutine stdlib${ii}$_cptcon

     pure module subroutine stdlib${ii}$_zptcon( n, d, e, anorm, rcond, rwork, info )
     !! ZPTCON computes the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite tridiagonal matrix
     !! using the factorization A = L*D*L**H or A = U**H*D*U computed by
     !! ZPTTRF.
     !! Norm(inv(A)) is computed by a direct method, and the reciprocal of
     !! the condition number is computed as
     !! RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           real(dp), intent(in) :: anorm
           real(dp), intent(out) :: rcond
           ! Array Arguments 
           real(dp), intent(in) :: d(*)
           real(dp), intent(out) :: rwork(*)
           complex(dp), intent(in) :: e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, ix
           real(dp) :: ainvnm
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPTCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           ! check that d(1:n) is positive.
           do i = 1, n
              if( d( i )<=zero )return
           end do
           ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
              ! m(i,j) =  abs(a(i,j)), i = j,
              ! m(i,j) = -abs(a(i,j)), i .ne. j,
           ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**h.
           ! solve m(l) * x = e.
           rwork( 1_${ik}$ ) = one
           do i = 2, n
              rwork( i ) = one + rwork( i-1 )*abs( e( i-1 ) )
           end do
           ! solve d * m(l)**h * x = b.
           rwork( n ) = rwork( n ) / d( n )
           do i = n - 1, 1, -1
              rwork( i ) = rwork( i ) / d( i ) + rwork( i+1 )*abs( e( i ) )
           end do
           ! compute ainvnm = max(x(i)), 1<=i<=n.
           ix = stdlib${ii}$_idamax( n, rwork, 1_${ik}$ )
           ainvnm = abs( rwork( ix ) )
           ! compute the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           return
     end subroutine stdlib${ii}$_zptcon

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ptcon( n, d, e, anorm, rcond, rwork, info )
     !! ZPTCON: computes the reciprocal of the condition number (in the
     !! 1-norm) of a complex Hermitian positive definite tridiagonal matrix
     !! using the factorization A = L*D*L**H or A = U**H*D*U computed by
     !! ZPTTRF.
     !! Norm(inv(A)) is computed by a direct method, and the reciprocal of
     !! the condition number is computed as
     !! RCOND = 1 / (ANORM * norm(inv(A))).
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           real(${ck}$), intent(in) :: anorm
           real(${ck}$), intent(out) :: rcond
           ! Array Arguments 
           real(${ck}$), intent(in) :: d(*)
           real(${ck}$), intent(out) :: rwork(*)
           complex(${ck}$), intent(in) :: e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, ix
           real(${ck}$) :: ainvnm
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( anorm<zero ) then
              info = -4_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPTCON', -info )
              return
           end if
           ! quick return if possible
           rcond = zero
           if( n==0_${ik}$ ) then
              rcond = one
              return
           else if( anorm==zero ) then
              return
           end if
           ! check that d(1:n) is positive.
           do i = 1, n
              if( d( i )<=zero )return
           end do
           ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
              ! m(i,j) =  abs(a(i,j)), i = j,
              ! m(i,j) = -abs(a(i,j)), i .ne. j,
           ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**h.
           ! solve m(l) * x = e.
           rwork( 1_${ik}$ ) = one
           do i = 2, n
              rwork( i ) = one + rwork( i-1 )*abs( e( i-1 ) )
           end do
           ! solve d * m(l)**h * x = b.
           rwork( n ) = rwork( n ) / d( n )
           do i = n - 1, 1, -1
              rwork( i ) = rwork( i ) / d( i ) + rwork( i+1 )*abs( e( i ) )
           end do
           ! compute ainvnm = max(x(i)), 1<=i<=n.
           ix = stdlib${ii}$_i${c2ri(ci)}$amax( n, rwork, 1_${ik}$ )
           ainvnm = abs( rwork( ix ) )
           ! compute the reciprocal condition number.
           if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm
           return
     end subroutine stdlib${ii}$_${ci}$ptcon

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spttrf( n, d, e, info )
     !! SPTTRF computes the L*D*L**T factorization of a real symmetric
     !! positive definite tridiagonal matrix A.  The factorization may also
     !! be regarded as having the form A = U**T*D*U.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(sp), intent(inout) :: d(*), e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, i4
           real(sp) :: ei
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
              call stdlib${ii}$_xerbla( 'SPTTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! compute the l*d*l**t (or u**t*d*u) factorization of a.
           i4 = mod( n-1, 4_${ik}$ )
           do i = 1, i4
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ei = e( i )
              e( i ) = ei / d( i )
              d( i+1 ) = d( i+1 ) - e( i )*ei
           end do
           loop_20: do i = i4 + 1, n - 4, 4
              ! drop out of the loop if d(i) <= 0: the matrix is not positive
              ! definite.
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ! solve for e(i) and d(i+1).
              ei = e( i )
              e( i ) = ei / d( i )
              d( i+1 ) = d( i+1 ) - e( i )*ei
              if( d( i+1 )<=zero ) then
                 info = i + 1_${ik}$
                 go to 30
              end if
              ! solve for e(i+1) and d(i+2).
              ei = e( i+1 )
              e( i+1 ) = ei / d( i+1 )
              d( i+2 ) = d( i+2 ) - e( i+1 )*ei
              if( d( i+2 )<=zero ) then
                 info = i + 2_${ik}$
                 go to 30
              end if
              ! solve for e(i+2) and d(i+3).
              ei = e( i+2 )
              e( i+2 ) = ei / d( i+2 )
              d( i+3 ) = d( i+3 ) - e( i+2 )*ei
              if( d( i+3 )<=zero ) then
                 info = i + 3_${ik}$
                 go to 30
              end if
              ! solve for e(i+3) and d(i+4).
              ei = e( i+3 )
              e( i+3 ) = ei / d( i+3 )
              d( i+4 ) = d( i+4 ) - e( i+3 )*ei
           end do loop_20
           ! check d(n) for positive definiteness.
           if( d( n )<=zero )info = n
           30 continue
           return
     end subroutine stdlib${ii}$_spttrf

     pure module subroutine stdlib${ii}$_dpttrf( n, d, e, info )
     !! DPTTRF computes the L*D*L**T factorization of a real symmetric
     !! positive definite tridiagonal matrix A.  The factorization may also
     !! be regarded as having the form A = U**T*D*U.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(dp), intent(inout) :: d(*), e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, i4
           real(dp) :: ei
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
              call stdlib${ii}$_xerbla( 'DPTTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! compute the l*d*l**t (or u**t*d*u) factorization of a.
           i4 = mod( n-1, 4_${ik}$ )
           do i = 1, i4
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ei = e( i )
              e( i ) = ei / d( i )
              d( i+1 ) = d( i+1 ) - e( i )*ei
           end do
           loop_20: do i = i4 + 1, n - 4, 4
              ! drop out of the loop if d(i) <= 0: the matrix is not positive
              ! definite.
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ! solve for e(i) and d(i+1).
              ei = e( i )
              e( i ) = ei / d( i )
              d( i+1 ) = d( i+1 ) - e( i )*ei
              if( d( i+1 )<=zero ) then
                 info = i + 1_${ik}$
                 go to 30
              end if
              ! solve for e(i+1) and d(i+2).
              ei = e( i+1 )
              e( i+1 ) = ei / d( i+1 )
              d( i+2 ) = d( i+2 ) - e( i+1 )*ei
              if( d( i+2 )<=zero ) then
                 info = i + 2_${ik}$
                 go to 30
              end if
              ! solve for e(i+2) and d(i+3).
              ei = e( i+2 )
              e( i+2 ) = ei / d( i+2 )
              d( i+3 ) = d( i+3 ) - e( i+2 )*ei
              if( d( i+3 )<=zero ) then
                 info = i + 3_${ik}$
                 go to 30
              end if
              ! solve for e(i+3) and d(i+4).
              ei = e( i+3 )
              e( i+3 ) = ei / d( i+3 )
              d( i+4 ) = d( i+4 ) - e( i+3 )*ei
           end do loop_20
           ! check d(n) for positive definiteness.
           if( d( n )<=zero )info = n
           30 continue
           return
     end subroutine stdlib${ii}$_dpttrf

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pttrf( n, d, e, info )
     !! DPTTRF: computes the L*D*L**T factorization of a real symmetric
     !! positive definite tridiagonal matrix A.  The factorization may also
     !! be regarded as having the form A = U**T*D*U.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(${rk}$), intent(inout) :: d(*), e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, i4
           real(${rk}$) :: ei
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
              call stdlib${ii}$_xerbla( 'DPTTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! compute the l*d*l**t (or u**t*d*u) factorization of a.
           i4 = mod( n-1, 4_${ik}$ )
           do i = 1, i4
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ei = e( i )
              e( i ) = ei / d( i )
              d( i+1 ) = d( i+1 ) - e( i )*ei
           end do
           loop_20: do i = i4 + 1, n - 4, 4
              ! drop out of the loop if d(i) <= 0: the matrix is not positive
              ! definite.
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ! solve for e(i) and d(i+1).
              ei = e( i )
              e( i ) = ei / d( i )
              d( i+1 ) = d( i+1 ) - e( i )*ei
              if( d( i+1 )<=zero ) then
                 info = i + 1_${ik}$
                 go to 30
              end if
              ! solve for e(i+1) and d(i+2).
              ei = e( i+1 )
              e( i+1 ) = ei / d( i+1 )
              d( i+2 ) = d( i+2 ) - e( i+1 )*ei
              if( d( i+2 )<=zero ) then
                 info = i + 2_${ik}$
                 go to 30
              end if
              ! solve for e(i+2) and d(i+3).
              ei = e( i+2 )
              e( i+2 ) = ei / d( i+2 )
              d( i+3 ) = d( i+3 ) - e( i+2 )*ei
              if( d( i+3 )<=zero ) then
                 info = i + 3_${ik}$
                 go to 30
              end if
              ! solve for e(i+3) and d(i+4).
              ei = e( i+3 )
              e( i+3 ) = ei / d( i+3 )
              d( i+4 ) = d( i+4 ) - e( i+3 )*ei
           end do loop_20
           ! check d(n) for positive definiteness.
           if( d( n )<=zero )info = n
           30 continue
           return
     end subroutine stdlib${ii}$_${ri}$pttrf

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpttrf( n, d, e, info )
     !! CPTTRF computes the L*D*L**H factorization of a complex Hermitian
     !! positive definite tridiagonal matrix A.  The factorization may also
     !! be regarded as having the form A = U**H *D*U.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(sp), intent(inout) :: d(*)
           complex(sp), intent(inout) :: e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, i4
           real(sp) :: eii, eir, f, g
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
              call stdlib${ii}$_xerbla( 'CPTTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! compute the l*d*l**h (or u**h *d*u) factorization of a.
           i4 = mod( n-1, 4_${ik}$ )
           do i = 1, i4
              if( d( i )<=zero ) then
                 info = i
                 go to 20
              end if
              eir = real( e( i ),KIND=sp)
              eii = aimag( e( i ) )
              f = eir / d( i )
              g = eii / d( i )
              e( i ) = cmplx( f, g,KIND=sp)
              d( i+1 ) = d( i+1 ) - f*eir - g*eii
           end do
           loop_110: do i = i4+1, n - 4, 4
              ! drop out of the loop if d(i) <= 0: the matrix is not positive
              ! definite.
              if( d( i )<=zero ) then
                 info = i
                 go to 20
              end if
              ! solve for e(i) and d(i+1).
              eir = real( e( i ),KIND=sp)
              eii = aimag( e( i ) )
              f = eir / d( i )
              g = eii / d( i )
              e( i ) = cmplx( f, g,KIND=sp)
              d( i+1 ) = d( i+1 ) - f*eir - g*eii
              if( d( i+1 )<=zero ) then
                 info = i+1
                 go to 20
              end if
              ! solve for e(i+1) and d(i+2).
              eir = real( e( i+1 ),KIND=sp)
              eii = aimag( e( i+1 ) )
              f = eir / d( i+1 )
              g = eii / d( i+1 )
              e( i+1 ) = cmplx( f, g,KIND=sp)
              d( i+2 ) = d( i+2 ) - f*eir - g*eii
              if( d( i+2 )<=zero ) then
                 info = i+2
                 go to 20
              end if
              ! solve for e(i+2) and d(i+3).
              eir = real( e( i+2 ),KIND=sp)
              eii = aimag( e( i+2 ) )
              f = eir / d( i+2 )
              g = eii / d( i+2 )
              e( i+2 ) = cmplx( f, g,KIND=sp)
              d( i+3 ) = d( i+3 ) - f*eir - g*eii
              if( d( i+3 )<=zero ) then
                 info = i+3
                 go to 20
              end if
              ! solve for e(i+3) and d(i+4).
              eir = real( e( i+3 ),KIND=sp)
              eii = aimag( e( i+3 ) )
              f = eir / d( i+3 )
              g = eii / d( i+3 )
              e( i+3 ) = cmplx( f, g,KIND=sp)
              d( i+4 ) = d( i+4 ) - f*eir - g*eii
           end do loop_110
           ! check d(n) for positive definiteness.
           if( d( n )<=zero )info = n
           20 continue
           return
     end subroutine stdlib${ii}$_cpttrf

     pure module subroutine stdlib${ii}$_zpttrf( n, d, e, info )
     !! ZPTTRF computes the L*D*L**H factorization of a complex Hermitian
     !! positive definite tridiagonal matrix A.  The factorization may also
     !! be regarded as having the form A = U**H *D*U.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(dp), intent(inout) :: d(*)
           complex(dp), intent(inout) :: e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, i4
           real(dp) :: eii, eir, f, g
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
              call stdlib${ii}$_xerbla( 'ZPTTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! compute the l*d*l**h (or u**h *d*u) factorization of a.
           i4 = mod( n-1, 4_${ik}$ )
           do i = 1, i4
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              eir = real( e( i ),KIND=dp)
              eii = aimag( e( i ) )
              f = eir / d( i )
              g = eii / d( i )
              e( i ) = cmplx( f, g,KIND=dp)
              d( i+1 ) = d( i+1 ) - f*eir - g*eii
           end do
           loop_20: do i = i4 + 1, n - 4, 4
              ! drop out of the loop if d(i) <= 0: the matrix is not positive
              ! definite.
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ! solve for e(i) and d(i+1).
              eir = real( e( i ),KIND=dp)
              eii = aimag( e( i ) )
              f = eir / d( i )
              g = eii / d( i )
              e( i ) = cmplx( f, g,KIND=dp)
              d( i+1 ) = d( i+1 ) - f*eir - g*eii
              if( d( i+1 )<=zero ) then
                 info = i + 1_${ik}$
                 go to 30
              end if
              ! solve for e(i+1) and d(i+2).
              eir = real( e( i+1 ),KIND=dp)
              eii = aimag( e( i+1 ) )
              f = eir / d( i+1 )
              g = eii / d( i+1 )
              e( i+1 ) = cmplx( f, g,KIND=dp)
              d( i+2 ) = d( i+2 ) - f*eir - g*eii
              if( d( i+2 )<=zero ) then
                 info = i + 2_${ik}$
                 go to 30
              end if
              ! solve for e(i+2) and d(i+3).
              eir = real( e( i+2 ),KIND=dp)
              eii = aimag( e( i+2 ) )
              f = eir / d( i+2 )
              g = eii / d( i+2 )
              e( i+2 ) = cmplx( f, g,KIND=dp)
              d( i+3 ) = d( i+3 ) - f*eir - g*eii
              if( d( i+3 )<=zero ) then
                 info = i + 3_${ik}$
                 go to 30
              end if
              ! solve for e(i+3) and d(i+4).
              eir = real( e( i+3 ),KIND=dp)
              eii = aimag( e( i+3 ) )
              f = eir / d( i+3 )
              g = eii / d( i+3 )
              e( i+3 ) = cmplx( f, g,KIND=dp)
              d( i+4 ) = d( i+4 ) - f*eir - g*eii
           end do loop_20
           ! check d(n) for positive definiteness.
           if( d( n )<=zero )info = n
           30 continue
           return
     end subroutine stdlib${ii}$_zpttrf

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pttrf( n, d, e, info )
     !! ZPTTRF: computes the L*D*L**H factorization of a complex Hermitian
     !! positive definite tridiagonal matrix A.  The factorization may also
     !! be regarded as having the form A = U**H *D*U.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: n
           ! Array Arguments 
           real(${ck}$), intent(inout) :: d(*)
           complex(${ck}$), intent(inout) :: e(*)
        ! =====================================================================
           
           ! Local Scalars 
           integer(${ik}$) :: i, i4
           real(${ck}$) :: eii, eir, f, g
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
              call stdlib${ii}$_xerbla( 'ZPTTRF', -info )
              return
           end if
           ! quick return if possible
           if( n==0 )return
           ! compute the l*d*l**h (or u**h *d*u) factorization of a.
           i4 = mod( n-1, 4_${ik}$ )
           do i = 1, i4
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              eir = real( e( i ),KIND=${ck}$)
              eii = aimag( e( i ) )
              f = eir / d( i )
              g = eii / d( i )
              e( i ) = cmplx( f, g,KIND=${ck}$)
              d( i+1 ) = d( i+1 ) - f*eir - g*eii
           end do
           loop_20: do i = i4 + 1, n - 4, 4
              ! drop out of the loop if d(i) <= 0: the matrix is not positive
              ! definite.
              if( d( i )<=zero ) then
                 info = i
                 go to 30
              end if
              ! solve for e(i) and d(i+1).
              eir = real( e( i ),KIND=${ck}$)
              eii = aimag( e( i ) )
              f = eir / d( i )
              g = eii / d( i )
              e( i ) = cmplx( f, g,KIND=${ck}$)
              d( i+1 ) = d( i+1 ) - f*eir - g*eii
              if( d( i+1 )<=zero ) then
                 info = i + 1_${ik}$
                 go to 30
              end if
              ! solve for e(i+1) and d(i+2).
              eir = real( e( i+1 ),KIND=${ck}$)
              eii = aimag( e( i+1 ) )
              f = eir / d( i+1 )
              g = eii / d( i+1 )
              e( i+1 ) = cmplx( f, g,KIND=${ck}$)
              d( i+2 ) = d( i+2 ) - f*eir - g*eii
              if( d( i+2 )<=zero ) then
                 info = i + 2_${ik}$
                 go to 30
              end if
              ! solve for e(i+2) and d(i+3).
              eir = real( e( i+2 ),KIND=${ck}$)
              eii = aimag( e( i+2 ) )
              f = eir / d( i+2 )
              g = eii / d( i+2 )
              e( i+2 ) = cmplx( f, g,KIND=${ck}$)
              d( i+3 ) = d( i+3 ) - f*eir - g*eii
              if( d( i+3 )<=zero ) then
                 info = i + 3_${ik}$
                 go to 30
              end if
              ! solve for e(i+3) and d(i+4).
              eir = real( e( i+3 ),KIND=${ck}$)
              eii = aimag( e( i+3 ) )
              f = eir / d( i+3 )
              g = eii / d( i+3 )
              e( i+3 ) = cmplx( f, g,KIND=${ck}$)
              d( i+4 ) = d( i+4 ) - f*eir - g*eii
           end do loop_20
           ! check d(n) for positive definiteness.
           if( d( n )<=zero )info = n
           30 continue
           return
     end subroutine stdlib${ii}$_${ci}$pttrf

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_spttrs( n, nrhs, d, e, b, ldb, info )
     !! SPTTRS solves a tridiagonal system of the form
     !! A * X = B
     !! using the L*D*L**T factorization of A computed by SPTTRF.  D is a
     !! diagonal matrix specified in the vector D, L is a unit bidiagonal
     !! matrix whose subdiagonal is specified in the vector E, and X and B
     !! are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(inout) :: b(ldb,*)
           real(sp), intent(in) :: d(*), e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: j, jb, nb
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPTTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! determine the number of right-hand sides to solve at a time.
           if( nrhs==1_${ik}$ ) then
              nb = 1_${ik}$
           else
              nb = max( 1_${ik}$, stdlib${ii}$_ilaenv( 1_${ik}$, 'SPTTRS', ' ', n, nrhs, -1_${ik}$, -1_${ik}$ ) )
           end if
           if( nb>=nrhs ) then
              call stdlib${ii}$_sptts2( n, nrhs, d, e, b, ldb )
           else
              do j = 1, nrhs, nb
                 jb = min( nrhs-j+1, nb )
                 call stdlib${ii}$_sptts2( n, jb, d, e, b( 1_${ik}$, j ), ldb )
              end do
           end if
           return
     end subroutine stdlib${ii}$_spttrs

     pure module subroutine stdlib${ii}$_dpttrs( n, nrhs, d, e, b, ldb, info )
     !! DPTTRS solves a tridiagonal system of the form
     !! A * X = B
     !! using the L*D*L**T factorization of A computed by DPTTRF.  D is a
     !! diagonal matrix specified in the vector D, L is a unit bidiagonal
     !! matrix whose subdiagonal is specified in the vector E, and X and B
     !! are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(inout) :: b(ldb,*)
           real(dp), intent(in) :: d(*), e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: j, jb, nb
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPTTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! determine the number of right-hand sides to solve at a time.
           if( nrhs==1_${ik}$ ) then
              nb = 1_${ik}$
           else
              nb = max( 1_${ik}$, stdlib${ii}$_ilaenv( 1_${ik}$, 'DPTTRS', ' ', n, nrhs, -1_${ik}$, -1_${ik}$ ) )
           end if
           if( nb>=nrhs ) then
              call stdlib${ii}$_dptts2( n, nrhs, d, e, b, ldb )
           else
              do j = 1, nrhs, nb
                 jb = min( nrhs-j+1, nb )
                 call stdlib${ii}$_dptts2( n, jb, d, e, b( 1_${ik}$, j ), ldb )
              end do
           end if
           return
     end subroutine stdlib${ii}$_dpttrs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$pttrs( n, nrhs, d, e, b, ldb, info )
     !! DPTTRS: solves a tridiagonal system of the form
     !! A * X = B
     !! using the L*D*L**T factorization of A computed by DPTTRF.  D is a
     !! diagonal matrix specified in the vector D, L is a unit bidiagonal
     !! matrix whose subdiagonal is specified in the vector E, and X and B
     !! are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(inout) :: b(ldb,*)
           real(${rk}$), intent(in) :: d(*), e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: j, jb, nb
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -6_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPTTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! determine the number of right-hand sides to solve at a time.
           if( nrhs==1_${ik}$ ) then
              nb = 1_${ik}$
           else
              nb = max( 1_${ik}$, stdlib${ii}$_ilaenv( 1_${ik}$, 'DPTTRS', ' ', n, nrhs, -1_${ik}$, -1_${ik}$ ) )
           end if
           if( nb>=nrhs ) then
              call stdlib${ii}$_${ri}$ptts2( n, nrhs, d, e, b, ldb )
           else
              do j = 1, nrhs, nb
                 jb = min( nrhs-j+1, nb )
                 call stdlib${ii}$_${ri}$ptts2( n, jb, d, e, b( 1_${ik}$, j ), ldb )
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ri}$pttrs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cpttrs( uplo, n, nrhs, d, e, b, ldb, info )
     !! CPTTRS solves a tridiagonal system of the form
     !! A * X = B
     !! using the factorization A = U**H*D*U or A = L*D*L**H computed by CPTTRF.
     !! D is a diagonal matrix specified in the vector D, U (or L) is a unit
     !! bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
     !! the vector E, and X and B are N by NRHS matrices.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: d(*)
           complex(sp), intent(inout) :: b(ldb,*)
           complex(sp), intent(in) :: e(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: iuplo, j, jb, nb
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           upper = ( uplo=='U' .or. uplo=='U' )
           if( .not.upper .and. .not.( uplo=='L' .or. uplo=='L' ) ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPTTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! determine the number of right-hand sides to solve at a time.
           if( nrhs==1_${ik}$ ) then
              nb = 1_${ik}$
           else
              nb = max( 1_${ik}$, stdlib${ii}$_ilaenv( 1_${ik}$, 'CPTTRS', uplo, n, nrhs, -1_${ik}$, -1_${ik}$ ) )
           end if
           ! decode uplo
           if( upper ) then
              iuplo = 1_${ik}$
           else
              iuplo = 0_${ik}$
           end if
           if( nb>=nrhs ) then
              call stdlib${ii}$_cptts2( iuplo, n, nrhs, d, e, b, ldb )
           else
              do j = 1, nrhs, nb
                 jb = min( nrhs-j+1, nb )
                 call stdlib${ii}$_cptts2( iuplo, n, jb, d, e, b( 1_${ik}$, j ), ldb )
              end do
           end if
           return
     end subroutine stdlib${ii}$_cpttrs

     pure module subroutine stdlib${ii}$_zpttrs( uplo, n, nrhs, d, e, b, ldb, info )
     !! ZPTTRS solves a tridiagonal system of the form
     !! A * X = B
     !! using the factorization A = U**H *D* U or A = L*D*L**H computed by ZPTTRF.
     !! D is a diagonal matrix specified in the vector D, U (or L) is a unit
     !! bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
     !! the vector E, and X and B are N by NRHS matrices.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: d(*)
           complex(dp), intent(inout) :: b(ldb,*)
           complex(dp), intent(in) :: e(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: iuplo, j, jb, nb
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           upper = ( uplo=='U' .or. uplo=='U' )
           if( .not.upper .and. .not.( uplo=='L' .or. uplo=='L' ) ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPTTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! determine the number of right-hand sides to solve at a time.
           if( nrhs==1_${ik}$ ) then
              nb = 1_${ik}$
           else
              nb = max( 1_${ik}$, stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPTTRS', uplo, n, nrhs, -1_${ik}$, -1_${ik}$ ) )
           end if
           ! decode uplo
           if( upper ) then
              iuplo = 1_${ik}$
           else
              iuplo = 0_${ik}$
           end if
           if( nb>=nrhs ) then
              call stdlib${ii}$_zptts2( iuplo, n, nrhs, d, e, b, ldb )
           else
              do j = 1, nrhs, nb
                 jb = min( nrhs-j+1, nb )
                 call stdlib${ii}$_zptts2( iuplo, n, jb, d, e, b( 1_${ik}$, j ), ldb )
              end do
           end if
           return
     end subroutine stdlib${ii}$_zpttrs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$pttrs( uplo, n, nrhs, d, e, b, ldb, info )
     !! ZPTTRS: solves a tridiagonal system of the form
     !! A * X = B
     !! using the factorization A = U**H *D* U or A = L*D*L**H computed by ZPTTRF.
     !! D is a diagonal matrix specified in the vector D, U (or L) is a unit
     !! bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
     !! the vector E, and X and B are N by NRHS matrices.
        ! -- 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) :: ldb, n, nrhs
           ! Array Arguments 
           real(${ck}$), intent(in) :: d(*)
           complex(${ck}$), intent(inout) :: b(ldb,*)
           complex(${ck}$), intent(in) :: e(*)
        ! =====================================================================
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: iuplo, j, jb, nb
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input arguments.
           info = 0_${ik}$
           upper = ( uplo=='U' .or. uplo=='U' )
           if( .not.upper .and. .not.( uplo=='L' .or. uplo=='L' ) ) then
              info = -1_${ik}$
           else if( n<0_${ik}$ ) then
              info = -2_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -7_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPTTRS', -info )
              return
           end if
           ! quick return if possible
           if( n==0 .or. nrhs==0 )return
           ! determine the number of right-hand sides to solve at a time.
           if( nrhs==1_${ik}$ ) then
              nb = 1_${ik}$
           else
              nb = max( 1_${ik}$, stdlib${ii}$_ilaenv( 1_${ik}$, 'ZPTTRS', uplo, n, nrhs, -1_${ik}$, -1_${ik}$ ) )
           end if
           ! decode uplo
           if( upper ) then
              iuplo = 1_${ik}$
           else
              iuplo = 0_${ik}$
           end if
           if( nb>=nrhs ) then
              call stdlib${ii}$_${ci}$ptts2( iuplo, n, nrhs, d, e, b, ldb )
           else
              do j = 1, nrhs, nb
                 jb = min( nrhs-j+1, nb )
                 call stdlib${ii}$_${ci}$ptts2( iuplo, n, jb, d, e, b( 1_${ik}$, j ), ldb )
              end do
           end if
           return
     end subroutine stdlib${ii}$_${ci}$pttrs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sptts2( n, nrhs, d, e, b, ldb )
     !! SPTTS2 solves a tridiagonal system of the form
     !! A * X = B
     !! using the L*D*L**T factorization of A computed by SPTTRF.  D is a
     !! diagonal matrix specified in the vector D, L is a unit bidiagonal
     !! matrix whose subdiagonal is specified in the vector E, and X and B
     !! are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(inout) :: b(ldb,*)
           real(sp), intent(in) :: d(*), e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           ! Executable Statements 
           ! quick return if possible
           if( n<=1_${ik}$ ) then
              if( n==1_${ik}$ )call stdlib${ii}$_sscal( nrhs, 1. / d( 1_${ik}$ ), b, ldb )
              return
           end if
           ! solve a * x = b using the factorization a = l*d*l**t,
           ! overwriting each right hand side vector with its solution.
           do j = 1, nrhs
                 ! solve l * x = b.
              do i = 2, n
                 b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
              end do
                 ! solve d * l**t * x = b.
              b( n, j ) = b( n, j ) / d( n )
              do i = n - 1, 1, -1
                 b( i, j ) = b( i, j ) / d( i ) - b( i+1, j )*e( i )
              end do
           end do
           return
     end subroutine stdlib${ii}$_sptts2

     pure module subroutine stdlib${ii}$_dptts2( n, nrhs, d, e, b, ldb )
     !! DPTTS2 solves a tridiagonal system of the form
     !! A * X = B
     !! using the L*D*L**T factorization of A computed by DPTTRF.  D is a
     !! diagonal matrix specified in the vector D, L is a unit bidiagonal
     !! matrix whose subdiagonal is specified in the vector E, and X and B
     !! are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(inout) :: b(ldb,*)
           real(dp), intent(in) :: d(*), e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           ! Executable Statements 
           ! quick return if possible
           if( n<=1_${ik}$ ) then
              if( n==1_${ik}$ )call stdlib${ii}$_dscal( nrhs, 1._dp / d( 1_${ik}$ ), b, ldb )
              return
           end if
           ! solve a * x = b using the factorization a = l*d*l**t,
           ! overwriting each right hand side vector with its solution.
           do j = 1, nrhs
                 ! solve l * x = b.
              do i = 2, n
                 b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
              end do
                 ! solve d * l**t * x = b.
              b( n, j ) = b( n, j ) / d( n )
              do i = n - 1, 1, -1
                 b( i, j ) = b( i, j ) / d( i ) - b( i+1, j )*e( i )
              end do
           end do
           return
     end subroutine stdlib${ii}$_dptts2

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$ptts2( n, nrhs, d, e, b, ldb )
     !! DPTTS2: solves a tridiagonal system of the form
     !! A * X = B
     !! using the L*D*L**T factorization of A computed by DPTTRF.  D is a
     !! diagonal matrix specified in the vector D, L is a unit bidiagonal
     !! matrix whose subdiagonal is specified in the vector E, and X and B
     !! are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: ldb, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(inout) :: b(ldb,*)
           real(${rk}$), intent(in) :: d(*), e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           ! Executable Statements 
           ! quick return if possible
           if( n<=1_${ik}$ ) then
              if( n==1_${ik}$ )call stdlib${ii}$_${ri}$scal( nrhs, 1._${rk}$ / d( 1_${ik}$ ), b, ldb )
              return
           end if
           ! solve a * x = b using the factorization a = l*d*l**t,
           ! overwriting each right hand side vector with its solution.
           do j = 1, nrhs
                 ! solve l * x = b.
              do i = 2, n
                 b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
              end do
                 ! solve d * l**t * x = b.
              b( n, j ) = b( n, j ) / d( n )
              do i = n - 1, 1, -1
                 b( i, j ) = b( i, j ) / d( i ) - b( i+1, j )*e( i )
              end do
           end do
           return
     end subroutine stdlib${ii}$_${ri}$ptts2

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cptts2( iuplo, n, nrhs, d, e, b, ldb )
     !! CPTTS2 solves a tridiagonal system of the form
     !! A * X = B
     !! using the factorization A = U**H*D*U or A = L*D*L**H computed by CPTTRF.
     !! D is a diagonal matrix specified in the vector D, U (or L) is a unit
     !! bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
     !! the vector E, and X and B are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: iuplo, ldb, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: d(*)
           complex(sp), intent(inout) :: b(ldb,*)
           complex(sp), intent(in) :: e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=1_${ik}$ ) then
              if( n==1_${ik}$ )call stdlib${ii}$_csscal( nrhs, 1. / d( 1_${ik}$ ), b, ldb )
              return
           end if
           if( iuplo==1_${ik}$ ) then
              ! solve a * x = b using the factorization a = u**h *d*u,
              ! overwriting each right hand side vector with its solution.
              if( nrhs<=2_${ik}$ ) then
                 j = 1_${ik}$
                 5 continue
                 ! solve u**h * x = b.
                 do i = 2, n
                    b( i, j ) = b( i, j ) - b( i-1, j )*conjg( e( i-1 ) )
                 end do
                 ! solve d * u * x = b.
                 do i = 1, n
                    b( i, j ) = b( i, j ) / d( i )
                 end do
                 do i = n - 1, 1, -1
                    b( i, j ) = b( i, j ) - b( i+1, j )*e( i )
                 end do
                 if( j<nrhs ) then
                    j = j + 1_${ik}$
                    go to 5
                 end if
              else
                 do j = 1, nrhs
                    ! solve u**h * x = b.
                    do i = 2, n
                       b( i, j ) = b( i, j ) - b( i-1, j )*conjg( e( i-1 ) )
                    end do
                    ! solve d * u * x = b.
                    b( n, j ) = b( n, j ) / d( n )
                    do i = n - 1, 1, -1
                       b( i, j ) = b( i, j ) / d( i ) - b( i+1, j )*e( i )
                    end do
                 end do
              end if
           else
              ! solve a * x = b using the factorization a = l*d*l**h,
              ! overwriting each right hand side vector with its solution.
              if( nrhs<=2_${ik}$ ) then
                 j = 1_${ik}$
                 65 continue
                 ! solve l * x = b.
                 do i = 2, n
                    b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
                 end do
                 ! solve d * l**h * x = b.
                 do i = 1, n
                    b( i, j ) = b( i, j ) / d( i )
                 end do
                 do i = n - 1, 1, -1
                    b( i, j ) = b( i, j ) - b( i+1, j )*conjg( e( i ) )
                 end do
                 if( j<nrhs ) then
                    j = j + 1_${ik}$
                    go to 65
                 end if
              else
                 do j = 1, nrhs
                    ! solve l * x = b.
                    do i = 2, n
                       b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
                    end do
                    ! solve d * l**h * x = b.
                    b( n, j ) = b( n, j ) / d( n )
                    do i = n - 1, 1, -1
                       b( i, j ) = b( i, j ) / d( i ) -b( i+1, j )*conjg( e( i ) )
                    end do
                 end do
              end if
           end if
           return
     end subroutine stdlib${ii}$_cptts2

     pure module subroutine stdlib${ii}$_zptts2( iuplo, n, nrhs, d, e, b, ldb )
     !! ZPTTS2 solves a tridiagonal system of the form
     !! A * X = B
     !! using the factorization A = U**H *D*U or A = L*D*L**H computed by ZPTTRF.
     !! D is a diagonal matrix specified in the vector D, U (or L) is a unit
     !! bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
     !! the vector E, and X and B are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: iuplo, ldb, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: d(*)
           complex(dp), intent(inout) :: b(ldb,*)
           complex(dp), intent(in) :: e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=1_${ik}$ ) then
              if( n==1_${ik}$ )call stdlib${ii}$_zdscal( nrhs, 1._dp / d( 1_${ik}$ ), b, ldb )
              return
           end if
           if( iuplo==1_${ik}$ ) then
              ! solve a * x = b using the factorization a = u**h *d*u,
              ! overwriting each right hand side vector with its solution.
              if( nrhs<=2_${ik}$ ) then
                 j = 1_${ik}$
                 10 continue
                 ! solve u**h * x = b.
                 do i = 2, n
                    b( i, j ) = b( i, j ) - b( i-1, j )*conjg( e( i-1 ) )
                 end do
                 ! solve d * u * x = b.
                 do i = 1, n
                    b( i, j ) = b( i, j ) / d( i )
                 end do
                 do i = n - 1, 1, -1
                    b( i, j ) = b( i, j ) - b( i+1, j )*e( i )
                 end do
                 if( j<nrhs ) then
                    j = j + 1_${ik}$
                    go to 10
                 end if
              else
                 do j = 1, nrhs
                    ! solve u**h * x = b.
                    do i = 2, n
                       b( i, j ) = b( i, j ) - b( i-1, j )*conjg( e( i-1 ) )
                    end do
                    ! solve d * u * x = b.
                    b( n, j ) = b( n, j ) / d( n )
                    do i = n - 1, 1, -1
                       b( i, j ) = b( i, j ) / d( i ) - b( i+1, j )*e( i )
                    end do
                 end do
              end if
           else
              ! solve a * x = b using the factorization a = l*d*l**h,
              ! overwriting each right hand side vector with its solution.
              if( nrhs<=2_${ik}$ ) then
                 j = 1_${ik}$
                 80 continue
                 ! solve l * x = b.
                 do i = 2, n
                    b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
                 end do
                 ! solve d * l**h * x = b.
                 do i = 1, n
                    b( i, j ) = b( i, j ) / d( i )
                 end do
                 do i = n - 1, 1, -1
                    b( i, j ) = b( i, j ) - b( i+1, j )*conjg( e( i ) )
                 end do
                 if( j<nrhs ) then
                    j = j + 1_${ik}$
                    go to 80
                 end if
              else
                 do j = 1, nrhs
                    ! solve l * x = b.
                    do i = 2, n
                       b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
                    end do
                    ! solve d * l**h * x = b.
                    b( n, j ) = b( n, j ) / d( n )
                    do i = n - 1, 1, -1
                       b( i, j ) = b( i, j ) / d( i ) -b( i+1, j )*conjg( e( i ) )
                    end do
                 end do
              end if
           end if
           return
     end subroutine stdlib${ii}$_zptts2

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ptts2( iuplo, n, nrhs, d, e, b, ldb )
     !! ZPTTS2: solves a tridiagonal system of the form
     !! A * X = B
     !! using the factorization A = U**H *D*U or A = L*D*L**H computed by ZPTTRF.
     !! D is a diagonal matrix specified in the vector D, U (or L) is a unit
     !! bidiagonal matrix whose superdiagonal (subdiagonal) is specified in
     !! the vector E, and X and B are N by NRHS matrices.
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(in) :: iuplo, ldb, n, nrhs
           ! Array Arguments 
           real(${ck}$), intent(in) :: d(*)
           complex(${ck}$), intent(inout) :: b(ldb,*)
           complex(${ck}$), intent(in) :: e(*)
        ! =====================================================================
           ! Local Scalars 
           integer(${ik}$) :: i, j
           ! Intrinsic Functions 
           ! Executable Statements 
           ! quick return if possible
           if( n<=1_${ik}$ ) then
              if( n==1_${ik}$ )call stdlib${ii}$_${ci}$dscal( nrhs, 1._${ck}$ / d( 1_${ik}$ ), b, ldb )
              return
           end if
           if( iuplo==1_${ik}$ ) then
              ! solve a * x = b using the factorization a = u**h *d*u,
              ! overwriting each right hand side vector with its solution.
              if( nrhs<=2_${ik}$ ) then
                 j = 1_${ik}$
                 10 continue
                 ! solve u**h * x = b.
                 do i = 2, n
                    b( i, j ) = b( i, j ) - b( i-1, j )*conjg( e( i-1 ) )
                 end do
                 ! solve d * u * x = b.
                 do i = 1, n
                    b( i, j ) = b( i, j ) / d( i )
                 end do
                 do i = n - 1, 1, -1
                    b( i, j ) = b( i, j ) - b( i+1, j )*e( i )
                 end do
                 if( j<nrhs ) then
                    j = j + 1_${ik}$
                    go to 10
                 end if
              else
                 do j = 1, nrhs
                    ! solve u**h * x = b.
                    do i = 2, n
                       b( i, j ) = b( i, j ) - b( i-1, j )*conjg( e( i-1 ) )
                    end do
                    ! solve d * u * x = b.
                    b( n, j ) = b( n, j ) / d( n )
                    do i = n - 1, 1, -1
                       b( i, j ) = b( i, j ) / d( i ) - b( i+1, j )*e( i )
                    end do
                 end do
              end if
           else
              ! solve a * x = b using the factorization a = l*d*l**h,
              ! overwriting each right hand side vector with its solution.
              if( nrhs<=2_${ik}$ ) then
                 j = 1_${ik}$
                 80 continue
                 ! solve l * x = b.
                 do i = 2, n
                    b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
                 end do
                 ! solve d * l**h * x = b.
                 do i = 1, n
                    b( i, j ) = b( i, j ) / d( i )
                 end do
                 do i = n - 1, 1, -1
                    b( i, j ) = b( i, j ) - b( i+1, j )*conjg( e( i ) )
                 end do
                 if( j<nrhs ) then
                    j = j + 1_${ik}$
                    go to 80
                 end if
              else
                 do j = 1, nrhs
                    ! solve l * x = b.
                    do i = 2, n
                       b( i, j ) = b( i, j ) - b( i-1, j )*e( i-1 )
                    end do
                    ! solve d * l**h * x = b.
                    b( n, j ) = b( n, j ) / d( n )
                    do i = n - 1, 1, -1
                       b( i, j ) = b( i, j ) / d( i ) -b( i+1, j )*conjg( e( i ) )
                    end do
                 end do
              end if
           end if
           return
     end subroutine stdlib${ii}$_${ci}$ptts2

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_sptrfs( n, nrhs, d, e, df, ef, b, ldb, x, ldx, ferr,berr, work, info )
     !! SPTRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and tridiagonal, and provides error bounds and backward error
     !! estimates for the solution.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(sp), intent(in) :: b(ldb,*), d(*), df(*), e(*), ef(*)
           real(sp), intent(out) :: berr(*), ferr(*), work(*)
           real(sp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: count, i, ix, j, nz
           real(sp) :: bi, cx, dx, eps, ex, lstres, s, safe1, safe2, safmin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'SPTRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = 4_${ik}$
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_90: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x.  also compute
              ! abs(a)*abs(x) + abs(b) for use in the backward error bound.
              if( n==1_${ik}$ ) then
                 bi = b( 1_${ik}$, j )
                 dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                 work( n+1 ) = bi - dx
                 work( 1_${ik}$ ) = abs( bi ) + abs( dx )
              else
                 bi = b( 1_${ik}$, j )
                 dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                 ex = e( 1_${ik}$ )*x( 2_${ik}$, j )
                 work( n+1 ) = bi - dx - ex
                 work( 1_${ik}$ ) = abs( bi ) + abs( dx ) + abs( ex )
                 do i = 2, n - 1
                    bi = b( i, j )
                    cx = e( i-1 )*x( i-1, j )
                    dx = d( i )*x( i, j )
                    ex = e( i )*x( i+1, j )
                    work( n+i ) = bi - cx - dx - ex
                    work( i ) = abs( bi ) + abs( cx ) + abs( dx ) + abs( ex )
                 end do
                 bi = b( n, j )
                 cx = e( n-1 )*x( n-1, j )
                 dx = d( n )*x( n, j )
                 work( n+n ) = bi - cx - dx
                 work( n ) = abs( bi ) + abs( cx ) + abs( dx )
              end if
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_spttrs( n, 1_${ik}$, df, ef, work( n+1 ), n, info )
                 call stdlib${ii}$_saxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ )
              ferr( j ) = work( ix )
              ! estimate the norm of inv(a).
              ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
                 ! m(i,j) =  abs(a(i,j)), i = j,
                 ! m(i,j) = -abs(a(i,j)), i .ne. j,
              ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**t.
              ! solve m(l) * x = e.
              work( 1_${ik}$ ) = one
              do i = 2, n
                 work( i ) = one + work( i-1 )*abs( ef( i-1 ) )
              end do
              ! solve d * m(l)**t * x = b.
              work( n ) = work( n ) / df( n )
              do i = n - 1, 1, -1
                 work( i ) = work( i ) / df( i ) + work( i+1 )*abs( ef( i ) )
              end do
              ! compute norm(inv(a)) = max(x(i)), 1<=i<=n.
              ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ )
              ferr( j ) = ferr( j )*abs( work( ix ) )
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_90
           return
     end subroutine stdlib${ii}$_sptrfs

     pure module subroutine stdlib${ii}$_dptrfs( n, nrhs, d, e, df, ef, b, ldb, x, ldx, ferr,berr, work, info )
     !! DPTRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and tridiagonal, and provides error bounds and backward error
     !! estimates for the solution.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(dp), intent(in) :: b(ldb,*), d(*), df(*), e(*), ef(*)
           real(dp), intent(out) :: berr(*), ferr(*), work(*)
           real(dp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: count, i, ix, j, nz
           real(dp) :: bi, cx, dx, eps, ex, lstres, s, safe1, safe2, safmin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPTRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = 4_${ik}$
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_90: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x.  also compute
              ! abs(a)*abs(x) + abs(b) for use in the backward error bound.
              if( n==1_${ik}$ ) then
                 bi = b( 1_${ik}$, j )
                 dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                 work( n+1 ) = bi - dx
                 work( 1_${ik}$ ) = abs( bi ) + abs( dx )
              else
                 bi = b( 1_${ik}$, j )
                 dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                 ex = e( 1_${ik}$ )*x( 2_${ik}$, j )
                 work( n+1 ) = bi - dx - ex
                 work( 1_${ik}$ ) = abs( bi ) + abs( dx ) + abs( ex )
                 do i = 2, n - 1
                    bi = b( i, j )
                    cx = e( i-1 )*x( i-1, j )
                    dx = d( i )*x( i, j )
                    ex = e( i )*x( i+1, j )
                    work( n+i ) = bi - cx - dx - ex
                    work( i ) = abs( bi ) + abs( cx ) + abs( dx ) + abs( ex )
                 end do
                 bi = b( n, j )
                 cx = e( n-1 )*x( n-1, j )
                 dx = d( n )*x( n, j )
                 work( n+n ) = bi - cx - dx
                 work( n ) = abs( bi ) + abs( cx ) + abs( dx )
              end if
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_dpttrs( n, 1_${ik}$, df, ef, work( n+1 ), n, info )
                 call stdlib${ii}$_daxpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ )
              ferr( j ) = work( ix )
              ! estimate the norm of inv(a).
              ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
                 ! m(i,j) =  abs(a(i,j)), i = j,
                 ! m(i,j) = -abs(a(i,j)), i .ne. j,
              ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**t.
              ! solve m(l) * x = e.
              work( 1_${ik}$ ) = one
              do i = 2, n
                 work( i ) = one + work( i-1 )*abs( ef( i-1 ) )
              end do
              ! solve d * m(l)**t * x = b.
              work( n ) = work( n ) / df( n )
              do i = n - 1, 1, -1
                 work( i ) = work( i ) / df( i ) + work( i+1 )*abs( ef( i ) )
              end do
              ! compute norm(inv(a)) = max(x(i)), 1<=i<=n.
              ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ )
              ferr( j ) = ferr( j )*abs( work( ix ) )
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_90
           return
     end subroutine stdlib${ii}$_dptrfs

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$ptrfs( n, nrhs, d, e, df, ef, b, ldb, x, ldx, ferr,berr, work, info )
     !! DPTRFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is symmetric positive definite
     !! and tridiagonal, and provides error bounds and backward error
     !! estimates for the solution.
               
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(${rk}$), intent(in) :: b(ldb,*), d(*), df(*), e(*), ef(*)
           real(${rk}$), intent(out) :: berr(*), ferr(*), work(*)
           real(${rk}$), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           integer(${ik}$) :: count, i, ix, j, nz
           real(${rk}$) :: bi, cx, dx, eps, ex, lstres, s, safe1, safe2, safmin
           ! Intrinsic Functions 
           ! Executable Statements 
           ! test the input parameters.
           info = 0_${ik}$
           if( n<0_${ik}$ ) then
              info = -1_${ik}$
           else if( nrhs<0_${ik}$ ) then
              info = -2_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -8_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -10_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'DPTRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = 4_${ik}$
           eps = stdlib${ii}$_${ri}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_90: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x.  also compute
              ! abs(a)*abs(x) + abs(b) for use in the backward error bound.
              if( n==1_${ik}$ ) then
                 bi = b( 1_${ik}$, j )
                 dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                 work( n+1 ) = bi - dx
                 work( 1_${ik}$ ) = abs( bi ) + abs( dx )
              else
                 bi = b( 1_${ik}$, j )
                 dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                 ex = e( 1_${ik}$ )*x( 2_${ik}$, j )
                 work( n+1 ) = bi - dx - ex
                 work( 1_${ik}$ ) = abs( bi ) + abs( dx ) + abs( ex )
                 do i = 2, n - 1
                    bi = b( i, j )
                    cx = e( i-1 )*x( i-1, j )
                    dx = d( i )*x( i, j )
                    ex = e( i )*x( i+1, j )
                    work( n+i ) = bi - cx - dx - ex
                    work( i ) = abs( bi ) + abs( cx ) + abs( dx ) + abs( ex )
                 end do
                 bi = b( n, j )
                 cx = e( n-1 )*x( n-1, j )
                 dx = d( n )*x( n, j )
                 work( n+n ) = bi - cx - dx
                 work( n ) = abs( bi ) + abs( cx ) + abs( dx )
              end if
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              s = zero
              do i = 1, n
                 if( work( i )>safe2 ) then
                    s = max( s, abs( work( n+i ) ) / work( i ) )
                 else
                    s = max( s, ( abs( work( n+i ) )+safe1 ) /( work( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ri}$pttrs( n, 1_${ik}$, df, ef, work( n+1 ), n, info )
                 call stdlib${ii}$_${ri}$axpy( n, one, work( n+1 ), 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              do i = 1, n
                 if( work( i )>safe2 ) then
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i )
                 else
                    work( i ) = abs( work( n+i ) ) + nz*eps*work( i ) + safe1
                 end if
              end do
              ix = stdlib${ii}$_i${ri}$amax( n, work, 1_${ik}$ )
              ferr( j ) = work( ix )
              ! estimate the norm of inv(a).
              ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
                 ! m(i,j) =  abs(a(i,j)), i = j,
                 ! m(i,j) = -abs(a(i,j)), i .ne. j,
              ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**t.
              ! solve m(l) * x = e.
              work( 1_${ik}$ ) = one
              do i = 2, n
                 work( i ) = one + work( i-1 )*abs( ef( i-1 ) )
              end do
              ! solve d * m(l)**t * x = b.
              work( n ) = work( n ) / df( n )
              do i = n - 1, 1, -1
                 work( i ) = work( i ) / df( i ) + work( i+1 )*abs( ef( i ) )
              end do
              ! compute norm(inv(a)) = max(x(i)), 1<=i<=n.
              ix = stdlib${ii}$_i${ri}$amax( n, work, 1_${ik}$ )
              ferr( j ) = ferr( j )*abs( work( ix ) )
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_90
           return
     end subroutine stdlib${ii}$_${ri}$ptrfs

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_cptrfs( uplo, n, nrhs, d, e, df, ef, b, ldb, x, ldx,ferr, berr, work, &
     !! CPTRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and tridiagonal, and provides error bounds and backward error
     !! estimates for the solution.
               rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(sp), intent(out) :: berr(*), ferr(*), rwork(*)
           real(sp), intent(in) :: d(*), df(*)
           complex(sp), intent(in) :: b(ldb,*), e(*), ef(*)
           complex(sp), intent(out) :: work(*)
           complex(sp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ix, j, nz
           real(sp) :: eps, lstres, s, safe1, safe2, safmin
           complex(sp) :: bi, cx, dx, ex, zdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(sp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'CPTRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = 4_${ik}$
           eps = stdlib${ii}$_slamch( 'EPSILON' )
           safmin = stdlib${ii}$_slamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_100: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x.  also compute
              ! abs(a)*abs(x) + abs(b) for use in the backward error bound.
              if( upper ) then
                 if( n==1_${ik}$ ) then
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx )
                 else
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    ex = e( 1_${ik}$ )*x( 2_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx - ex
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx ) +cabs1( e( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) )
                              
                    do i = 2, n - 1
                       bi = b( i, j )
                       cx = conjg( e( i-1 ) )*x( i-1, j )
                       dx = d( i )*x( i, j )
                       ex = e( i )*x( i+1, j )
                       work( i ) = bi - cx - dx - ex
                       rwork( i ) = cabs1( bi ) +cabs1( e( i-1 ) )*cabs1( x( i-1, j ) ) +cabs1( &
                                 dx ) + cabs1( e( i ) )*cabs1( x( i+1, j ) )
                    end do
                    bi = b( n, j )
                    cx = conjg( e( n-1 ) )*x( n-1, j )
                    dx = d( n )*x( n, j )
                    work( n ) = bi - cx - dx
                    rwork( n ) = cabs1( bi ) + cabs1( e( n-1 ) )*cabs1( x( n-1, j ) ) + cabs1( dx &
                              )
                 end if
              else
                 if( n==1_${ik}$ ) then
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx )
                 else
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    ex = conjg( e( 1_${ik}$ ) )*x( 2_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx - ex
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx ) +cabs1( e( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) )
                              
                    do i = 2, n - 1
                       bi = b( i, j )
                       cx = e( i-1 )*x( i-1, j )
                       dx = d( i )*x( i, j )
                       ex = conjg( e( i ) )*x( i+1, j )
                       work( i ) = bi - cx - dx - ex
                       rwork( i ) = cabs1( bi ) +cabs1( e( i-1 ) )*cabs1( x( i-1, j ) ) +cabs1( &
                                 dx ) + cabs1( e( i ) )*cabs1( x( i+1, j ) )
                    end do
                    bi = b( n, j )
                    cx = e( n-1 )*x( n-1, j )
                    dx = d( n )*x( n, j )
                    work( n ) = bi - cx - dx
                    rwork( n ) = cabs1( bi ) + cabs1( e( n-1 ) )*cabs1( x( n-1, j ) ) + cabs1( dx &
                              )
                 end if
              end if
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_cpttrs( uplo, n, 1_${ik}$, df, ef, work, n, info )
                 call stdlib${ii}$_caxpy( n, cmplx( one,KIND=sp), work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              ix = stdlib${ii}$_isamax( n, rwork, 1_${ik}$ )
              ferr( j ) = rwork( ix )
              ! estimate the norm of inv(a).
              ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
                 ! m(i,j) =  abs(a(i,j)), i = j,
                 ! m(i,j) = -abs(a(i,j)), i .ne. j,
              ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**h.
              ! solve m(l) * x = e.
              rwork( 1_${ik}$ ) = one
              do i = 2, n
                 rwork( i ) = one + rwork( i-1 )*abs( ef( i-1 ) )
              end do
              ! solve d * m(l)**h * x = b.
              rwork( n ) = rwork( n ) / df( n )
              do i = n - 1, 1, -1
                 rwork( i ) = rwork( i ) / df( i ) +rwork( i+1 )*abs( ef( i ) )
              end do
              ! compute norm(inv(a)) = max(x(i)), 1<=i<=n.
              ix = stdlib${ii}$_isamax( n, rwork, 1_${ik}$ )
              ferr( j ) = ferr( j )*abs( rwork( ix ) )
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_100
           return
     end subroutine stdlib${ii}$_cptrfs

     pure module subroutine stdlib${ii}$_zptrfs( uplo, n, nrhs, d, e, df, ef, b, ldb, x, ldx,ferr, berr, work, &
     !! ZPTRFS improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and tridiagonal, and provides error bounds and backward error
     !! estimates for the solution.
               rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(dp), intent(out) :: berr(*), ferr(*), rwork(*)
           real(dp), intent(in) :: d(*), df(*)
           complex(dp), intent(in) :: b(ldb,*), e(*), ef(*)
           complex(dp), intent(out) :: work(*)
           complex(dp), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ix, j, nz
           real(dp) :: eps, lstres, s, safe1, safe2, safmin
           complex(dp) :: bi, cx, dx, ex, zdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(dp) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPTRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = 4_${ik}$
           eps = stdlib${ii}$_dlamch( 'EPSILON' )
           safmin = stdlib${ii}$_dlamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_100: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x.  also compute
              ! abs(a)*abs(x) + abs(b) for use in the backward error bound.
              if( upper ) then
                 if( n==1_${ik}$ ) then
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx )
                 else
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    ex = e( 1_${ik}$ )*x( 2_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx - ex
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx ) +cabs1( e( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) )
                              
                    do i = 2, n - 1
                       bi = b( i, j )
                       cx = conjg( e( i-1 ) )*x( i-1, j )
                       dx = d( i )*x( i, j )
                       ex = e( i )*x( i+1, j )
                       work( i ) = bi - cx - dx - ex
                       rwork( i ) = cabs1( bi ) +cabs1( e( i-1 ) )*cabs1( x( i-1, j ) ) +cabs1( &
                                 dx ) + cabs1( e( i ) )*cabs1( x( i+1, j ) )
                    end do
                    bi = b( n, j )
                    cx = conjg( e( n-1 ) )*x( n-1, j )
                    dx = d( n )*x( n, j )
                    work( n ) = bi - cx - dx
                    rwork( n ) = cabs1( bi ) + cabs1( e( n-1 ) )*cabs1( x( n-1, j ) ) + cabs1( dx &
                              )
                 end if
              else
                 if( n==1_${ik}$ ) then
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx )
                 else
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    ex = conjg( e( 1_${ik}$ ) )*x( 2_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx - ex
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx ) +cabs1( e( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) )
                              
                    do i = 2, n - 1
                       bi = b( i, j )
                       cx = e( i-1 )*x( i-1, j )
                       dx = d( i )*x( i, j )
                       ex = conjg( e( i ) )*x( i+1, j )
                       work( i ) = bi - cx - dx - ex
                       rwork( i ) = cabs1( bi ) +cabs1( e( i-1 ) )*cabs1( x( i-1, j ) ) +cabs1( &
                                 dx ) + cabs1( e( i ) )*cabs1( x( i+1, j ) )
                    end do
                    bi = b( n, j )
                    cx = e( n-1 )*x( n-1, j )
                    dx = d( n )*x( n, j )
                    work( n ) = bi - cx - dx
                    rwork( n ) = cabs1( bi ) + cabs1( e( n-1 ) )*cabs1( x( n-1, j ) ) + cabs1( dx &
                              )
                 end if
              end if
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_zpttrs( uplo, n, 1_${ik}$, df, ef, work, n, info )
                 call stdlib${ii}$_zaxpy( n, cmplx( one,KIND=dp), work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              ix = stdlib${ii}$_idamax( n, rwork, 1_${ik}$ )
              ferr( j ) = rwork( ix )
              ! estimate the norm of inv(a).
              ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
                 ! m(i,j) =  abs(a(i,j)), i = j,
                 ! m(i,j) = -abs(a(i,j)), i .ne. j,
              ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**h.
              ! solve m(l) * x = e.
              rwork( 1_${ik}$ ) = one
              do i = 2, n
                 rwork( i ) = one + rwork( i-1 )*abs( ef( i-1 ) )
              end do
              ! solve d * m(l)**h * x = b.
              rwork( n ) = rwork( n ) / df( n )
              do i = n - 1, 1, -1
                 rwork( i ) = rwork( i ) / df( i ) +rwork( i+1 )*abs( ef( i ) )
              end do
              ! compute norm(inv(a)) = max(x(i)), 1<=i<=n.
              ix = stdlib${ii}$_idamax( n, rwork, 1_${ik}$ )
              ferr( j ) = ferr( j )*abs( rwork( ix ) )
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_100
           return
     end subroutine stdlib${ii}$_zptrfs

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$ptrfs( uplo, n, nrhs, d, e, df, ef, b, ldb, x, ldx,ferr, berr, work, &
     !! ZPTRFS: improves the computed solution to a system of linear
     !! equations when the coefficient matrix is Hermitian positive definite
     !! and tridiagonal, and provides error bounds and backward error
     !! estimates for the solution.
               rwork, info )
        ! -- lapack computational routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(in) :: uplo
           integer(${ik}$), intent(out) :: info
           integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs
           ! Array Arguments 
           real(${ck}$), intent(out) :: berr(*), ferr(*), rwork(*)
           real(${ck}$), intent(in) :: d(*), df(*)
           complex(${ck}$), intent(in) :: b(ldb,*), e(*), ef(*)
           complex(${ck}$), intent(out) :: work(*)
           complex(${ck}$), intent(inout) :: x(ldx,*)
        ! =====================================================================
           ! Parameters 
           integer(${ik}$), parameter :: itmax = 5_${ik}$
           
           
           
           
           
           ! Local Scalars 
           logical(lk) :: upper
           integer(${ik}$) :: count, i, ix, j, nz
           real(${ck}$) :: eps, lstres, s, safe1, safe2, safmin
           complex(${ck}$) :: bi, cx, dx, ex, zdum
           ! Intrinsic Functions 
           ! Statement Functions 
           real(${ck}$) :: cabs1
           ! Statement Function Definitions 
           cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) )
           ! 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( nrhs<0_${ik}$ ) then
              info = -3_${ik}$
           else if( ldb<max( 1_${ik}$, n ) ) then
              info = -9_${ik}$
           else if( ldx<max( 1_${ik}$, n ) ) then
              info = -11_${ik}$
           end if
           if( info/=0_${ik}$ ) then
              call stdlib${ii}$_xerbla( 'ZPTRFS', -info )
              return
           end if
           ! quick return if possible
           if( n==0_${ik}$ .or. nrhs==0_${ik}$ ) then
              do j = 1, nrhs
                 ferr( j ) = zero
                 berr( j ) = zero
              end do
              return
           end if
           ! nz = maximum number of nonzero elements in each row of a, plus 1
           nz = 4_${ik}$
           eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'EPSILON' )
           safmin = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' )
           safe1 = nz*safmin
           safe2 = safe1 / eps
           ! do for each right hand side
           loop_100: do j = 1, nrhs
              count = 1_${ik}$
              lstres = three
              20 continue
              ! loop until stopping criterion is satisfied.
              ! compute residual r = b - a * x.  also compute
              ! abs(a)*abs(x) + abs(b) for use in the backward error bound.
              if( upper ) then
                 if( n==1_${ik}$ ) then
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx )
                 else
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    ex = e( 1_${ik}$ )*x( 2_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx - ex
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx ) +cabs1( e( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) )
                              
                    do i = 2, n - 1
                       bi = b( i, j )
                       cx = conjg( e( i-1 ) )*x( i-1, j )
                       dx = d( i )*x( i, j )
                       ex = e( i )*x( i+1, j )
                       work( i ) = bi - cx - dx - ex
                       rwork( i ) = cabs1( bi ) +cabs1( e( i-1 ) )*cabs1( x( i-1, j ) ) +cabs1( &
                                 dx ) + cabs1( e( i ) )*cabs1( x( i+1, j ) )
                    end do
                    bi = b( n, j )
                    cx = conjg( e( n-1 ) )*x( n-1, j )
                    dx = d( n )*x( n, j )
                    work( n ) = bi - cx - dx
                    rwork( n ) = cabs1( bi ) + cabs1( e( n-1 ) )*cabs1( x( n-1, j ) ) + cabs1( dx &
                              )
                 end if
              else
                 if( n==1_${ik}$ ) then
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx )
                 else
                    bi = b( 1_${ik}$, j )
                    dx = d( 1_${ik}$ )*x( 1_${ik}$, j )
                    ex = conjg( e( 1_${ik}$ ) )*x( 2_${ik}$, j )
                    work( 1_${ik}$ ) = bi - dx - ex
                    rwork( 1_${ik}$ ) = cabs1( bi ) + cabs1( dx ) +cabs1( e( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) )
                              
                    do i = 2, n - 1
                       bi = b( i, j )
                       cx = e( i-1 )*x( i-1, j )
                       dx = d( i )*x( i, j )
                       ex = conjg( e( i ) )*x( i+1, j )
                       work( i ) = bi - cx - dx - ex
                       rwork( i ) = cabs1( bi ) +cabs1( e( i-1 ) )*cabs1( x( i-1, j ) ) +cabs1( &
                                 dx ) + cabs1( e( i ) )*cabs1( x( i+1, j ) )
                    end do
                    bi = b( n, j )
                    cx = e( n-1 )*x( n-1, j )
                    dx = d( n )*x( n, j )
                    work( n ) = bi - cx - dx
                    rwork( n ) = cabs1( bi ) + cabs1( e( n-1 ) )*cabs1( x( n-1, j ) ) + cabs1( dx &
                              )
                 end if
              end if
              ! compute componentwise relative backward error from formula
              ! max(i) ( abs(r(i)) / ( abs(a)*abs(x) + abs(b) )(i) )
              ! where abs(z) is the componentwise absolute value of the matrix
              ! or vector z.  if the i-th component of the denominator is less
              ! than safe2, then safe1 is added to the i-th components of the
              ! numerator and denominator before dividing.
              s = zero
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    s = max( s, cabs1( work( i ) ) / rwork( i ) )
                 else
                    s = max( s, ( cabs1( work( i ) )+safe1 ) /( rwork( i )+safe1 ) )
                 end if
              end do
              berr( j ) = s
              ! test stopping criterion. continue iterating if
                 ! 1) the residual berr(j) is larger than machine epsilon, and
                 ! 2) berr(j) decreased by at least a factor of 2 during the
                    ! last iteration, and
                 ! 3) at most itmax iterations tried.
              if( berr( j )>eps .and. two*berr( j )<=lstres .and.count<=itmax ) then
                 ! update solution and try again.
                 call stdlib${ii}$_${ci}$pttrs( uplo, n, 1_${ik}$, df, ef, work, n, info )
                 call stdlib${ii}$_${ci}$axpy( n, cmplx( one,KIND=${ck}$), work, 1_${ik}$, x( 1_${ik}$, j ), 1_${ik}$ )
                 lstres = berr( j )
                 count = count + 1_${ik}$
                 go to 20
              end if
              ! bound error from formula
              ! norm(x - xtrue) / norm(x) .le. ferr =
              ! norm( abs(inv(a))*
                 ! ( abs(r) + nz*eps*( abs(a)*abs(x)+abs(b) ))) / norm(x)
              ! where
                ! norm(z) is the magnitude of the largest component of z
                ! inv(a) is the inverse of a
                ! abs(z) is the componentwise absolute value of the matrix or
                   ! vector z
                ! nz is the maximum number of nonzeros in any row of a, plus 1
                ! eps is machine epsilon
              ! the i-th component of abs(r)+nz*eps*(abs(a)*abs(x)+abs(b))
              ! is incremented by safe1 if the i-th component of
              ! abs(a)*abs(x) + abs(b) is less than safe2.
              do i = 1, n
                 if( rwork( i )>safe2 ) then
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i )
                 else
                    rwork( i ) = cabs1( work( i ) ) + nz*eps*rwork( i ) +safe1
                 end if
              end do
              ix = stdlib${ii}$_i${c2ri(ci)}$amax( n, rwork, 1_${ik}$ )
              ferr( j ) = rwork( ix )
              ! estimate the norm of inv(a).
              ! solve m(a) * x = e, where m(a) = (m(i,j)) is given by
                 ! m(i,j) =  abs(a(i,j)), i = j,
                 ! m(i,j) = -abs(a(i,j)), i .ne. j,
              ! and e = [ 1, 1, ..., 1 ]**t.  note m(a) = m(l)*d*m(l)**h.
              ! solve m(l) * x = e.
              rwork( 1_${ik}$ ) = one
              do i = 2, n
                 rwork( i ) = one + rwork( i-1 )*abs( ef( i-1 ) )
              end do
              ! solve d * m(l)**h * x = b.
              rwork( n ) = rwork( n ) / df( n )
              do i = n - 1, 1, -1
                 rwork( i ) = rwork( i ) / df( i ) +rwork( i+1 )*abs( ef( i ) )
              end do
              ! compute norm(inv(a)) = max(x(i)), 1<=i<=n.
              ix = stdlib${ii}$_i${c2ri(ci)}$amax( n, rwork, 1_${ik}$ )
              ferr( j ) = ferr( j )*abs( rwork( ix ) )
              ! normalize error.
              lstres = zero
              do i = 1, n
                 lstres = max( lstres, abs( x( i, j ) ) )
              end do
              if( lstres/=zero )ferr( j ) = ferr( j ) / lstres
           end do loop_100
           return
     end subroutine stdlib${ii}$_${ci}$ptrfs

#:endif
#:endfor



     pure module subroutine stdlib${ii}$_slaqsp( uplo, n, ap, s, scond, amax, equed )
     !! SLAQSP equilibrates a symmetric matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(sp), intent(in) :: amax, scond
           ! Array Arguments 
           real(sp), intent(inout) :: ap(*)
           real(sp), intent(in) :: s(*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: thresh = 0.1e+0_sp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(sp) :: cj, large, small
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_slamch( 'SAFE MINIMUM' ) / stdlib${ii}$_slamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = j, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_slaqsp

     pure module subroutine stdlib${ii}$_dlaqsp( uplo, n, ap, s, scond, amax, equed )
     !! DLAQSP equilibrates a symmetric matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(dp), intent(in) :: amax, scond
           ! Array Arguments 
           real(dp), intent(inout) :: ap(*)
           real(dp), intent(in) :: s(*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: thresh = 0.1e+0_dp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(dp) :: cj, large, small
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_dlamch( 'SAFE MINIMUM' ) / stdlib${ii}$_dlamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = j, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_dlaqsp

#:for rk,rt,ri in REAL_KINDS_TYPES
#:if not rk in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ri}$laqsp( uplo, n, ap, s, scond, amax, equed )
     !! DLAQSP: equilibrates a symmetric matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(${rk}$), intent(in) :: amax, scond
           ! Array Arguments 
           real(${rk}$), intent(inout) :: ap(*)
           real(${rk}$), intent(in) :: s(*)
        ! =====================================================================
           ! Parameters 
           real(${rk}$), parameter :: thresh = 0.1e+0_${rk}$
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(${rk}$) :: cj, large, small
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_${ri}$lamch( 'SAFE MINIMUM' ) / stdlib${ii}$_${ri}$lamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = j, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_${ri}$laqsp

#:endif
#:endfor

     pure module subroutine stdlib${ii}$_claqsp( uplo, n, ap, s, scond, amax, equed )
     !! CLAQSP equilibrates a symmetric matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(sp), intent(in) :: amax, scond
           ! Array Arguments 
           real(sp), intent(in) :: s(*)
           complex(sp), intent(inout) :: ap(*)
        ! =====================================================================
           ! Parameters 
           real(sp), parameter :: thresh = 0.1e+0_sp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(sp) :: cj, large, small
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_slamch( 'SAFE MINIMUM' ) / stdlib${ii}$_slamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = j, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_claqsp

     pure module subroutine stdlib${ii}$_zlaqsp( uplo, n, ap, s, scond, amax, equed )
     !! ZLAQSP equilibrates a symmetric matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(dp), intent(in) :: amax, scond
           ! Array Arguments 
           real(dp), intent(in) :: s(*)
           complex(dp), intent(inout) :: ap(*)
        ! =====================================================================
           ! Parameters 
           real(dp), parameter :: thresh = 0.1e+0_dp
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(dp) :: cj, large, small
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_dlamch( 'SAFE MINIMUM' ) / stdlib${ii}$_dlamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = j, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_zlaqsp

#:for ck,ct,ci in CMPLX_KINDS_TYPES
#:if not ck in ["sp","dp"]
     pure module subroutine stdlib${ii}$_${ci}$laqsp( uplo, n, ap, s, scond, amax, equed )
     !! ZLAQSP: equilibrates a symmetric matrix A using the scaling factors
     !! in the vector S.
        ! -- lapack auxiliary routine --
        ! -- lapack is a software package provided by univ. of tennessee,    --
        ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..--
           use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone
           ! Scalar Arguments 
           character, intent(out) :: equed
           character, intent(in) :: uplo
           integer(${ik}$), intent(in) :: n
           real(${ck}$), intent(in) :: amax, scond
           ! Array Arguments 
           real(${ck}$), intent(in) :: s(*)
           complex(${ck}$), intent(inout) :: ap(*)
        ! =====================================================================
           ! Parameters 
           real(${ck}$), parameter :: thresh = 0.1e+0_${ck}$
           
           ! Local Scalars 
           integer(${ik}$) :: i, j, jc
           real(${ck}$) :: cj, large, small
           ! Executable Statements 
           ! quick return if possible
           if( n<=0_${ik}$ ) then
              equed = 'N'
              return
           end if
           ! initialize large and small.
           small = stdlib${ii}$_${c2ri(ci)}$lamch( 'SAFE MINIMUM' ) / stdlib${ii}$_${c2ri(ci)}$lamch( 'PRECISION' )
           large = one / small
           if( scond>=thresh .and. amax>=small .and. amax<=large ) then
              ! no equilibration
              equed = 'N'
           else
              ! replace a by diag(s) * a * diag(s).
              if( stdlib_lsame( uplo, 'U' ) ) then
                 ! upper triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = 1, j
                       ap( jc+i-1 ) = cj*s( i )*ap( jc+i-1 )
                    end do
                    jc = jc + j
                 end do
              else
                 ! lower triangle of a is stored.
                 jc = 1_${ik}$
                 do j = 1, n
                    cj = s( j )
                    do i = j, n
                       ap( jc+i-j ) = cj*s( i )*ap( jc+i-j )
                    end do
                    jc = jc + n - j + 1_${ik}$
                 end do
              end if
              equed = 'Y'
           end if
           return
     end subroutine stdlib${ii}$_${ci}$laqsp

#:endif
#:endfor


#:endfor
end submodule stdlib_lapack_solve_chol_comp