#:include "common.fypp" submodule(stdlib_lapack_solve) stdlib_lapack_solve_lu_comp implicit none contains #:for ik,it,ii in LINALG_INT_KINDS_TYPES pure module subroutine stdlib${ii}$_sgecon( norm, n, a, lda, anorm, rcond, work, iwork,info ) !! SGECON estimates the reciprocal of the condition number of a general !! real matrix A, in either the 1-norm or the infinity-norm, using !! the LU factorization computed by SGETRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * 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) :: norm 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) :: onenrm character :: normin integer(${ik}$) :: ix, kase, kase1 real(sp) :: ainvnm, scale, sl, smlnum, su ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) 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( 'SGECON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if 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==kase1 ) then ! multiply by inv(l). call stdlib${ii}$_slatrs( 'LOWER', 'NO TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & work( 2_${ik}$*n+1 ), info ) ! multiply by inv(u). call stdlib${ii}$_slatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, & su, work( 3_${ik}$*n+1 ), info ) else ! multiply by inv(u**t). call stdlib${ii}$_slatrs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, su,& work( 3_${ik}$*n+1 ), info ) ! multiply by inv(l**t). call stdlib${ii}$_slatrs( 'LOWER', 'TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & work( 2_${ik}$*n+1 ), info ) end if ! divide x by 1/(sl*su) if doing so will not cause overflow. scale = sl*su normin = 'Y' 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}$_sgecon pure module subroutine stdlib${ii}$_dgecon( norm, n, a, lda, anorm, rcond, work, iwork,info ) !! DGECON estimates the reciprocal of the condition number of a general !! real matrix A, in either the 1-norm or the infinity-norm, using !! the LU factorization computed by DGETRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * 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) :: norm 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) :: onenrm character :: normin integer(${ik}$) :: ix, kase, kase1 real(dp) :: ainvnm, scale, sl, smlnum, su ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) 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( 'DGECON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if 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==kase1 ) then ! multiply by inv(l). call stdlib${ii}$_dlatrs( 'LOWER', 'NO TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & work( 2_${ik}$*n+1 ), info ) ! multiply by inv(u). call stdlib${ii}$_dlatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, & su, work( 3_${ik}$*n+1 ), info ) else ! multiply by inv(u**t). call stdlib${ii}$_dlatrs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, su,& work( 3_${ik}$*n+1 ), info ) ! multiply by inv(l**t). call stdlib${ii}$_dlatrs( 'LOWER', 'TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & work( 2_${ik}$*n+1 ), info ) end if ! divide x by 1/(sl*su) if doing so will not cause overflow. scale = sl*su normin = 'Y' 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}$_dgecon #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gecon( norm, n, a, lda, anorm, rcond, work, iwork,info ) !! DGECON: estimates the reciprocal of the condition number of a general !! real matrix A, in either the 1-norm or the infinity-norm, using !! the LU factorization computed by DGETRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * 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) :: norm 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) :: onenrm character :: normin integer(${ik}$) :: ix, kase, kase1 real(${rk}$) :: ainvnm, scale, sl, smlnum, su ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) 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( 'DGECON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if 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==kase1 ) then ! multiply by inv(l). call stdlib${ii}$_${ri}$latrs( 'LOWER', 'NO TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & work( 2_${ik}$*n+1 ), info ) ! multiply by inv(u). call stdlib${ii}$_${ri}$latrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, & su, work( 3_${ik}$*n+1 ), info ) else ! multiply by inv(u**t). call stdlib${ii}$_${ri}$latrs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n, a,lda, work, su,& work( 3_${ik}$*n+1 ), info ) ! multiply by inv(l**t). call stdlib${ii}$_${ri}$latrs( 'LOWER', 'TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & work( 2_${ik}$*n+1 ), info ) end if ! divide x by 1/(sl*su) if doing so will not cause overflow. scale = sl*su normin = 'Y' 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}$gecon #:endif #:endfor pure module subroutine stdlib${ii}$_cgecon( norm, n, a, lda, anorm, rcond, work, rwork,info ) !! CGECON estimates the reciprocal of the condition number of a general !! complex matrix A, in either the 1-norm or the infinity-norm, using !! the LU factorization computed by CGETRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * 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) :: norm 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) :: onenrm character :: normin integer(${ik}$) :: ix, kase, kase1 real(sp) :: ainvnm, scale, sl, smlnum, su 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}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) 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( 'CGECON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 10 continue call stdlib${ii}$_clacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(l). call stdlib${ii}$_clatrs( 'LOWER', 'NO TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & rwork, info ) ! multiply by inv(u). call stdlib${ii}$_clatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, & su, rwork( n+1 ), info ) else ! multiply by inv(u**h). call stdlib${ii}$_clatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,& work, su, rwork( n+1 ),info ) ! multiply by inv(l**h). call stdlib${ii}$_clatrs( 'LOWER', 'CONJUGATE TRANSPOSE', 'UNIT', normin,n, a, lda, & work, sl, rwork, info ) end if ! divide x by 1/(sl*su) if doing so will not cause overflow. scale = sl*su normin = 'Y' 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}$_cgecon pure module subroutine stdlib${ii}$_zgecon( norm, n, a, lda, anorm, rcond, work, rwork,info ) !! ZGECON estimates the reciprocal of the condition number of a general !! complex matrix A, in either the 1-norm or the infinity-norm, using !! the LU factorization computed by ZGETRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * 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) :: norm 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) :: onenrm character :: normin integer(${ik}$) :: ix, kase, kase1 real(dp) :: ainvnm, scale, sl, smlnum, su 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}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) 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( 'ZGECON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 10 continue call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(l). call stdlib${ii}$_zlatrs( 'LOWER', 'NO TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & rwork, info ) ! multiply by inv(u). call stdlib${ii}$_zlatrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, & su, rwork( n+1 ), info ) else ! multiply by inv(u**h). call stdlib${ii}$_zlatrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,& work, su, rwork( n+1 ),info ) ! multiply by inv(l**h). call stdlib${ii}$_zlatrs( 'LOWER', 'CONJUGATE TRANSPOSE', 'UNIT', normin,n, a, lda, & work, sl, rwork, info ) end if ! divide x by 1/(sl*su) if doing so will not cause overflow. scale = sl*su normin = 'Y' 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}$_zgecon #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gecon( norm, n, a, lda, anorm, rcond, work, rwork,info ) !! ZGECON: estimates the reciprocal of the condition number of a general !! complex matrix A, in either the 1-norm or the infinity-norm, using !! the LU factorization computed by ZGETRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * 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) :: norm 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) :: onenrm character :: normin integer(${ik}$) :: ix, kase, kase1 real(${ck}$) :: ainvnm, scale, sl, smlnum, su 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}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) 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( 'ZGECON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 10 continue call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(l). call stdlib${ii}$_${ci}$latrs( 'LOWER', 'NO TRANSPOSE', 'UNIT', normin, n, a,lda, work, sl, & rwork, info ) ! multiply by inv(u). call stdlib${ii}$_${ci}$latrs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,a, lda, work, & su, rwork( n+1 ), info ) else ! multiply by inv(u**h). call stdlib${ii}$_${ci}$latrs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, a, lda,& work, su, rwork( n+1 ),info ) ! multiply by inv(l**h). call stdlib${ii}$_${ci}$latrs( 'LOWER', 'CONJUGATE TRANSPOSE', 'UNIT', normin,n, a, lda, & work, sl, rwork, info ) end if ! divide x by 1/(sl*su) if doing so will not cause overflow. scale = sl*su normin = 'Y' 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}$gecon #:endif #:endfor pure module subroutine stdlib${ii}$_sgetrf( m, n, a, lda, ipiv, info ) !! SGETRF computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 3 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, iinfo, j, jb, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGETRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGETRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) if( nb<=1_${ik}$ .or. nb>=min( m, n ) ) then ! use unblocked code. call stdlib${ii}$_sgetrf2( m, n, a, lda, ipiv, info ) else ! use blocked code. do j = 1, min( m, n ), nb jb = min( min( m, n )-j+1, nb ) ! factor diagonal and subdiagonal blocks and test for exact ! singularity. call stdlib${ii}$_sgetrf2( m-j+1, jb, a( j, j ), lda, ipiv( j ), iinfo ) ! adjust info and the pivot indices. if( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + j - 1_${ik}$ do i = j, min( m, j+jb-1 ) ipiv( i ) = j - 1_${ik}$ + ipiv( i ) end do ! apply interchanges to columns 1:j-1. call stdlib${ii}$_slaswp( j-1, a, lda, j, j+jb-1, ipiv, 1_${ik}$ ) if( j+jb<=n ) then ! apply interchanges to columns j+jb:n. call stdlib${ii}$_slaswp( n-j-jb+1, a( 1_${ik}$, j+jb ), lda, j, j+jb-1,ipiv, 1_${ik}$ ) ! compute block row of u. call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT', jb,n-j-jb+1, one, & a( j, j ), lda, a( j, j+jb ),lda ) if( j+jb<=m ) then ! update trailing submatrix. call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', m-j-jb+1,n-j-jb+1, jb, -& one, a( j+jb, j ), lda,a( j, j+jb ), lda, one, a( j+jb, j+jb ),lda ) end if end if end do end if return end subroutine stdlib${ii}$_sgetrf pure module subroutine stdlib${ii}$_dgetrf( m, n, a, lda, ipiv, info ) !! DGETRF computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 3 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, iinfo, j, jb, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGETRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) if( nb<=1_${ik}$ .or. nb>=min( m, n ) ) then ! use unblocked code. call stdlib${ii}$_dgetrf2( m, n, a, lda, ipiv, info ) else ! use blocked code. do j = 1, min( m, n ), nb jb = min( min( m, n )-j+1, nb ) ! factor diagonal and subdiagonal blocks and test for exact ! singularity. call stdlib${ii}$_dgetrf2( m-j+1, jb, a( j, j ), lda, ipiv( j ), iinfo ) ! adjust info and the pivot indices. if( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + j - 1_${ik}$ do i = j, min( m, j+jb-1 ) ipiv( i ) = j - 1_${ik}$ + ipiv( i ) end do ! apply interchanges to columns 1:j-1. call stdlib${ii}$_dlaswp( j-1, a, lda, j, j+jb-1, ipiv, 1_${ik}$ ) if( j+jb<=n ) then ! apply interchanges to columns j+jb:n. call stdlib${ii}$_dlaswp( n-j-jb+1, a( 1_${ik}$, j+jb ), lda, j, j+jb-1,ipiv, 1_${ik}$ ) ! compute block row of u. call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT', jb,n-j-jb+1, one, & a( j, j ), lda, a( j, j+jb ),lda ) if( j+jb<=m ) then ! update trailing submatrix. call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', m-j-jb+1,n-j-jb+1, jb, -& one, a( j+jb, j ), lda,a( j, j+jb ), lda, one, a( j+jb, j+jb ),lda ) end if end if end do end if return end subroutine stdlib${ii}$_dgetrf #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$getrf( m, n, a, lda, ipiv, info ) !! DGETRF: computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 3 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(${rk}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, iinfo, j, jb, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGETRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) if( nb<=1_${ik}$ .or. nb>=min( m, n ) ) then ! use unblocked code. call stdlib${ii}$_${ri}$getrf2( m, n, a, lda, ipiv, info ) else ! use blocked code. do j = 1, min( m, n ), nb jb = min( min( m, n )-j+1, nb ) ! factor diagonal and subdiagonal blocks and test for exact ! singularity. call stdlib${ii}$_${ri}$getrf2( m-j+1, jb, a( j, j ), lda, ipiv( j ), iinfo ) ! adjust info and the pivot indices. if( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + j - 1_${ik}$ do i = j, min( m, j+jb-1 ) ipiv( i ) = j - 1_${ik}$ + ipiv( i ) end do ! apply interchanges to columns 1:j-1. call stdlib${ii}$_${ri}$laswp( j-1, a, lda, j, j+jb-1, ipiv, 1_${ik}$ ) if( j+jb<=n ) then ! apply interchanges to columns j+jb:n. call stdlib${ii}$_${ri}$laswp( n-j-jb+1, a( 1_${ik}$, j+jb ), lda, j, j+jb-1,ipiv, 1_${ik}$ ) ! compute block row of u. call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT', jb,n-j-jb+1, one, & a( j, j ), lda, a( j, j+jb ),lda ) if( j+jb<=m ) then ! update trailing submatrix. call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', m-j-jb+1,n-j-jb+1, jb, -& one, a( j+jb, j ), lda,a( j, j+jb ), lda, one, a( j+jb, j+jb ),lda ) end if end if end do end if return end subroutine stdlib${ii}$_${ri}$getrf #:endif #:endfor pure module subroutine stdlib${ii}$_cgetrf( m, n, a, lda, ipiv, info ) !! CGETRF computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 3 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, iinfo, j, jb, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGETRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGETRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) if( nb<=1_${ik}$ .or. nb>=min( m, n ) ) then ! use unblocked code. call stdlib${ii}$_cgetrf2( m, n, a, lda, ipiv, info ) else ! use blocked code. do j = 1, min( m, n ), nb jb = min( min( m, n )-j+1, nb ) ! factor diagonal and subdiagonal blocks and test for exact ! singularity. call stdlib${ii}$_cgetrf2( m-j+1, jb, a( j, j ), lda, ipiv( j ), iinfo ) ! adjust info and the pivot indices. if( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + j - 1_${ik}$ do i = j, min( m, j+jb-1 ) ipiv( i ) = j - 1_${ik}$ + ipiv( i ) end do ! apply interchanges to columns 1:j-1. call stdlib${ii}$_claswp( j-1, a, lda, j, j+jb-1, ipiv, 1_${ik}$ ) if( j+jb<=n ) then ! apply interchanges to columns j+jb:n. call stdlib${ii}$_claswp( n-j-jb+1, a( 1_${ik}$, j+jb ), lda, j, j+jb-1,ipiv, 1_${ik}$ ) ! compute block row of u. call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT', jb,n-j-jb+1, cone,& a( j, j ), lda, a( j, j+jb ),lda ) if( j+jb<=m ) then ! update trailing submatrix. call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', m-j-jb+1,n-j-jb+1, jb, -& cone, a( j+jb, j ), lda,a( j, j+jb ), lda, cone, a( j+jb, j+jb ),lda ) end if end if end do end if return end subroutine stdlib${ii}$_cgetrf pure module subroutine stdlib${ii}$_zgetrf( m, n, a, lda, ipiv, info ) !! ZGETRF computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 3 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, iinfo, j, jb, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGETRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) if( nb<=1_${ik}$ .or. nb>=min( m, n ) ) then ! use unblocked code. call stdlib${ii}$_zgetrf2( m, n, a, lda, ipiv, info ) else ! use blocked code. do j = 1, min( m, n ), nb jb = min( min( m, n )-j+1, nb ) ! factor diagonal and subdiagonal blocks and test for exact ! singularity. call stdlib${ii}$_zgetrf2( m-j+1, jb, a( j, j ), lda, ipiv( j ), iinfo ) ! adjust info and the pivot indices. if( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + j - 1_${ik}$ do i = j, min( m, j+jb-1 ) ipiv( i ) = j - 1_${ik}$ + ipiv( i ) end do ! apply interchanges to columns 1:j-1. call stdlib${ii}$_zlaswp( j-1, a, lda, j, j+jb-1, ipiv, 1_${ik}$ ) if( j+jb<=n ) then ! apply interchanges to columns j+jb:n. call stdlib${ii}$_zlaswp( n-j-jb+1, a( 1_${ik}$, j+jb ), lda, j, j+jb-1,ipiv, 1_${ik}$ ) ! compute block row of u. call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT', jb,n-j-jb+1, cone,& a( j, j ), lda, a( j, j+jb ),lda ) if( j+jb<=m ) then ! update trailing submatrix. call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', m-j-jb+1,n-j-jb+1, jb, -& cone, a( j+jb, j ), lda,a( j, j+jb ), lda, cone, a( j+jb, j+jb ),lda ) end if end if end do end if return end subroutine stdlib${ii}$_zgetrf #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$getrf( m, n, a, lda, ipiv, info ) !! ZGETRF: computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 3 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(${ck}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, iinfo, j, jb, nb ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment. nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGETRF', ' ', m, n, -1_${ik}$, -1_${ik}$ ) if( nb<=1_${ik}$ .or. nb>=min( m, n ) ) then ! use unblocked code. call stdlib${ii}$_${ci}$getrf2( m, n, a, lda, ipiv, info ) else ! use blocked code. do j = 1, min( m, n ), nb jb = min( min( m, n )-j+1, nb ) ! factor diagonal and subdiagonal blocks and test for exact ! singularity. call stdlib${ii}$_${ci}$getrf2( m-j+1, jb, a( j, j ), lda, ipiv( j ), iinfo ) ! adjust info and the pivot indices. if( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + j - 1_${ik}$ do i = j, min( m, j+jb-1 ) ipiv( i ) = j - 1_${ik}$ + ipiv( i ) end do ! apply interchanges to columns 1:j-1. call stdlib${ii}$_${ci}$laswp( j-1, a, lda, j, j+jb-1, ipiv, 1_${ik}$ ) if( j+jb<=n ) then ! apply interchanges to columns j+jb:n. call stdlib${ii}$_${ci}$laswp( n-j-jb+1, a( 1_${ik}$, j+jb ), lda, j, j+jb-1,ipiv, 1_${ik}$ ) ! compute block row of u. call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT', jb,n-j-jb+1, cone,& a( j, j ), lda, a( j, j+jb ),lda ) if( j+jb<=m ) then ! update trailing submatrix. call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', m-j-jb+1,n-j-jb+1, jb, -& cone, a( j+jb, j ), lda,a( j, j+jb ), lda, cone, a( j+jb, j+jb ),lda ) end if end if end do end if return end subroutine stdlib${ii}$_${ci}$getrf #:endif #:endfor pure recursive module subroutine stdlib${ii}$_sgetrf2( m, n, a, lda, ipiv, info ) !! SGETRF2 computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! 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 = min(m,n)/2 !! [ A21 | A22 ] n2 = n-n1 !! [ A11 ] !! The subroutine calls itself to factor [ --- ], !! [ A12 ] !! [ A12 ] !! do the swaps on [ --- ], solve A12, update A22, !! [ A22 ] !! then calls itself to factor A22 and do the swaps on A21. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(sp) :: sfmin, temp integer(${ik}$) :: i, iinfo, n1, n2 ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGETRF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return if ( m==1_${ik}$ ) then ! use unblocked code for one row case ! just need to handle ipiv and info ipiv( 1_${ik}$ ) = 1_${ik}$ if ( a(1_${ik}$,1_${ik}$)==zero )info = 1_${ik}$ else if( n==1_${ik}$ ) then ! use unblocked code for one column case ! compute machine safe minimum sfmin = stdlib${ii}$_slamch('S') ! find pivot and test for singularity i = stdlib${ii}$_isamax( m, a( 1_${ik}$, 1_${ik}$ ), 1_${ik}$ ) ipiv( 1_${ik}$ ) = i if( a( i, 1_${ik}$ )/=zero ) then ! apply the interchange if( i/=1_${ik}$ ) then temp = a( 1_${ik}$, 1_${ik}$ ) a( 1_${ik}$, 1_${ik}$ ) = a( i, 1_${ik}$ ) a( i, 1_${ik}$ ) = temp end if ! compute elements 2:m of the column if( abs(a( 1_${ik}$, 1_${ik}$ )) >= sfmin ) then call stdlib${ii}$_sscal( m-1, one / a( 1_${ik}$, 1_${ik}$ ), a( 2_${ik}$, 1_${ik}$ ), 1_${ik}$ ) else do i = 1, m-1 a( 1_${ik}$+i, 1_${ik}$ ) = a( 1_${ik}$+i, 1_${ik}$ ) / a( 1_${ik}$, 1_${ik}$ ) end do end if else info = 1_${ik}$ end if else ! use recursive code n1 = min( m, n ) / 2_${ik}$ n2 = n-n1 ! [ a11 ] ! factor [ --- ] ! [ a21 ] call stdlib${ii}$_sgetrf2( m, n1, a, lda, ipiv, iinfo ) if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo ! [ a12 ] ! apply interchanges to [ --- ] ! [ a22 ] call stdlib${ii}$_slaswp( n2, a( 1_${ik}$, n1+1 ), lda, 1_${ik}$, n1, ipiv, 1_${ik}$ ) ! solve a12 call stdlib${ii}$_strsm( 'L', 'L', 'N', 'U', n1, n2, one, a, lda,a( 1_${ik}$, n1+1 ), lda ) ! update a22 call stdlib${ii}$_sgemm( 'N', 'N', m-n1, n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,a( 1_${ik}$, n1+1 ), & lda, one, a( n1+1, n1+1 ), lda ) ! factor a22 call stdlib${ii}$_sgetrf2( m-n1, n2, a( n1+1, n1+1 ), lda, ipiv( n1+1 ),iinfo ) ! adjust info and the pivot indices if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + n1 do i = n1+1, min( m, n ) ipiv( i ) = ipiv( i ) + n1 end do ! apply interchanges to a21 call stdlib${ii}$_slaswp( n1, a( 1_${ik}$, 1_${ik}$ ), lda, n1+1, min( m, n), ipiv, 1_${ik}$ ) end if return end subroutine stdlib${ii}$_sgetrf2 pure recursive module subroutine stdlib${ii}$_dgetrf2( m, n, a, lda, ipiv, info ) !! DGETRF2 computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! 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 = min(m,n)/2 !! [ A21 | A22 ] n2 = n-n1 !! [ A11 ] !! The subroutine calls itself to factor [ --- ], !! [ A12 ] !! [ A12 ] !! do the swaps on [ --- ], solve A12, update A22, !! [ A22 ] !! then calls itself to factor A22 and do the swaps on A21. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(dp) :: sfmin, temp integer(${ik}$) :: i, iinfo, n1, n2 ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return if ( m==1_${ik}$ ) then ! use unblocked code for one row case ! just need to handle ipiv and info ipiv( 1_${ik}$ ) = 1_${ik}$ if ( a(1_${ik}$,1_${ik}$)==zero )info = 1_${ik}$ else if( n==1_${ik}$ ) then ! use unblocked code for one column case ! compute machine safe minimum sfmin = stdlib${ii}$_dlamch('S') ! find pivot and test for singularity i = stdlib${ii}$_idamax( m, a( 1_${ik}$, 1_${ik}$ ), 1_${ik}$ ) ipiv( 1_${ik}$ ) = i if( a( i, 1_${ik}$ )/=zero ) then ! apply the interchange if( i/=1_${ik}$ ) then temp = a( 1_${ik}$, 1_${ik}$ ) a( 1_${ik}$, 1_${ik}$ ) = a( i, 1_${ik}$ ) a( i, 1_${ik}$ ) = temp end if ! compute elements 2:m of the column if( abs(a( 1_${ik}$, 1_${ik}$ )) >= sfmin ) then call stdlib${ii}$_dscal( m-1, one / a( 1_${ik}$, 1_${ik}$ ), a( 2_${ik}$, 1_${ik}$ ), 1_${ik}$ ) else do i = 1, m-1 a( 1_${ik}$+i, 1_${ik}$ ) = a( 1_${ik}$+i, 1_${ik}$ ) / a( 1_${ik}$, 1_${ik}$ ) end do end if else info = 1_${ik}$ end if else ! use recursive code n1 = min( m, n ) / 2_${ik}$ n2 = n-n1 ! [ a11 ] ! factor [ --- ] ! [ a21 ] call stdlib${ii}$_dgetrf2( m, n1, a, lda, ipiv, iinfo ) if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo ! [ a12 ] ! apply interchanges to [ --- ] ! [ a22 ] call stdlib${ii}$_dlaswp( n2, a( 1_${ik}$, n1+1 ), lda, 1_${ik}$, n1, ipiv, 1_${ik}$ ) ! solve a12 call stdlib${ii}$_dtrsm( 'L', 'L', 'N', 'U', n1, n2, one, a, lda,a( 1_${ik}$, n1+1 ), lda ) ! update a22 call stdlib${ii}$_dgemm( 'N', 'N', m-n1, n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,a( 1_${ik}$, n1+1 ), & lda, one, a( n1+1, n1+1 ), lda ) ! factor a22 call stdlib${ii}$_dgetrf2( m-n1, n2, a( n1+1, n1+1 ), lda, ipiv( n1+1 ),iinfo ) ! adjust info and the pivot indices if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + n1 do i = n1+1, min( m, n ) ipiv( i ) = ipiv( i ) + n1 end do ! apply interchanges to a21 call stdlib${ii}$_dlaswp( n1, a( 1_${ik}$, 1_${ik}$ ), lda, n1+1, min( m, n), ipiv, 1_${ik}$ ) end if return end subroutine stdlib${ii}$_dgetrf2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure recursive module subroutine stdlib${ii}$_${ri}$getrf2( m, n, a, lda, ipiv, info ) !! DGETRF2: computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! 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 = min(m,n)/2 !! [ A21 | A22 ] n2 = n-n1 !! [ A11 ] !! The subroutine calls itself to factor [ --- ], !! [ A12 ] !! [ A12 ] !! do the swaps on [ --- ], solve A12, update A22, !! [ A22 ] !! then calls itself to factor A22 and do the swaps on A21. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(${rk}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(${rk}$) :: sfmin, temp integer(${ik}$) :: i, iinfo, n1, n2 ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return if ( m==1_${ik}$ ) then ! use unblocked code for one row case ! just need to handle ipiv and info ipiv( 1_${ik}$ ) = 1_${ik}$ if ( a(1_${ik}$,1_${ik}$)==zero )info = 1_${ik}$ else if( n==1_${ik}$ ) then ! use unblocked code for one column case ! compute machine safe minimum sfmin = stdlib${ii}$_${ri}$lamch('S') ! find pivot and test for singularity i = stdlib${ii}$_i${ri}$amax( m, a( 1_${ik}$, 1_${ik}$ ), 1_${ik}$ ) ipiv( 1_${ik}$ ) = i if( a( i, 1_${ik}$ )/=zero ) then ! apply the interchange if( i/=1_${ik}$ ) then temp = a( 1_${ik}$, 1_${ik}$ ) a( 1_${ik}$, 1_${ik}$ ) = a( i, 1_${ik}$ ) a( i, 1_${ik}$ ) = temp end if ! compute elements 2:m of the column if( abs(a( 1_${ik}$, 1_${ik}$ )) >= sfmin ) then call stdlib${ii}$_${ri}$scal( m-1, one / a( 1_${ik}$, 1_${ik}$ ), a( 2_${ik}$, 1_${ik}$ ), 1_${ik}$ ) else do i = 1, m-1 a( 1_${ik}$+i, 1_${ik}$ ) = a( 1_${ik}$+i, 1_${ik}$ ) / a( 1_${ik}$, 1_${ik}$ ) end do end if else info = 1_${ik}$ end if else ! use recursive code n1 = min( m, n ) / 2_${ik}$ n2 = n-n1 ! [ a11 ] ! factor [ --- ] ! [ a21 ] call stdlib${ii}$_${ri}$getrf2( m, n1, a, lda, ipiv, iinfo ) if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo ! [ a12 ] ! apply interchanges to [ --- ] ! [ a22 ] call stdlib${ii}$_${ri}$laswp( n2, a( 1_${ik}$, n1+1 ), lda, 1_${ik}$, n1, ipiv, 1_${ik}$ ) ! solve a12 call stdlib${ii}$_${ri}$trsm( 'L', 'L', 'N', 'U', n1, n2, one, a, lda,a( 1_${ik}$, n1+1 ), lda ) ! update a22 call stdlib${ii}$_${ri}$gemm( 'N', 'N', m-n1, n2, n1, -one, a( n1+1, 1_${ik}$ ), lda,a( 1_${ik}$, n1+1 ), & lda, one, a( n1+1, n1+1 ), lda ) ! factor a22 call stdlib${ii}$_${ri}$getrf2( m-n1, n2, a( n1+1, n1+1 ), lda, ipiv( n1+1 ),iinfo ) ! adjust info and the pivot indices if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + n1 do i = n1+1, min( m, n ) ipiv( i ) = ipiv( i ) + n1 end do ! apply interchanges to a21 call stdlib${ii}$_${ri}$laswp( n1, a( 1_${ik}$, 1_${ik}$ ), lda, n1+1, min( m, n), ipiv, 1_${ik}$ ) end if return end subroutine stdlib${ii}$_${ri}$getrf2 #:endif #:endfor pure recursive module subroutine stdlib${ii}$_cgetrf2( m, n, a, lda, ipiv, info ) !! CGETRF2 computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! 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 = min(m,n)/2 !! [ A21 | A22 ] n2 = n-n1 !! [ A11 ] !! The subroutine calls itself to factor [ --- ], !! [ A12 ] !! [ A12 ] !! do the swaps on [ --- ], solve A12, update A22, !! [ A22 ] !! then calls itself to factor A22 and do the swaps on A21. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(sp) :: sfmin complex(sp) :: temp integer(${ik}$) :: i, iinfo, n1, n2 ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGETRF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return if ( m==1_${ik}$ ) then ! use unblocked code for cone row case ! just need to handle ipiv and info ipiv( 1_${ik}$ ) = 1_${ik}$ if ( a(1_${ik}$,1_${ik}$)==czero )info = 1_${ik}$ else if( n==1_${ik}$ ) then ! use unblocked code for cone column case ! compute machine safe minimum sfmin = stdlib${ii}$_slamch('S') ! find pivot and test for singularity i = stdlib${ii}$_icamax( m, a( 1_${ik}$, 1_${ik}$ ), 1_${ik}$ ) ipiv( 1_${ik}$ ) = i if( a( i, 1_${ik}$ )/=czero ) then ! apply the interchange if( i/=1_${ik}$ ) then temp = a( 1_${ik}$, 1_${ik}$ ) a( 1_${ik}$, 1_${ik}$ ) = a( i, 1_${ik}$ ) a( i, 1_${ik}$ ) = temp end if ! compute elements 2:m of the column if( abs(a( 1_${ik}$, 1_${ik}$ )) >= sfmin ) then call stdlib${ii}$_cscal( m-1, cone / a( 1_${ik}$, 1_${ik}$ ), a( 2_${ik}$, 1_${ik}$ ), 1_${ik}$ ) else do i = 1, m-1 a( 1_${ik}$+i, 1_${ik}$ ) = a( 1_${ik}$+i, 1_${ik}$ ) / a( 1_${ik}$, 1_${ik}$ ) end do end if else info = 1_${ik}$ end if else ! use recursive code n1 = min( m, n ) / 2_${ik}$ n2 = n-n1 ! [ a11 ] ! factor [ --- ] ! [ a21 ] call stdlib${ii}$_cgetrf2( m, n1, a, lda, ipiv, iinfo ) if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo ! [ a12 ] ! apply interchanges to [ --- ] ! [ a22 ] call stdlib${ii}$_claswp( n2, a( 1_${ik}$, n1+1 ), lda, 1_${ik}$, n1, ipiv, 1_${ik}$ ) ! solve a12 call stdlib${ii}$_ctrsm( 'L', 'L', 'N', 'U', n1, n2, cone, a, lda,a( 1_${ik}$, n1+1 ), lda ) ! update a22 call stdlib${ii}$_cgemm( 'N', 'N', m-n1, n2, n1, -cone, a( n1+1, 1_${ik}$ ), lda,a( 1_${ik}$, n1+1 ), & lda, cone, a( n1+1, n1+1 ), lda ) ! factor a22 call stdlib${ii}$_cgetrf2( m-n1, n2, a( n1+1, n1+1 ), lda, ipiv( n1+1 ),iinfo ) ! adjust info and the pivot indices if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + n1 do i = n1+1, min( m, n ) ipiv( i ) = ipiv( i ) + n1 end do ! apply interchanges to a21 call stdlib${ii}$_claswp( n1, a( 1_${ik}$, 1_${ik}$ ), lda, n1+1, min( m, n), ipiv, 1_${ik}$ ) end if return end subroutine stdlib${ii}$_cgetrf2 pure recursive module subroutine stdlib${ii}$_zgetrf2( m, n, a, lda, ipiv, info ) !! ZGETRF2 computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! 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 = min(m,n)/2 !! [ A21 | A22 ] n2 = n-n1 !! [ A11 ] !! The subroutine calls itself to factor [ --- ], !! [ A12 ] !! [ A12 ] !! do the swaps on [ --- ], solve A12, update A22, !! [ A22 ] !! then calls itself to factor A22 and do the swaps on A21. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(dp) :: sfmin complex(dp) :: temp integer(${ik}$) :: i, iinfo, n1, n2 ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return if ( m==1_${ik}$ ) then ! use unblocked code for cone row case ! just need to handle ipiv and info ipiv( 1_${ik}$ ) = 1_${ik}$ if ( a(1_${ik}$,1_${ik}$)==czero )info = 1_${ik}$ else if( n==1_${ik}$ ) then ! use unblocked code for cone column case ! compute machine safe minimum sfmin = stdlib${ii}$_dlamch('S') ! find pivot and test for singularity i = stdlib${ii}$_izamax( m, a( 1_${ik}$, 1_${ik}$ ), 1_${ik}$ ) ipiv( 1_${ik}$ ) = i if( a( i, 1_${ik}$ )/=czero ) then ! apply the interchange if( i/=1_${ik}$ ) then temp = a( 1_${ik}$, 1_${ik}$ ) a( 1_${ik}$, 1_${ik}$ ) = a( i, 1_${ik}$ ) a( i, 1_${ik}$ ) = temp end if ! compute elements 2:m of the column if( abs(a( 1_${ik}$, 1_${ik}$ )) >= sfmin ) then call stdlib${ii}$_zscal( m-1, cone / a( 1_${ik}$, 1_${ik}$ ), a( 2_${ik}$, 1_${ik}$ ), 1_${ik}$ ) else do i = 1, m-1 a( 1_${ik}$+i, 1_${ik}$ ) = a( 1_${ik}$+i, 1_${ik}$ ) / a( 1_${ik}$, 1_${ik}$ ) end do end if else info = 1_${ik}$ end if else ! use recursive code n1 = min( m, n ) / 2_${ik}$ n2 = n-n1 ! [ a11 ] ! factor [ --- ] ! [ a21 ] call stdlib${ii}$_zgetrf2( m, n1, a, lda, ipiv, iinfo ) if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo ! [ a12 ] ! apply interchanges to [ --- ] ! [ a22 ] call stdlib${ii}$_zlaswp( n2, a( 1_${ik}$, n1+1 ), lda, 1_${ik}$, n1, ipiv, 1_${ik}$ ) ! solve a12 call stdlib${ii}$_ztrsm( 'L', 'L', 'N', 'U', n1, n2, cone, a, lda,a( 1_${ik}$, n1+1 ), lda ) ! update a22 call stdlib${ii}$_zgemm( 'N', 'N', m-n1, n2, n1, -cone, a( n1+1, 1_${ik}$ ), lda,a( 1_${ik}$, n1+1 ), & lda, cone, a( n1+1, n1+1 ), lda ) ! factor a22 call stdlib${ii}$_zgetrf2( m-n1, n2, a( n1+1, n1+1 ), lda, ipiv( n1+1 ),iinfo ) ! adjust info and the pivot indices if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + n1 do i = n1+1, min( m, n ) ipiv( i ) = ipiv( i ) + n1 end do ! apply interchanges to a21 call stdlib${ii}$_zlaswp( n1, a( 1_${ik}$, 1_${ik}$ ), lda, n1+1, min( m, n), ipiv, 1_${ik}$ ) end if return end subroutine stdlib${ii}$_zgetrf2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure recursive module subroutine stdlib${ii}$_${ci}$getrf2( m, n, a, lda, ipiv, info ) !! ZGETRF2: computes an LU factorization of a general M-by-N matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! 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 = min(m,n)/2 !! [ A21 | A22 ] n2 = n-n1 !! [ A11 ] !! The subroutine calls itself to factor [ --- ], !! [ A12 ] !! [ A12 ] !! do the swaps on [ --- ], solve A12, update A22, !! [ A22 ] !! then calls itself to factor A22 and do the swaps on A21. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(${ck}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(${ck}$) :: sfmin complex(${ck}$) :: temp integer(${ik}$) :: i, iinfo, n1, n2 ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return if ( m==1_${ik}$ ) then ! use unblocked code for cone row case ! just need to handle ipiv and info ipiv( 1_${ik}$ ) = 1_${ik}$ if ( a(1_${ik}$,1_${ik}$)==czero )info = 1_${ik}$ else if( n==1_${ik}$ ) then ! use unblocked code for cone column case ! compute machine safe minimum sfmin = stdlib${ii}$_${c2ri(ci)}$lamch('S') ! find pivot and test for singularity i = stdlib${ii}$_i${ci}$amax( m, a( 1_${ik}$, 1_${ik}$ ), 1_${ik}$ ) ipiv( 1_${ik}$ ) = i if( a( i, 1_${ik}$ )/=czero ) then ! apply the interchange if( i/=1_${ik}$ ) then temp = a( 1_${ik}$, 1_${ik}$ ) a( 1_${ik}$, 1_${ik}$ ) = a( i, 1_${ik}$ ) a( i, 1_${ik}$ ) = temp end if ! compute elements 2:m of the column if( abs(a( 1_${ik}$, 1_${ik}$ )) >= sfmin ) then call stdlib${ii}$_${ci}$scal( m-1, cone / a( 1_${ik}$, 1_${ik}$ ), a( 2_${ik}$, 1_${ik}$ ), 1_${ik}$ ) else do i = 1, m-1 a( 1_${ik}$+i, 1_${ik}$ ) = a( 1_${ik}$+i, 1_${ik}$ ) / a( 1_${ik}$, 1_${ik}$ ) end do end if else info = 1_${ik}$ end if else ! use recursive code n1 = min( m, n ) / 2_${ik}$ n2 = n-n1 ! [ a11 ] ! factor [ --- ] ! [ a21 ] call stdlib${ii}$_${ci}$getrf2( m, n1, a, lda, ipiv, iinfo ) if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo ! [ a12 ] ! apply interchanges to [ --- ] ! [ a22 ] call stdlib${ii}$_${ci}$laswp( n2, a( 1_${ik}$, n1+1 ), lda, 1_${ik}$, n1, ipiv, 1_${ik}$ ) ! solve a12 call stdlib${ii}$_${ci}$trsm( 'L', 'L', 'N', 'U', n1, n2, cone, a, lda,a( 1_${ik}$, n1+1 ), lda ) ! update a22 call stdlib${ii}$_${ci}$gemm( 'N', 'N', m-n1, n2, n1, -cone, a( n1+1, 1_${ik}$ ), lda,a( 1_${ik}$, n1+1 ), & lda, cone, a( n1+1, n1+1 ), lda ) ! factor a22 call stdlib${ii}$_${ci}$getrf2( m-n1, n2, a( n1+1, n1+1 ), lda, ipiv( n1+1 ),iinfo ) ! adjust info and the pivot indices if ( info==0_${ik}$ .and. iinfo>0_${ik}$ )info = iinfo + n1 do i = n1+1, min( m, n ) ipiv( i ) = ipiv( i ) + n1 end do ! apply interchanges to a21 call stdlib${ii}$_${ci}$laswp( n1, a( 1_${ik}$, 1_${ik}$ ), lda, n1+1, min( m, n), ipiv, 1_${ik}$ ) end if return end subroutine stdlib${ii}$_${ci}$getrf2 #:endif #:endfor pure module subroutine stdlib${ii}$_sgetf2( m, n, a, lda, ipiv, info ) !! SGETF2 computes an LU factorization of a general m-by-n matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 2 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(sp) :: sfmin integer(${ik}$) :: i, j, jp ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGETF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! compute machine safe minimum sfmin = stdlib${ii}$_slamch('S') do j = 1, min( m, n ) ! find pivot and test for singularity. jp = j - 1_${ik}$ + stdlib${ii}$_isamax( m-j+1, a( j, j ), 1_${ik}$ ) ipiv( j ) = jp if( a( jp, j )/=zero ) then ! apply the interchange to columns 1:n. if( jp/=j )call stdlib${ii}$_sswap( n, a( j, 1_${ik}$ ), lda, a( jp, 1_${ik}$ ), lda ) ! compute elements j+1:m of j-th column. if( j<m ) then if( abs(a( j, j )) >= sfmin ) then call stdlib${ii}$_sscal( m-j, one / a( j, j ), a( j+1, j ), 1_${ik}$ ) else do i = 1, m-j a( j+i, j ) = a( j+i, j ) / a( j, j ) end do end if end if else if( info==0_${ik}$ ) then info = j end if if( j<min( m, n ) ) then ! update trailing submatrix. call stdlib${ii}$_sger( m-j, n-j, -one, a( j+1, j ), 1_${ik}$, a( j, j+1 ), lda,a( j+1, j+1 ),& lda ) end if end do return end subroutine stdlib${ii}$_sgetf2 pure module subroutine stdlib${ii}$_dgetf2( m, n, a, lda, ipiv, info ) !! DGETF2 computes an LU factorization of a general m-by-n matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 2 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(dp) :: sfmin integer(${ik}$) :: i, j, jp ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! compute machine safe minimum sfmin = stdlib${ii}$_dlamch('S') do j = 1, min( m, n ) ! find pivot and test for singularity. jp = j - 1_${ik}$ + stdlib${ii}$_idamax( m-j+1, a( j, j ), 1_${ik}$ ) ipiv( j ) = jp if( a( jp, j )/=zero ) then ! apply the interchange to columns 1:n. if( jp/=j )call stdlib${ii}$_dswap( n, a( j, 1_${ik}$ ), lda, a( jp, 1_${ik}$ ), lda ) ! compute elements j+1:m of j-th column. if( j<m ) then if( abs(a( j, j )) >= sfmin ) then call stdlib${ii}$_dscal( m-j, one / a( j, j ), a( j+1, j ), 1_${ik}$ ) else do i = 1, m-j a( j+i, j ) = a( j+i, j ) / a( j, j ) end do end if end if else if( info==0_${ik}$ ) then info = j end if if( j<min( m, n ) ) then ! update trailing submatrix. call stdlib${ii}$_dger( m-j, n-j, -one, a( j+1, j ), 1_${ik}$, a( j, j+1 ), lda,a( j+1, j+1 ),& lda ) end if end do return end subroutine stdlib${ii}$_dgetf2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$getf2( m, n, a, lda, ipiv, info ) !! DGETF2: computes an LU factorization of a general m-by-n matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 2 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(${rk}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(${rk}$) :: sfmin integer(${ik}$) :: i, j, jp ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! compute machine safe minimum sfmin = stdlib${ii}$_${ri}$lamch('S') do j = 1, min( m, n ) ! find pivot and test for singularity. jp = j - 1_${ik}$ + stdlib${ii}$_i${ri}$amax( m-j+1, a( j, j ), 1_${ik}$ ) ipiv( j ) = jp if( a( jp, j )/=zero ) then ! apply the interchange to columns 1:n. if( jp/=j )call stdlib${ii}$_${ri}$swap( n, a( j, 1_${ik}$ ), lda, a( jp, 1_${ik}$ ), lda ) ! compute elements j+1:m of j-th column. if( j<m ) then if( abs(a( j, j )) >= sfmin ) then call stdlib${ii}$_${ri}$scal( m-j, one / a( j, j ), a( j+1, j ), 1_${ik}$ ) else do i = 1, m-j a( j+i, j ) = a( j+i, j ) / a( j, j ) end do end if end if else if( info==0_${ik}$ ) then info = j end if if( j<min( m, n ) ) then ! update trailing submatrix. call stdlib${ii}$_${ri}$ger( m-j, n-j, -one, a( j+1, j ), 1_${ik}$, a( j, j+1 ), lda,a( j+1, j+1 ),& lda ) end if end do return end subroutine stdlib${ii}$_${ri}$getf2 #:endif #:endfor pure module subroutine stdlib${ii}$_cgetf2( m, n, a, lda, ipiv, info ) !! CGETF2 computes an LU factorization of a general m-by-n matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 2 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(sp) :: sfmin integer(${ik}$) :: i, j, jp ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGETF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! compute machine safe minimum sfmin = stdlib${ii}$_slamch('S') do j = 1, min( m, n ) ! find pivot and test for singularity. jp = j - 1_${ik}$ + stdlib${ii}$_icamax( m-j+1, a( j, j ), 1_${ik}$ ) ipiv( j ) = jp if( a( jp, j )/=czero ) then ! apply the interchange to columns 1:n. if( jp/=j )call stdlib${ii}$_cswap( n, a( j, 1_${ik}$ ), lda, a( jp, 1_${ik}$ ), lda ) ! compute elements j+1:m of j-th column. if( j<m ) then if( abs(a( j, j )) >= sfmin ) then call stdlib${ii}$_cscal( m-j, cone / a( j, j ), a( j+1, j ), 1_${ik}$ ) else do i = 1, m-j a( j+i, j ) = a( j+i, j ) / a( j, j ) end do end if end if else if( info==0_${ik}$ ) then info = j end if if( j<min( m, n ) ) then ! update trailing submatrix. call stdlib${ii}$_cgeru( m-j, n-j, -cone, a( j+1, j ), 1_${ik}$, a( j, j+1 ),lda, a( j+1, j+1 & ), lda ) end if end do return end subroutine stdlib${ii}$_cgetf2 pure module subroutine stdlib${ii}$_zgetf2( m, n, a, lda, ipiv, info ) !! ZGETF2 computes an LU factorization of a general m-by-n matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 2 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(dp) :: sfmin integer(${ik}$) :: i, j, jp ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! compute machine safe minimum sfmin = stdlib${ii}$_dlamch('S') do j = 1, min( m, n ) ! find pivot and test for singularity. jp = j - 1_${ik}$ + stdlib${ii}$_izamax( m-j+1, a( j, j ), 1_${ik}$ ) ipiv( j ) = jp if( a( jp, j )/=czero ) then ! apply the interchange to columns 1:n. if( jp/=j )call stdlib${ii}$_zswap( n, a( j, 1_${ik}$ ), lda, a( jp, 1_${ik}$ ), lda ) ! compute elements j+1:m of j-th column. if( j<m ) then if( abs(a( j, j )) >= sfmin ) then call stdlib${ii}$_zscal( m-j, cone / a( j, j ), a( j+1, j ), 1_${ik}$ ) else do i = 1, m-j a( j+i, j ) = a( j+i, j ) / a( j, j ) end do end if end if else if( info==0_${ik}$ ) then info = j end if if( j<min( m, n ) ) then ! update trailing submatrix. call stdlib${ii}$_zgeru( m-j, n-j, -cone, a( j+1, j ), 1_${ik}$, a( j, j+1 ),lda, a( j+1, j+1 & ), lda ) end if end do return end subroutine stdlib${ii}$_zgetf2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$getf2( m, n, a, lda, ipiv, info ) !! ZGETF2: computes an LU factorization of a general m-by-n matrix A !! using partial pivoting with row interchanges. !! The factorization has the form !! A = P * L * U !! where P is a permutation matrix, L is lower triangular with unit !! diagonal elements (lower trapezoidal if m > n), and U is upper !! triangular (upper trapezoidal if m < n). !! This is the right-looking Level 2 BLAS version of the algorithm. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(${ck}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars real(${ck}$) :: sfmin integer(${ik}$) :: i, j, jp ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! compute machine safe minimum sfmin = stdlib${ii}$_${c2ri(ci)}$lamch('S') do j = 1, min( m, n ) ! find pivot and test for singularity. jp = j - 1_${ik}$ + stdlib${ii}$_i${ci}$amax( m-j+1, a( j, j ), 1_${ik}$ ) ipiv( j ) = jp if( a( jp, j )/=czero ) then ! apply the interchange to columns 1:n. if( jp/=j )call stdlib${ii}$_${ci}$swap( n, a( j, 1_${ik}$ ), lda, a( jp, 1_${ik}$ ), lda ) ! compute elements j+1:m of j-th column. if( j<m ) then if( abs(a( j, j )) >= sfmin ) then call stdlib${ii}$_${ci}$scal( m-j, cone / a( j, j ), a( j+1, j ), 1_${ik}$ ) else do i = 1, m-j a( j+i, j ) = a( j+i, j ) / a( j, j ) end do end if end if else if( info==0_${ik}$ ) then info = j end if if( j<min( m, n ) ) then ! update trailing submatrix. call stdlib${ii}$_${ci}$geru( m-j, n-j, -cone, a( j+1, j ), 1_${ik}$, a( j, j+1 ),lda, a( j+1, j+1 & ), lda ) end if end do return end subroutine stdlib${ii}$_${ci}$getf2 #:endif #:endfor pure module subroutine stdlib${ii}$_sgetrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info ) !! SGETRS solves a system of linear equations !! A * X = B or A**T * X = B !! with a general N-by-N matrix A using the LU factorization computed !! by SGETRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(in) :: a(lda,*) real(sp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: notran ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGETRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return if( notran ) then ! solve a * x = b. ! apply row interchanges to the right hand sides. call stdlib${ii}$_slaswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, 1_${ik}$ ) ! solve l*x = b, overwriting b with x. call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', '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**t * x = b. ! 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 l**t *x = b, overwriting b with x. call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'TRANSPOSE', 'UNIT', n, nrhs, one,a, lda, b, & ldb ) ! apply row interchanges to the solution vectors. call stdlib${ii}$_slaswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, -1_${ik}$ ) end if return end subroutine stdlib${ii}$_sgetrs pure module subroutine stdlib${ii}$_dgetrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info ) !! DGETRS solves a system of linear equations !! A * X = B or A**T * X = B !! with a general N-by-N matrix A using the LU factorization computed !! by DGETRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(in) :: a(lda,*) real(dp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: notran ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return if( notran ) then ! solve a * x = b. ! apply row interchanges to the right hand sides. call stdlib${ii}$_dlaswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, 1_${ik}$ ) ! solve l*x = b, overwriting b with x. call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', '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**t * x = b. ! 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 l**t *x = b, overwriting b with x. call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'TRANSPOSE', 'UNIT', n, nrhs, one,a, lda, b, & ldb ) ! apply row interchanges to the solution vectors. call stdlib${ii}$_dlaswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, -1_${ik}$ ) end if return end subroutine stdlib${ii}$_dgetrs #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$getrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info ) !! DGETRS: solves a system of linear equations !! A * X = B or A**T * X = B !! with a general N-by-N matrix A using the LU factorization computed !! by DGETRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(in) :: a(lda,*) real(${rk}$), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: notran ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return if( notran ) then ! solve a * x = b. ! apply row interchanges to the right hand sides. call stdlib${ii}$_${ri}$laswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, 1_${ik}$ ) ! solve l*x = b, overwriting b with x. call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', '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**t * x = b. ! 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 l**t *x = b, overwriting b with x. call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'TRANSPOSE', 'UNIT', n, nrhs, one,a, lda, b, & ldb ) ! apply row interchanges to the solution vectors. call stdlib${ii}$_${ri}$laswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, -1_${ik}$ ) end if return end subroutine stdlib${ii}$_${ri}$getrs #:endif #:endfor pure module subroutine stdlib${ii}$_cgetrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info ) !! CGETRS solves a system of linear equations !! A * X = B, A**T * X = B, or A**H * X = B !! with a general N-by-N matrix A using the LU factorization computed !! by CGETRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(sp), intent(in) :: a(lda,*) complex(sp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: notran ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGETRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return if( notran ) then ! solve a * x = b. ! apply row interchanges to the right hand sides. call stdlib${ii}$_claswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, 1_${ik}$ ) ! solve l*x = b, overwriting b with x. call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', '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**t * x = b or a**h * x = b. ! solve u**t *x = b or u**h *x = b, overwriting b with x. call stdlib${ii}$_ctrsm( 'LEFT', 'UPPER', trans, 'NON-UNIT', n, nrhs, cone,a, lda, b, ldb & ) ! solve l**t *x = b, or l**h *x = b overwriting b with x. call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', trans, 'UNIT', n, nrhs, cone, a,lda, b, ldb ) ! apply row interchanges to the solution vectors. call stdlib${ii}$_claswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, -1_${ik}$ ) end if return end subroutine stdlib${ii}$_cgetrs pure module subroutine stdlib${ii}$_zgetrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info ) !! ZGETRS solves a system of linear equations !! A * X = B, A**T * X = B, or A**H * X = B !! with a general N-by-N matrix A using the LU factorization computed !! by ZGETRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(dp), intent(in) :: a(lda,*) complex(dp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: notran ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return if( notran ) then ! solve a * x = b. ! apply row interchanges to the right hand sides. call stdlib${ii}$_zlaswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, 1_${ik}$ ) ! solve l*x = b, overwriting b with x. call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', '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**t * x = b or a**h * x = b. ! solve u**t *x = b or u**h *x = b, overwriting b with x. call stdlib${ii}$_ztrsm( 'LEFT', 'UPPER', trans, 'NON-UNIT', n, nrhs, cone,a, lda, b, ldb & ) ! solve l**t *x = b, or l**h *x = b overwriting b with x. call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', trans, 'UNIT', n, nrhs, cone, a,lda, b, ldb ) ! apply row interchanges to the solution vectors. call stdlib${ii}$_zlaswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, -1_${ik}$ ) end if return end subroutine stdlib${ii}$_zgetrs #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$getrs( trans, n, nrhs, a, lda, ipiv, b, ldb, info ) !! ZGETRS: solves a system of linear equations !! A * X = B, A**T * X = B, or A**H * X = B !! with a general N-by-N matrix A using the LU factorization computed !! by ZGETRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(in) :: a(lda,*) complex(${ck}$), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: notran ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return if( notran ) then ! solve a * x = b. ! apply row interchanges to the right hand sides. call stdlib${ii}$_${ci}$laswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, 1_${ik}$ ) ! solve l*x = b, overwriting b with x. call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', '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**t * x = b or a**h * x = b. ! solve u**t *x = b or u**h *x = b, overwriting b with x. call stdlib${ii}$_${ci}$trsm( 'LEFT', 'UPPER', trans, 'NON-UNIT', n, nrhs, cone,a, lda, b, ldb & ) ! solve l**t *x = b, or l**h *x = b overwriting b with x. call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', trans, 'UNIT', n, nrhs, cone, a,lda, b, ldb ) ! apply row interchanges to the solution vectors. call stdlib${ii}$_${ci}$laswp( nrhs, b, ldb, 1_${ik}$, n, ipiv, -1_${ik}$ ) end if return end subroutine stdlib${ii}$_${ci}$getrs #:endif #:endfor pure module subroutine stdlib${ii}$_sgetri( n, a, lda, ipiv, work, lwork, info ) !! SGETRI computes the inverse of a matrix using the LU factorization !! computed by SGETRF. !! This method inverts U and then computes inv(A) by solving the system !! inv(A)*L = inv(U) for 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) :: lda, lwork, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(inout) :: a(lda,*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery integer(${ik}$) :: i, iws, j, jb, jj, jp, ldwork, lwkopt, nb, nbmin, nn ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( n<0_${ik}$ ) then info = -1_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -3_${ik}$ else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGETRI', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form inv(u). if info > 0 from stdlib${ii}$_strtri, then u is singular, ! and the inverse is not computed. call stdlib${ii}$_strtri( 'UPPER', 'NON-UNIT', n, a, lda, info ) if( info>0 )return nbmin = 2_${ik}$ ldwork = n if( nb>1_${ik}$ .and. nb<n ) then iws = max( ldwork*nb, 1_${ik}$ ) if( lwork<iws ) then nb = lwork / ldwork nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'SGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) end if else iws = n end if ! solve the equation inv(a)*l = inv(u) for inv(a). if( nb<nbmin .or. nb>=n ) then ! use unblocked code. do j = n, 1, -1 ! copy current column of l to work and replace with zeros. do i = j + 1, n work( i ) = a( i, j ) a( i, j ) = zero end do ! compute current column of inv(a). if( j<n )call stdlib${ii}$_sgemv( 'NO TRANSPOSE', n, n-j, -one, a( 1_${ik}$, j+1 ),lda, work( & j+1 ), 1_${ik}$, one, a( 1_${ik}$, j ), 1_${ik}$ ) end do else ! use blocked code. nn = ( ( n-1 ) / nb )*nb + 1_${ik}$ do j = nn, 1, -nb jb = min( nb, n-j+1 ) ! copy current block column of l to work and replace with ! zeros. do jj = j, j + jb - 1 do i = jj + 1, n work( i+( jj-j )*ldwork ) = a( i, jj ) a( i, jj ) = zero end do end do ! compute current block column of inv(a). if( j+jb<=n )call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', n, jb,n-j-jb+1, -& one, a( 1_${ik}$, j+jb ), lda,work( j+jb ), ldwork, one, a( 1_${ik}$, j ), lda ) call stdlib${ii}$_strsm( 'RIGHT', 'LOWER', 'NO TRANSPOSE', 'UNIT', n, jb,one, work( j )& , ldwork, a( 1_${ik}$, j ), lda ) end do end if ! apply column interchanges. do j = n - 1, 1, -1 jp = ipiv( j ) if( jp/=j )call stdlib${ii}$_sswap( n, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, jp ), 1_${ik}$ ) end do work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_sgetri pure module subroutine stdlib${ii}$_dgetri( n, a, lda, ipiv, work, lwork, info ) !! DGETRI computes the inverse of a matrix using the LU factorization !! computed by DGETRF. !! This method inverts U and then computes inv(A) by solving the system !! inv(A)*L = inv(U) for 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) :: lda, lwork, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(inout) :: a(lda,*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery integer(${ik}$) :: i, iws, j, jb, jj, jp, ldwork, lwkopt, nb, nbmin, nn ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( n<0_${ik}$ ) then info = -1_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -3_${ik}$ else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRI', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form inv(u). if info > 0 from stdlib${ii}$_dtrtri, then u is singular, ! and the inverse is not computed. call stdlib${ii}$_dtrtri( 'UPPER', 'NON-UNIT', n, a, lda, info ) if( info>0 )return nbmin = 2_${ik}$ ldwork = n if( nb>1_${ik}$ .and. nb<n ) then iws = max( ldwork*nb, 1_${ik}$ ) if( lwork<iws ) then nb = lwork / ldwork nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'DGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) end if else iws = n end if ! solve the equation inv(a)*l = inv(u) for inv(a). if( nb<nbmin .or. nb>=n ) then ! use unblocked code. do j = n, 1, -1 ! copy current column of l to work and replace with zeros. do i = j + 1, n work( i ) = a( i, j ) a( i, j ) = zero end do ! compute current column of inv(a). if( j<n )call stdlib${ii}$_dgemv( 'NO TRANSPOSE', n, n-j, -one, a( 1_${ik}$, j+1 ),lda, work( & j+1 ), 1_${ik}$, one, a( 1_${ik}$, j ), 1_${ik}$ ) end do else ! use blocked code. nn = ( ( n-1 ) / nb )*nb + 1_${ik}$ do j = nn, 1, -nb jb = min( nb, n-j+1 ) ! copy current block column of l to work and replace with ! zeros. do jj = j, j + jb - 1 do i = jj + 1, n work( i+( jj-j )*ldwork ) = a( i, jj ) a( i, jj ) = zero end do end do ! compute current block column of inv(a). if( j+jb<=n )call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', n, jb,n-j-jb+1, -& one, a( 1_${ik}$, j+jb ), lda,work( j+jb ), ldwork, one, a( 1_${ik}$, j ), lda ) call stdlib${ii}$_dtrsm( 'RIGHT', 'LOWER', 'NO TRANSPOSE', 'UNIT', n, jb,one, work( j )& , ldwork, a( 1_${ik}$, j ), lda ) end do end if ! apply column interchanges. do j = n - 1, 1, -1 jp = ipiv( j ) if( jp/=j )call stdlib${ii}$_dswap( n, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, jp ), 1_${ik}$ ) end do work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_dgetri #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$getri( n, a, lda, ipiv, work, lwork, info ) !! DGETRI: computes the inverse of a matrix using the LU factorization !! computed by DGETRF. !! This method inverts U and then computes inv(A) by solving the system !! inv(A)*L = inv(U) for 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) :: lda, lwork, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery integer(${ik}$) :: i, iws, j, jb, jj, jp, ldwork, lwkopt, nb, nbmin, nn ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( n<0_${ik}$ ) then info = -1_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -3_${ik}$ else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGETRI', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form inv(u). if info > 0 from stdlib${ii}$_${ri}$trtri, then u is singular, ! and the inverse is not computed. call stdlib${ii}$_${ri}$trtri( 'UPPER', 'NON-UNIT', n, a, lda, info ) if( info>0 )return nbmin = 2_${ik}$ ldwork = n if( nb>1_${ik}$ .and. nb<n ) then iws = max( ldwork*nb, 1_${ik}$ ) if( lwork<iws ) then nb = lwork / ldwork nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'DGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) end if else iws = n end if ! solve the equation inv(a)*l = inv(u) for inv(a). if( nb<nbmin .or. nb>=n ) then ! use unblocked code. do j = n, 1, -1 ! copy current column of l to work and replace with zeros. do i = j + 1, n work( i ) = a( i, j ) a( i, j ) = zero end do ! compute current column of inv(a). if( j<n )call stdlib${ii}$_${ri}$gemv( 'NO TRANSPOSE', n, n-j, -one, a( 1_${ik}$, j+1 ),lda, work( & j+1 ), 1_${ik}$, one, a( 1_${ik}$, j ), 1_${ik}$ ) end do else ! use blocked code. nn = ( ( n-1 ) / nb )*nb + 1_${ik}$ do j = nn, 1, -nb jb = min( nb, n-j+1 ) ! copy current block column of l to work and replace with ! zeros. do jj = j, j + jb - 1 do i = jj + 1, n work( i+( jj-j )*ldwork ) = a( i, jj ) a( i, jj ) = zero end do end do ! compute current block column of inv(a). if( j+jb<=n )call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', n, jb,n-j-jb+1, -& one, a( 1_${ik}$, j+jb ), lda,work( j+jb ), ldwork, one, a( 1_${ik}$, j ), lda ) call stdlib${ii}$_${ri}$trsm( 'RIGHT', 'LOWER', 'NO TRANSPOSE', 'UNIT', n, jb,one, work( j )& , ldwork, a( 1_${ik}$, j ), lda ) end do end if ! apply column interchanges. do j = n - 1, 1, -1 jp = ipiv( j ) if( jp/=j )call stdlib${ii}$_${ri}$swap( n, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, jp ), 1_${ik}$ ) end do work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_${ri}$getri #:endif #:endfor pure module subroutine stdlib${ii}$_cgetri( n, a, lda, ipiv, work, lwork, info ) !! CGETRI computes the inverse of a matrix using the LU factorization !! computed by CGETRF. !! This method inverts U and then computes inv(A) by solving the system !! inv(A)*L = inv(U) for 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) :: lda, lwork, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(sp), intent(inout) :: a(lda,*) complex(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery integer(${ik}$) :: i, iws, j, jb, jj, jp, ldwork, lwkopt, nb, nbmin, nn ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( n<0_${ik}$ ) then info = -1_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -3_${ik}$ else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGETRI', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form inv(u). if info > 0 from stdlib${ii}$_ctrtri, then u is singular, ! and the inverse is not computed. call stdlib${ii}$_ctrtri( 'UPPER', 'NON-UNIT', n, a, lda, info ) if( info>0 )return nbmin = 2_${ik}$ ldwork = n if( nb>1_${ik}$ .and. nb<n ) then iws = max( ldwork*nb, 1_${ik}$ ) if( lwork<iws ) then nb = lwork / ldwork nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'CGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) end if else iws = n end if ! solve the equation inv(a)*l = inv(u) for inv(a). if( nb<nbmin .or. nb>=n ) then ! use unblocked code. do j = n, 1, -1 ! copy current column of l to work and replace with zeros. do i = j + 1, n work( i ) = a( i, j ) a( i, j ) = czero end do ! compute current column of inv(a). if( j<n )call stdlib${ii}$_cgemv( 'NO TRANSPOSE', n, n-j, -cone, a( 1_${ik}$, j+1 ),lda, work(& j+1 ), 1_${ik}$, cone, a( 1_${ik}$, j ), 1_${ik}$ ) end do else ! use blocked code. nn = ( ( n-1 ) / nb )*nb + 1_${ik}$ do j = nn, 1, -nb jb = min( nb, n-j+1 ) ! copy current block column of l to work and replace with ! zeros. do jj = j, j + jb - 1 do i = jj + 1, n work( i+( jj-j )*ldwork ) = a( i, jj ) a( i, jj ) = czero end do end do ! compute current block column of inv(a). if( j+jb<=n )call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', n, jb,n-j-jb+1, -& cone, a( 1_${ik}$, j+jb ), lda,work( j+jb ), ldwork, cone, a( 1_${ik}$, j ), lda ) call stdlib${ii}$_ctrsm( 'RIGHT', 'LOWER', 'NO TRANSPOSE', 'UNIT', n, jb,cone, work( j & ), ldwork, a( 1_${ik}$, j ), lda ) end do end if ! apply column interchanges. do j = n - 1, 1, -1 jp = ipiv( j ) if( jp/=j )call stdlib${ii}$_cswap( n, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, jp ), 1_${ik}$ ) end do work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_cgetri pure module subroutine stdlib${ii}$_zgetri( n, a, lda, ipiv, work, lwork, info ) !! ZGETRI computes the inverse of a matrix using the LU factorization !! computed by ZGETRF. !! This method inverts U and then computes inv(A) by solving the system !! inv(A)*L = inv(U) for 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) :: lda, lwork, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(dp), intent(inout) :: a(lda,*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery integer(${ik}$) :: i, iws, j, jb, jj, jp, ldwork, lwkopt, nb, nbmin, nn ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( n<0_${ik}$ ) then info = -1_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -3_${ik}$ else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRI', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form inv(u). if info > 0 from stdlib${ii}$_ztrtri, then u is singular, ! and the inverse is not computed. call stdlib${ii}$_ztrtri( 'UPPER', 'NON-UNIT', n, a, lda, info ) if( info>0 )return nbmin = 2_${ik}$ ldwork = n if( nb>1_${ik}$ .and. nb<n ) then iws = max( ldwork*nb, 1_${ik}$ ) if( lwork<iws ) then nb = lwork / ldwork nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'ZGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) end if else iws = n end if ! solve the equation inv(a)*l = inv(u) for inv(a). if( nb<nbmin .or. nb>=n ) then ! use unblocked code. do j = n, 1, -1 ! copy current column of l to work and replace with zeros. do i = j + 1, n work( i ) = a( i, j ) a( i, j ) = czero end do ! compute current column of inv(a). if( j<n )call stdlib${ii}$_zgemv( 'NO TRANSPOSE', n, n-j, -cone, a( 1_${ik}$, j+1 ),lda, work(& j+1 ), 1_${ik}$, cone, a( 1_${ik}$, j ), 1_${ik}$ ) end do else ! use blocked code. nn = ( ( n-1 ) / nb )*nb + 1_${ik}$ do j = nn, 1, -nb jb = min( nb, n-j+1 ) ! copy current block column of l to work and replace with ! zeros. do jj = j, j + jb - 1 do i = jj + 1, n work( i+( jj-j )*ldwork ) = a( i, jj ) a( i, jj ) = czero end do end do ! compute current block column of inv(a). if( j+jb<=n )call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', n, jb,n-j-jb+1, -& cone, a( 1_${ik}$, j+jb ), lda,work( j+jb ), ldwork, cone, a( 1_${ik}$, j ), lda ) call stdlib${ii}$_ztrsm( 'RIGHT', 'LOWER', 'NO TRANSPOSE', 'UNIT', n, jb,cone, work( j & ), ldwork, a( 1_${ik}$, j ), lda ) end do end if ! apply column interchanges. do j = n - 1, 1, -1 jp = ipiv( j ) if( jp/=j )call stdlib${ii}$_zswap( n, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, jp ), 1_${ik}$ ) end do work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_zgetri #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$getri( n, a, lda, ipiv, work, lwork, info ) !! ZGETRI: computes the inverse of a matrix using the LU factorization !! computed by ZGETRF. !! This method inverts U and then computes inv(A) by solving the system !! inv(A)*L = inv(U) for 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) :: lda, lwork, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(inout) :: a(lda,*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lquery integer(${ik}$) :: i, iws, j, jb, jj, jp, ldwork, lwkopt, nb, nbmin, nn ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) lwkopt = n*nb work( 1_${ik}$ ) = lwkopt lquery = ( lwork==-1_${ik}$ ) if( n<0_${ik}$ ) then info = -1_${ik}$ else if( lda<max( 1_${ik}$, n ) ) then info = -3_${ik}$ else if( lwork<max( 1_${ik}$, n ) .and. .not.lquery ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGETRI', -info ) return else if( lquery ) then return end if ! quick return if possible if( n==0 )return ! form inv(u). if info > 0 from stdlib${ii}$_${ci}$trtri, then u is singular, ! and the inverse is not computed. call stdlib${ii}$_${ci}$trtri( 'UPPER', 'NON-UNIT', n, a, lda, info ) if( info>0 )return nbmin = 2_${ik}$ ldwork = n if( nb>1_${ik}$ .and. nb<n ) then iws = max( ldwork*nb, 1_${ik}$ ) if( lwork<iws ) then nb = lwork / ldwork nbmin = max( 2_${ik}$, stdlib${ii}$_ilaenv( 2_${ik}$, 'ZGETRI', ' ', n, -1_${ik}$, -1_${ik}$, -1_${ik}$ ) ) end if else iws = n end if ! solve the equation inv(a)*l = inv(u) for inv(a). if( nb<nbmin .or. nb>=n ) then ! use unblocked code. do j = n, 1, -1 ! copy current column of l to work and replace with zeros. do i = j + 1, n work( i ) = a( i, j ) a( i, j ) = czero end do ! compute current column of inv(a). if( j<n )call stdlib${ii}$_${ci}$gemv( 'NO TRANSPOSE', n, n-j, -cone, a( 1_${ik}$, j+1 ),lda, work(& j+1 ), 1_${ik}$, cone, a( 1_${ik}$, j ), 1_${ik}$ ) end do else ! use blocked code. nn = ( ( n-1 ) / nb )*nb + 1_${ik}$ do j = nn, 1, -nb jb = min( nb, n-j+1 ) ! copy current block column of l to work and replace with ! zeros. do jj = j, j + jb - 1 do i = jj + 1, n work( i+( jj-j )*ldwork ) = a( i, jj ) a( i, jj ) = czero end do end do ! compute current block column of inv(a). if( j+jb<=n )call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', n, jb,n-j-jb+1, -& cone, a( 1_${ik}$, j+jb ), lda,work( j+jb ), ldwork, cone, a( 1_${ik}$, j ), lda ) call stdlib${ii}$_${ci}$trsm( 'RIGHT', 'LOWER', 'NO TRANSPOSE', 'UNIT', n, jb,cone, work( j & ), ldwork, a( 1_${ik}$, j ), lda ) end do end if ! apply column interchanges. do j = n - 1, 1, -1 jp = ipiv( j ) if( jp/=j )call stdlib${ii}$_${ci}$swap( n, a( 1_${ik}$, j ), 1_${ik}$, a( 1_${ik}$, jp ), 1_${ik}$ ) end do work( 1_${ik}$ ) = iws return end subroutine stdlib${ii}$_${ci}$getri #:endif #:endfor pure module subroutine stdlib${ii}$_sgerfs( trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb,x, ldx, ferr, & !! SGERFS improves the computed solution to a system of linear !! equations 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transt 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -10_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGERFS', -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 if( notran ) then transt = 'T' else transt = 'N' 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_scopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_sgemv( trans, n, 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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n xk = abs( x( k, j ) ) do i = 1, n work( i ) = work( i ) + abs( a( i, k ) )*xk end do end do else do k = 1, n s = zero do i = 1, n 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}$_sgetrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_slacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**t). call stdlib${ii}$_sgetrs( transt, n, 1_${ik}$, af, ldaf, ipiv, work( n+1 ),n, info ) do i = 1, n work( n+i ) = work( i )*work( n+i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( i )*work( n+i ) end do call stdlib${ii}$_sgetrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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}$_sgerfs pure module subroutine stdlib${ii}$_dgerfs( trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb,x, ldx, ferr, & !! DGERFS improves the computed solution to a system of linear !! equations 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transt 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -10_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGERFS', -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 if( notran ) then transt = 'T' else transt = 'N' 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_dcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_dgemv( trans, n, 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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n xk = abs( x( k, j ) ) do i = 1, n work( i ) = work( i ) + abs( a( i, k ) )*xk end do end do else do k = 1, n s = zero do i = 1, n 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}$_dgetrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_dlacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**t). call stdlib${ii}$_dgetrs( transt, n, 1_${ik}$, af, ldaf, ipiv, work( n+1 ),n, info ) do i = 1, n work( n+i ) = work( i )*work( n+i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( i )*work( n+i ) end do call stdlib${ii}$_dgetrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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}$_dgerfs #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gerfs( trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb,x, ldx, ferr, & !! DGERFS: improves the computed solution to a system of linear !! equations 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transt 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -10_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGERFS', -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 if( notran ) then transt = 'T' else transt = 'N' 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_${ri}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_${ri}$gemv( trans, n, 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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n xk = abs( x( k, j ) ) do i = 1, n work( i ) = work( i ) + abs( a( i, k ) )*xk end do end do else do k = 1, n s = zero do i = 1, n 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}$getrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_${ri}$lacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**t). call stdlib${ii}$_${ri}$getrs( transt, n, 1_${ik}$, af, ldaf, ipiv, work( n+1 ),n, info ) do i = 1, n work( n+i ) = work( i )*work( n+i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( i )*work( n+i ) end do call stdlib${ii}$_${ri}$getrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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}$gerfs #:endif #:endfor pure module subroutine stdlib${ii}$_cgerfs( trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb,x, ldx, ferr, & !! CGERFS improves the computed solution to a system of linear !! equations 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transn, transt 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -10_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGERFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_ccopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_cgemv( trans, n, 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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n xk = cabs1( x( k, j ) ) do i = 1, n rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk end do end do else do k = 1, n s = zero do i = 1, n 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}$_cgetrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_clacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**h). call stdlib${ii}$_cgetrs( transt, n, 1_${ik}$, af, ldaf, ipiv, work, n,info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_cgetrs( transn, n, 1_${ik}$, af, ldaf, ipiv, 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}$_cgerfs pure module subroutine stdlib${ii}$_zgerfs( trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb,x, ldx, ferr, & !! ZGERFS improves the computed solution to a system of linear !! equations 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transn, transt 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -10_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGERFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_zcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_zgemv( trans, n, 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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n xk = cabs1( x( k, j ) ) do i = 1, n rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk end do end do else do k = 1, n s = zero do i = 1, n 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}$_zgetrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_zlacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**h). call stdlib${ii}$_zgetrs( transt, n, 1_${ik}$, af, ldaf, ipiv, work, n,info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_zgetrs( transn, n, 1_${ik}$, af, ldaf, ipiv, 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}$_zgerfs #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gerfs( trans, n, nrhs, a, lda, af, ldaf, ipiv, b, ldb,x, ldx, ferr, & !! ZGERFS: improves the computed solution to a system of linear !! equations 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, ldaf, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transn, transt 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -10_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -12_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGERFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_${ci}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_${ci}$gemv( trans, n, 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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n xk = cabs1( x( k, j ) ) do i = 1, n rwork( i ) = rwork( i ) + cabs1( a( i, k ) )*xk end do end do else do k = 1, n s = zero do i = 1, n 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}$getrs( trans, n, 1_${ik}$, af, ldaf, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_${ci}$lacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**h). call stdlib${ii}$_${ci}$getrs( transt, n, 1_${ik}$, af, ldaf, ipiv, work, n,info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_${ci}$getrs( transn, n, 1_${ik}$, af, ldaf, ipiv, 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}$gerfs #:endif #:endfor pure module subroutine stdlib${ii}$_sgeequ( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! SGEEQU computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(in) :: a(lda,*) real(sp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(sp) :: bignum, rcmax, rcmin, smlnum ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGEEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), abs( a( i, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), abs( a( i, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_sgeequ pure module subroutine stdlib${ii}$_dgeequ( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! DGEEQU computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(in) :: a(lda,*) real(dp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(dp) :: bignum, rcmax, rcmin, smlnum ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGEEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), abs( a( i, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), abs( a( i, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_dgeequ #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$geequ( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! DGEEQU: computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${rk}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n real(${rk}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${rk}$), intent(in) :: a(lda,*) real(${rk}$), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(${rk}$) :: bignum, rcmax, rcmin, smlnum ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGEEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), abs( a( i, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), abs( a( i, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ri}$geequ #:endif #:endfor pure module subroutine stdlib${ii}$_cgeequ( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! CGEEQU computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_sp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(out) :: c(*), r(*) complex(sp), intent(in) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(sp) :: bignum, rcmax, rcmin, smlnum 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGEEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), cabs1( a( i, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), cabs1( a( i, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_cgeequ pure module subroutine stdlib${ii}$_zgeequ( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! ZGEEQU computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_dp, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(out) :: c(*), r(*) complex(dp), intent(in) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(dp) :: bignum, rcmax, rcmin, smlnum 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGEEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), cabs1( a( i, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), cabs1( a( i, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_zgeequ #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$geequ( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! ZGEEQU: computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack is a software package provided by univ. of tennessee, -- ! -- univ. of california berkeley, univ. of colorado denver and nag ltd..-- use stdlib_blas_constants_${ck}$, only: negone, zero, half, one, two, three, four, eight, ten, czero, chalf, cone, cnegone ! Scalar Arguments integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, m, n real(${ck}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${ck}$), intent(out) :: c(*), r(*) complex(${ck}$), intent(in) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(${ck}$) :: bignum, rcmax, rcmin, smlnum 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGEEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), cabs1( a( i, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), cabs1( a( i, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ci}$geequ #:endif #:endfor pure module subroutine stdlib${ii}$_sgeequb( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! SGEEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from SGEEQU 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 entries' magnitudes 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, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(in) :: a(lda,*) real(sp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(sp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGEEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_slamch( 'B' ) logrdx = log( radix ) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), abs( a( i, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), abs( a( i, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_sgeequb pure module subroutine stdlib${ii}$_dgeequb( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! DGEEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from DGEEQU 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 entries' magnitudes 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, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(in) :: a(lda,*) real(dp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(dp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGEEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_dlamch( 'B' ) logrdx = log( radix ) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), abs( a( i, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), abs( a( i, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_dgeequb #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$geequb( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! DGEEQUB: computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from DGEEQU 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 entries' magnitudes 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, m, n real(${rk}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${rk}$), intent(in) :: a(lda,*) real(${rk}$), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(${rk}$) :: bignum, rcmax, rcmin, smlnum, radix, logrdx ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGEEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_${ri}$lamch( 'B' ) logrdx = log( radix ) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), abs( a( i, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), abs( a( i, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ri}$geequb #:endif #:endfor pure module subroutine stdlib${ii}$_cgeequb( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! CGEEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from CGEEQU 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 entries' magnitudes 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, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(out) :: c(*), r(*) complex(sp), intent(in) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(sp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGEEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_slamch( 'B' ) logrdx = log( radix ) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), cabs1( a( i, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log(r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), cabs1( a( i, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_cgeequb pure module subroutine stdlib${ii}$_zgeequb( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! ZGEEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from ZGEEQU 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 entries' magnitudes 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, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(out) :: c(*), r(*) complex(dp), intent(in) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(dp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGEEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_dlamch( 'B' ) logrdx = log( radix ) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), cabs1( a( i, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log(r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), cabs1( a( i, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_zgeequb #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$geequb( m, n, a, lda, r, c, rowcnd, colcnd, amax,info ) !! ZGEEQUB: computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from ZGEEQU 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 entries' magnitudes 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, m, n real(${ck}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${ck}$), intent(out) :: c(*), r(*) complex(${ck}$), intent(in) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(${ck}$) :: bignum, rcmax, rcmin, smlnum, radix, logrdx 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( lda<max( 1_${ik}$, m ) ) then info = -4_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGEEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_${c2ri(ci)}$lamch( 'B' ) logrdx = log( radix ) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. do j = 1, n do i = 1, m r( i ) = max( r( i ), cabs1( a( i, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log(r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = 1, m c( j ) = max( c( j ), cabs1( a( i, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ci}$geequb #:endif #:endfor pure module subroutine stdlib${ii}$_slaqge( m, n, a, lda, r, c, rowcnd, colcnd, amax,equed ) !! SLAQGE equilibrates a general M by N matrix A using the row and !! column scaling factors in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: lda, m, n real(sp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(inout) :: a(lda,*) real(sp), intent(in) :: c(*), r(*) ! ===================================================================== ! Parameters real(sp), parameter :: thresh = 0.1e+0_sp ! Local Scalars integer(${ik}$) :: i, j real(sp) :: cj, large, small ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*a( i, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = 1, m a( i, j ) = r( i )*a( i, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*r( i )*a( i, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_slaqge pure module subroutine stdlib${ii}$_dlaqge( m, n, a, lda, r, c, rowcnd, colcnd, amax,equed ) !! DLAQGE equilibrates a general M by N matrix A using the row and !! column scaling factors in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: lda, m, n real(dp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(inout) :: a(lda,*) real(dp), intent(in) :: c(*), r(*) ! ===================================================================== ! Parameters real(dp), parameter :: thresh = 0.1e+0_dp ! Local Scalars integer(${ik}$) :: i, j real(dp) :: cj, large, small ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*a( i, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = 1, m a( i, j ) = r( i )*a( i, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*r( i )*a( i, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_dlaqge #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$laqge( m, n, a, lda, r, c, rowcnd, colcnd, amax,equed ) !! DLAQGE: equilibrates a general M by N matrix A using the row and !! column scaling factors in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: lda, m, n real(${rk}$), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(${rk}$), intent(inout) :: a(lda,*) real(${rk}$), intent(in) :: c(*), r(*) ! ===================================================================== ! Parameters real(${rk}$), parameter :: thresh = 0.1e+0_${rk}$ ! Local Scalars integer(${ik}$) :: i, j real(${rk}$) :: cj, large, small ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*a( i, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = 1, m a( i, j ) = r( i )*a( i, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*r( i )*a( i, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_${ri}$laqge #:endif #:endfor pure module subroutine stdlib${ii}$_claqge( m, n, a, lda, r, c, rowcnd, colcnd, amax,equed ) !! CLAQGE equilibrates a general M by N matrix A using the row and !! column scaling factors in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: lda, m, n real(sp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(in) :: c(*), r(*) 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 ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*a( i, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = 1, m a( i, j ) = r( i )*a( i, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*r( i )*a( i, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_claqge pure module subroutine stdlib${ii}$_zlaqge( m, n, a, lda, r, c, rowcnd, colcnd, amax,equed ) !! ZLAQGE equilibrates a general M by N matrix A using the row and !! column scaling factors in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: lda, m, n real(dp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(in) :: c(*), r(*) 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 ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*a( i, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = 1, m a( i, j ) = r( i )*a( i, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*r( i )*a( i, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_zlaqge #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$laqge( m, n, a, lda, r, c, rowcnd, colcnd, amax,equed ) !! ZLAQGE: equilibrates a general M by N matrix A using the row and !! column scaling factors in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: lda, m, n real(${ck}$), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(${ck}$), intent(in) :: c(*), r(*) 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 ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*a( i, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = 1, m a( i, j ) = r( i )*a( i, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = 1, m a( i, j ) = cj*r( i )*a( i, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_${ci}$laqge #:endif #:endfor pure module subroutine stdlib${ii}$_slaswp( n, a, lda, k1, k2, ipiv, incx ) !! SLASWP performs a series of row interchanges on the matrix A. !! One row interchange is initiated for each of rows K1 through K2 of A. ! -- 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 integer(${ik}$), intent(in) :: incx, k1, k2, lda, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, i1, i2, inc, ip, ix, ix0, j, k, n32 real(sp) :: temp ! Executable Statements ! interchange row i with row ipiv(k1+(i-k1)*abs(incx)) for each of rows ! k1 through k2. if( incx>0_${ik}$ ) then ix0 = k1 i1 = k1 i2 = k2 inc = 1_${ik}$ else if( incx<0_${ik}$ ) then ix0 = k1 + ( k1-k2 )*incx i1 = k2 i2 = k1 inc = -1_${ik}$ else return end if n32 = ( n / 32_${ik}$ )*32_${ik}$ if( n32/=0_${ik}$ ) then do j = 1, n32, 32 ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = j, j + 31 temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end do end if if( n32/=n ) then n32 = n32 + 1_${ik}$ ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = n32, n temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end if return end subroutine stdlib${ii}$_slaswp pure module subroutine stdlib${ii}$_dlaswp( n, a, lda, k1, k2, ipiv, incx ) !! DLASWP performs a series of row interchanges on the matrix A. !! One row interchange is initiated for each of rows K1 through K2 of A. ! -- 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 integer(${ik}$), intent(in) :: incx, k1, k2, lda, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, i1, i2, inc, ip, ix, ix0, j, k, n32 real(dp) :: temp ! Executable Statements ! interchange row i with row ipiv(k1+(i-k1)*abs(incx)) for each of rows ! k1 through k2. if( incx>0_${ik}$ ) then ix0 = k1 i1 = k1 i2 = k2 inc = 1_${ik}$ else if( incx<0_${ik}$ ) then ix0 = k1 + ( k1-k2 )*incx i1 = k2 i2 = k1 inc = -1_${ik}$ else return end if n32 = ( n / 32_${ik}$ )*32_${ik}$ if( n32/=0_${ik}$ ) then do j = 1, n32, 32 ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = j, j + 31 temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end do end if if( n32/=n ) then n32 = n32 + 1_${ik}$ ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = n32, n temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end if return end subroutine stdlib${ii}$_dlaswp #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$laswp( n, a, lda, k1, k2, ipiv, incx ) !! DLASWP: performs a series of row interchanges on the matrix A. !! One row interchange is initiated for each of rows K1 through K2 of A. ! -- 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 integer(${ik}$), intent(in) :: incx, k1, k2, lda, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, i1, i2, inc, ip, ix, ix0, j, k, n32 real(${rk}$) :: temp ! Executable Statements ! interchange row i with row ipiv(k1+(i-k1)*abs(incx)) for each of rows ! k1 through k2. if( incx>0_${ik}$ ) then ix0 = k1 i1 = k1 i2 = k2 inc = 1_${ik}$ else if( incx<0_${ik}$ ) then ix0 = k1 + ( k1-k2 )*incx i1 = k2 i2 = k1 inc = -1_${ik}$ else return end if n32 = ( n / 32_${ik}$ )*32_${ik}$ if( n32/=0_${ik}$ ) then do j = 1, n32, 32 ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = j, j + 31 temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end do end if if( n32/=n ) then n32 = n32 + 1_${ik}$ ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = n32, n temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end if return end subroutine stdlib${ii}$_${ri}$laswp #:endif #:endfor pure module subroutine stdlib${ii}$_claswp( n, a, lda, k1, k2, ipiv, incx ) !! CLASWP performs a series of row interchanges on the matrix A. !! One row interchange is initiated for each of rows K1 through K2 of A. ! -- 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 integer(${ik}$), intent(in) :: incx, k1, k2, lda, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, i1, i2, inc, ip, ix, ix0, j, k, n32 complex(sp) :: temp ! Executable Statements ! interchange row i with row ipiv(k1+(i-k1)*abs(incx)) for each of rows ! k1 through k2. if( incx>0_${ik}$ ) then ix0 = k1 i1 = k1 i2 = k2 inc = 1_${ik}$ else if( incx<0_${ik}$ ) then ix0 = k1 + ( k1-k2 )*incx i1 = k2 i2 = k1 inc = -1_${ik}$ else return end if n32 = ( n / 32_${ik}$ )*32_${ik}$ if( n32/=0_${ik}$ ) then do j = 1, n32, 32 ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = j, j + 31 temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end do end if if( n32/=n ) then n32 = n32 + 1_${ik}$ ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = n32, n temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end if return end subroutine stdlib${ii}$_claswp pure module subroutine stdlib${ii}$_zlaswp( n, a, lda, k1, k2, ipiv, incx ) !! ZLASWP performs a series of row interchanges on the matrix A. !! One row interchange is initiated for each of rows K1 through K2 of A. ! -- 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 integer(${ik}$), intent(in) :: incx, k1, k2, lda, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, i1, i2, inc, ip, ix, ix0, j, k, n32 complex(dp) :: temp ! Executable Statements ! interchange row i with row ipiv(k1+(i-k1)*abs(incx)) for each of rows ! k1 through k2. if( incx>0_${ik}$ ) then ix0 = k1 i1 = k1 i2 = k2 inc = 1_${ik}$ else if( incx<0_${ik}$ ) then ix0 = k1 + ( k1-k2 )*incx i1 = k2 i2 = k1 inc = -1_${ik}$ else return end if n32 = ( n / 32_${ik}$ )*32_${ik}$ if( n32/=0_${ik}$ ) then do j = 1, n32, 32 ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = j, j + 31 temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end do end if if( n32/=n ) then n32 = n32 + 1_${ik}$ ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = n32, n temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end if return end subroutine stdlib${ii}$_zlaswp #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$laswp( n, a, lda, k1, k2, ipiv, incx ) !! ZLASWP: performs a series of row interchanges on the matrix A. !! One row interchange is initiated for each of rows K1 through K2 of A. ! -- 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 integer(${ik}$), intent(in) :: incx, k1, k2, lda, n ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, i1, i2, inc, ip, ix, ix0, j, k, n32 complex(${ck}$) :: temp ! Executable Statements ! interchange row i with row ipiv(k1+(i-k1)*abs(incx)) for each of rows ! k1 through k2. if( incx>0_${ik}$ ) then ix0 = k1 i1 = k1 i2 = k2 inc = 1_${ik}$ else if( incx<0_${ik}$ ) then ix0 = k1 + ( k1-k2 )*incx i1 = k2 i2 = k1 inc = -1_${ik}$ else return end if n32 = ( n / 32_${ik}$ )*32_${ik}$ if( n32/=0_${ik}$ ) then do j = 1, n32, 32 ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = j, j + 31 temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end do end if if( n32/=n ) then n32 = n32 + 1_${ik}$ ix = ix0 do i = i1, i2, inc ip = ipiv( ix ) if( ip/=i ) then do k = n32, n temp = a( i, k ) a( i, k ) = a( ip, k ) a( ip, k ) = temp end do end if ix = ix + incx end do end if return end subroutine stdlib${ii}$_${ci}$laswp #:endif #:endfor pure module subroutine stdlib${ii}$_sgetc2( n, a, lda, ipiv, jpiv, info ) !! SGETC2 computes an LU factorization with complete pivoting of the !! n-by-n matrix A. The factorization has the form A = P * L * U * Q, !! where P and Q are permutation matrices, L is lower triangular with !! unit diagonal elements and U is upper triangular. !! This is the Level 2 BLAS algorithm. ! -- 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*), jpiv(*) real(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, ipv, j, jp, jpv real(sp) :: bignum, eps, smin, smlnum, xmax ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ ! quick return if possible if( n==0 )return ! set constants to control overflow eps = stdlib${ii}$_slamch( 'P' ) smlnum = stdlib${ii}$_slamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_slabad( smlnum, bignum ) ! handle the case n=1 by itself if( n==1_${ik}$ ) then ipiv( 1_${ik}$ ) = 1_${ik}$ jpiv( 1_${ik}$ ) = 1_${ik}$ if( abs( a( 1_${ik}$, 1_${ik}$ ) )<smlnum ) then info = 1_${ik}$ a( 1_${ik}$, 1_${ik}$ ) = smlnum end if return end if ! factorize a using complete pivoting. ! set pivots less than smin to smin. loop_40: do i = 1, n - 1 ! find max element in matrix a xmax = zero do ip = i, n do jp = i, n if( abs( a( ip, jp ) )>=xmax ) then xmax = abs( a( ip, jp ) ) ipv = ip jpv = jp end if end do end do if( i==1_${ik}$ )smin = max( eps*xmax, smlnum ) ! swap rows if( ipv/=i )call stdlib${ii}$_sswap( n, a( ipv, 1_${ik}$ ), lda, a( i, 1_${ik}$ ), lda ) ipiv( i ) = ipv ! swap columns if( jpv/=i )call stdlib${ii}$_sswap( n, a( 1_${ik}$, jpv ), 1_${ik}$, a( 1_${ik}$, i ), 1_${ik}$ ) jpiv( i ) = jpv ! check for singularity if( abs( a( i, i ) )<smin ) then info = i a( i, i ) = smin end if do j = i + 1, n a( j, i ) = a( j, i ) / a( i, i ) end do call stdlib${ii}$_sger( n-i, n-i, -one, a( i+1, i ), 1_${ik}$, a( i, i+1 ), lda,a( i+1, i+1 ), & lda ) end do loop_40 if( abs( a( n, n ) )<smin ) then info = n a( n, n ) = smin end if ! set last pivots to n ipiv( n ) = n jpiv( n ) = n return end subroutine stdlib${ii}$_sgetc2 pure module subroutine stdlib${ii}$_dgetc2( n, a, lda, ipiv, jpiv, info ) !! DGETC2 computes an LU factorization with complete pivoting of the !! n-by-n matrix A. The factorization has the form A = P * L * U * Q, !! where P and Q are permutation matrices, L is lower triangular with !! unit diagonal elements and U is upper triangular. !! This is the Level 2 BLAS algorithm. ! -- 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*), jpiv(*) real(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, ipv, j, jp, jpv real(dp) :: bignum, eps, smin, smlnum, xmax ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ ! quick return if possible if( n==0 )return ! set constants to control overflow eps = stdlib${ii}$_dlamch( 'P' ) smlnum = stdlib${ii}$_dlamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_dlabad( smlnum, bignum ) ! handle the case n=1 by itself if( n==1_${ik}$ ) then ipiv( 1_${ik}$ ) = 1_${ik}$ jpiv( 1_${ik}$ ) = 1_${ik}$ if( abs( a( 1_${ik}$, 1_${ik}$ ) )<smlnum ) then info = 1_${ik}$ a( 1_${ik}$, 1_${ik}$ ) = smlnum end if return end if ! factorize a using complete pivoting. ! set pivots less than smin to smin. loop_40: do i = 1, n - 1 ! find max element in matrix a xmax = zero do ip = i, n do jp = i, n if( abs( a( ip, jp ) )>=xmax ) then xmax = abs( a( ip, jp ) ) ipv = ip jpv = jp end if end do end do if( i==1_${ik}$ )smin = max( eps*xmax, smlnum ) ! swap rows if( ipv/=i )call stdlib${ii}$_dswap( n, a( ipv, 1_${ik}$ ), lda, a( i, 1_${ik}$ ), lda ) ipiv( i ) = ipv ! swap columns if( jpv/=i )call stdlib${ii}$_dswap( n, a( 1_${ik}$, jpv ), 1_${ik}$, a( 1_${ik}$, i ), 1_${ik}$ ) jpiv( i ) = jpv ! check for singularity if( abs( a( i, i ) )<smin ) then info = i a( i, i ) = smin end if do j = i + 1, n a( j, i ) = a( j, i ) / a( i, i ) end do call stdlib${ii}$_dger( n-i, n-i, -one, a( i+1, i ), 1_${ik}$, a( i, i+1 ), lda,a( i+1, i+1 ), & lda ) end do loop_40 if( abs( a( n, n ) )<smin ) then info = n a( n, n ) = smin end if ! set last pivots to n ipiv( n ) = n jpiv( n ) = n return end subroutine stdlib${ii}$_dgetc2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$getc2( n, a, lda, ipiv, jpiv, info ) !! DGETC2: computes an LU factorization with complete pivoting of the !! n-by-n matrix A. The factorization has the form A = P * L * U * Q, !! where P and Q are permutation matrices, L is lower triangular with !! unit diagonal elements and U is upper triangular. !! This is the Level 2 BLAS algorithm. ! -- 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*), jpiv(*) real(${rk}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, ipv, j, jp, jpv real(${rk}$) :: bignum, eps, smin, smlnum, xmax ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ ! quick return if possible if( n==0 )return ! set constants to control overflow eps = stdlib${ii}$_${ri}$lamch( 'P' ) smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_${ri}$labad( smlnum, bignum ) ! handle the case n=1 by itself if( n==1_${ik}$ ) then ipiv( 1_${ik}$ ) = 1_${ik}$ jpiv( 1_${ik}$ ) = 1_${ik}$ if( abs( a( 1_${ik}$, 1_${ik}$ ) )<smlnum ) then info = 1_${ik}$ a( 1_${ik}$, 1_${ik}$ ) = smlnum end if return end if ! factorize a using complete pivoting. ! set pivots less than smin to smin. loop_40: do i = 1, n - 1 ! find max element in matrix a xmax = zero do ip = i, n do jp = i, n if( abs( a( ip, jp ) )>=xmax ) then xmax = abs( a( ip, jp ) ) ipv = ip jpv = jp end if end do end do if( i==1_${ik}$ )smin = max( eps*xmax, smlnum ) ! swap rows if( ipv/=i )call stdlib${ii}$_${ri}$swap( n, a( ipv, 1_${ik}$ ), lda, a( i, 1_${ik}$ ), lda ) ipiv( i ) = ipv ! swap columns if( jpv/=i )call stdlib${ii}$_${ri}$swap( n, a( 1_${ik}$, jpv ), 1_${ik}$, a( 1_${ik}$, i ), 1_${ik}$ ) jpiv( i ) = jpv ! check for singularity if( abs( a( i, i ) )<smin ) then info = i a( i, i ) = smin end if do j = i + 1, n a( j, i ) = a( j, i ) / a( i, i ) end do call stdlib${ii}$_${ri}$ger( n-i, n-i, -one, a( i+1, i ), 1_${ik}$, a( i, i+1 ), lda,a( i+1, i+1 ), & lda ) end do loop_40 if( abs( a( n, n ) )<smin ) then info = n a( n, n ) = smin end if ! set last pivots to n ipiv( n ) = n jpiv( n ) = n return end subroutine stdlib${ii}$_${ri}$getc2 #:endif #:endfor pure module subroutine stdlib${ii}$_cgetc2( n, a, lda, ipiv, jpiv, info ) !! CGETC2 computes an LU factorization, using complete pivoting, of the !! n-by-n matrix A. The factorization has the form A = P * L * U * Q, !! where P and Q are permutation matrices, L is lower triangular with !! unit diagonal elements and U is upper triangular. !! This is a level 1 BLAS version of the algorithm. ! -- 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*), jpiv(*) complex(sp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, ipv, j, jp, jpv real(sp) :: bignum, eps, smin, smlnum, xmax ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ ! quick return if possible if( n==0 )return ! set constants to control overflow eps = stdlib${ii}$_slamch( 'P' ) smlnum = stdlib${ii}$_slamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_slabad( smlnum, bignum ) ! handle the case n=1 by itself if( n==1_${ik}$ ) then ipiv( 1_${ik}$ ) = 1_${ik}$ jpiv( 1_${ik}$ ) = 1_${ik}$ if( abs( a( 1_${ik}$, 1_${ik}$ ) )<smlnum ) then info = 1_${ik}$ a( 1_${ik}$, 1_${ik}$ ) = cmplx( smlnum, zero,KIND=sp) end if return end if ! factorize a using complete pivoting. ! set pivots less than smin to smin loop_40: do i = 1, n - 1 ! find max element in matrix a xmax = zero do ip = i, n do jp = i, n if( abs( a( ip, jp ) )>=xmax ) then xmax = abs( a( ip, jp ) ) ipv = ip jpv = jp end if end do end do if( i==1_${ik}$ )smin = max( eps*xmax, smlnum ) ! swap rows if( ipv/=i )call stdlib${ii}$_cswap( n, a( ipv, 1_${ik}$ ), lda, a( i, 1_${ik}$ ), lda ) ipiv( i ) = ipv ! swap columns if( jpv/=i )call stdlib${ii}$_cswap( n, a( 1_${ik}$, jpv ), 1_${ik}$, a( 1_${ik}$, i ), 1_${ik}$ ) jpiv( i ) = jpv ! check for singularity if( abs( a( i, i ) )<smin ) then info = i a( i, i ) = cmplx( smin, zero,KIND=sp) end if do j = i + 1, n a( j, i ) = a( j, i ) / a( i, i ) end do call stdlib${ii}$_cgeru( n-i, n-i, -cmplx( one,KIND=sp), a( i+1, i ), 1_${ik}$,a( i, i+1 ), lda, & a( i+1, i+1 ), lda ) end do loop_40 if( abs( a( n, n ) )<smin ) then info = n a( n, n ) = cmplx( smin, zero,KIND=sp) end if ! set last pivots to n ipiv( n ) = n jpiv( n ) = n return end subroutine stdlib${ii}$_cgetc2 pure module subroutine stdlib${ii}$_zgetc2( n, a, lda, ipiv, jpiv, info ) !! ZGETC2 computes an LU factorization, using complete pivoting, of the !! n-by-n matrix A. The factorization has the form A = P * L * U * Q, !! where P and Q are permutation matrices, L is lower triangular with !! unit diagonal elements and U is upper triangular. !! This is a level 1 BLAS version of the algorithm. ! -- 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*), jpiv(*) complex(dp), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, ipv, j, jp, jpv real(dp) :: bignum, eps, smin, smlnum, xmax ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ ! quick return if possible if( n==0 )return ! set constants to control overflow eps = stdlib${ii}$_dlamch( 'P' ) smlnum = stdlib${ii}$_dlamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_dlabad( smlnum, bignum ) ! handle the case n=1 by itself if( n==1_${ik}$ ) then ipiv( 1_${ik}$ ) = 1_${ik}$ jpiv( 1_${ik}$ ) = 1_${ik}$ if( abs( a( 1_${ik}$, 1_${ik}$ ) )<smlnum ) then info = 1_${ik}$ a( 1_${ik}$, 1_${ik}$ ) = cmplx( smlnum, zero,KIND=dp) end if return end if ! factorize a using complete pivoting. ! set pivots less than smin to smin loop_40: do i = 1, n - 1 ! find max element in matrix a xmax = zero do ip = i, n do jp = i, n if( abs( a( ip, jp ) )>=xmax ) then xmax = abs( a( ip, jp ) ) ipv = ip jpv = jp end if end do end do if( i==1_${ik}$ )smin = max( eps*xmax, smlnum ) ! swap rows if( ipv/=i )call stdlib${ii}$_zswap( n, a( ipv, 1_${ik}$ ), lda, a( i, 1_${ik}$ ), lda ) ipiv( i ) = ipv ! swap columns if( jpv/=i )call stdlib${ii}$_zswap( n, a( 1_${ik}$, jpv ), 1_${ik}$, a( 1_${ik}$, i ), 1_${ik}$ ) jpiv( i ) = jpv ! check for singularity if( abs( a( i, i ) )<smin ) then info = i a( i, i ) = cmplx( smin, zero,KIND=dp) end if do j = i + 1, n a( j, i ) = a( j, i ) / a( i, i ) end do call stdlib${ii}$_zgeru( n-i, n-i, -cmplx( one,KIND=dp), a( i+1, i ), 1_${ik}$,a( i, i+1 ), lda, & a( i+1, i+1 ), lda ) end do loop_40 if( abs( a( n, n ) )<smin ) then info = n a( n, n ) = cmplx( smin, zero,KIND=dp) end if ! set last pivots to n ipiv( n ) = n jpiv( n ) = n return end subroutine stdlib${ii}$_zgetc2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$getc2( n, a, lda, ipiv, jpiv, info ) !! ZGETC2: computes an LU factorization, using complete pivoting, of the !! n-by-n matrix A. The factorization has the form A = P * L * U * Q, !! where P and Q are permutation matrices, L is lower triangular with !! unit diagonal elements and U is upper triangular. !! This is a level 1 BLAS version of the algorithm. ! -- 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: lda, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*), jpiv(*) complex(${ck}$), intent(inout) :: a(lda,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, ipv, j, jp, jpv real(${ck}$) :: bignum, eps, smin, smlnum, xmax ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ ! quick return if possible if( n==0 )return ! set constants to control overflow eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'P' ) smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_${c2ri(ci)}$labad( smlnum, bignum ) ! handle the case n=1 by itself if( n==1_${ik}$ ) then ipiv( 1_${ik}$ ) = 1_${ik}$ jpiv( 1_${ik}$ ) = 1_${ik}$ if( abs( a( 1_${ik}$, 1_${ik}$ ) )<smlnum ) then info = 1_${ik}$ a( 1_${ik}$, 1_${ik}$ ) = cmplx( smlnum, zero,KIND=${ck}$) end if return end if ! factorize a using complete pivoting. ! set pivots less than smin to smin loop_40: do i = 1, n - 1 ! find max element in matrix a xmax = zero do ip = i, n do jp = i, n if( abs( a( ip, jp ) )>=xmax ) then xmax = abs( a( ip, jp ) ) ipv = ip jpv = jp end if end do end do if( i==1_${ik}$ )smin = max( eps*xmax, smlnum ) ! swap rows if( ipv/=i )call stdlib${ii}$_${ci}$swap( n, a( ipv, 1_${ik}$ ), lda, a( i, 1_${ik}$ ), lda ) ipiv( i ) = ipv ! swap columns if( jpv/=i )call stdlib${ii}$_${ci}$swap( n, a( 1_${ik}$, jpv ), 1_${ik}$, a( 1_${ik}$, i ), 1_${ik}$ ) jpiv( i ) = jpv ! check for singularity if( abs( a( i, i ) )<smin ) then info = i a( i, i ) = cmplx( smin, zero,KIND=${ck}$) end if do j = i + 1, n a( j, i ) = a( j, i ) / a( i, i ) end do call stdlib${ii}$_${ci}$geru( n-i, n-i, -cmplx( one,KIND=${ck}$), a( i+1, i ), 1_${ik}$,a( i, i+1 ), lda, & a( i+1, i+1 ), lda ) end do loop_40 if( abs( a( n, n ) )<smin ) then info = n a( n, n ) = cmplx( smin, zero,KIND=${ck}$) end if ! set last pivots to n ipiv( n ) = n jpiv( n ) = n return end subroutine stdlib${ii}$_${ci}$getc2 #:endif #:endfor pure module subroutine stdlib${ii}$_sgesc2( n, a, lda, rhs, ipiv, jpiv, scale ) !! SGESC2 solves a system of linear equations !! A * X = scale* RHS !! with a general N-by-N matrix A using the LU factorization with !! complete pivoting computed by SGETC2. ! -- 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 integer(${ik}$), intent(in) :: lda, n real(sp), intent(out) :: scale ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) real(sp), intent(in) :: a(lda,*) real(sp), intent(inout) :: rhs(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(sp) :: bignum, eps, smlnum, temp ! Intrinsic Functions ! Executable Statements ! set constant to control overflow eps = stdlib${ii}$_slamch( 'P' ) smlnum = stdlib${ii}$_slamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_slabad( smlnum, bignum ) ! apply permutations ipiv to rhs call stdlib${ii}$_slaswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l part do i = 1, n - 1 do j = i + 1, n rhs( j ) = rhs( j ) - a( j, i )*rhs( i ) end do end do ! solve for u part scale = one ! check for scaling i = stdlib${ii}$_isamax( n, rhs, 1_${ik}$ ) if( two*smlnum*abs( rhs( i ) )>abs( a( n, n ) ) ) then temp = ( one / two ) / abs( rhs( i ) ) call stdlib${ii}$_sscal( n, temp, rhs( 1_${ik}$ ), 1_${ik}$ ) scale = scale*temp end if do i = n, 1, -1 temp = one / a( i, i ) rhs( i ) = rhs( i )*temp do j = i + 1, n rhs( i ) = rhs( i ) - rhs( j )*( a( i, j )*temp ) end do end do ! apply permutations jpiv to the solution (rhs) call stdlib${ii}$_slaswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) return end subroutine stdlib${ii}$_sgesc2 pure module subroutine stdlib${ii}$_dgesc2( n, a, lda, rhs, ipiv, jpiv, scale ) !! DGESC2 solves a system of linear equations !! A * X = scale* RHS !! with a general N-by-N matrix A using the LU factorization with !! complete pivoting computed by DGETC2. ! -- 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 integer(${ik}$), intent(in) :: lda, n real(dp), intent(out) :: scale ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) real(dp), intent(in) :: a(lda,*) real(dp), intent(inout) :: rhs(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(dp) :: bignum, eps, smlnum, temp ! Intrinsic Functions ! Executable Statements ! set constant to control overflow eps = stdlib${ii}$_dlamch( 'P' ) smlnum = stdlib${ii}$_dlamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_dlabad( smlnum, bignum ) ! apply permutations ipiv to rhs call stdlib${ii}$_dlaswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l part do i = 1, n - 1 do j = i + 1, n rhs( j ) = rhs( j ) - a( j, i )*rhs( i ) end do end do ! solve for u part scale = one ! check for scaling i = stdlib${ii}$_idamax( n, rhs, 1_${ik}$ ) if( two*smlnum*abs( rhs( i ) )>abs( a( n, n ) ) ) then temp = ( one / two ) / abs( rhs( i ) ) call stdlib${ii}$_dscal( n, temp, rhs( 1_${ik}$ ), 1_${ik}$ ) scale = scale*temp end if do i = n, 1, -1 temp = one / a( i, i ) rhs( i ) = rhs( i )*temp do j = i + 1, n rhs( i ) = rhs( i ) - rhs( j )*( a( i, j )*temp ) end do end do ! apply permutations jpiv to the solution (rhs) call stdlib${ii}$_dlaswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) return end subroutine stdlib${ii}$_dgesc2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gesc2( n, a, lda, rhs, ipiv, jpiv, scale ) !! DGESC2: solves a system of linear equations !! A * X = scale* RHS !! with a general N-by-N matrix A using the LU factorization with !! complete pivoting computed by DGETC2. ! -- 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 integer(${ik}$), intent(in) :: lda, n real(${rk}$), intent(out) :: scale ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) real(${rk}$), intent(in) :: a(lda,*) real(${rk}$), intent(inout) :: rhs(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(${rk}$) :: bignum, eps, smlnum, temp ! Intrinsic Functions ! Executable Statements ! set constant to control overflow eps = stdlib${ii}$_${ri}$lamch( 'P' ) smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_${ri}$labad( smlnum, bignum ) ! apply permutations ipiv to rhs call stdlib${ii}$_${ri}$laswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l part do i = 1, n - 1 do j = i + 1, n rhs( j ) = rhs( j ) - a( j, i )*rhs( i ) end do end do ! solve for u part scale = one ! check for scaling i = stdlib${ii}$_i${ri}$amax( n, rhs, 1_${ik}$ ) if( two*smlnum*abs( rhs( i ) )>abs( a( n, n ) ) ) then temp = ( one / two ) / abs( rhs( i ) ) call stdlib${ii}$_${ri}$scal( n, temp, rhs( 1_${ik}$ ), 1_${ik}$ ) scale = scale*temp end if do i = n, 1, -1 temp = one / a( i, i ) rhs( i ) = rhs( i )*temp do j = i + 1, n rhs( i ) = rhs( i ) - rhs( j )*( a( i, j )*temp ) end do end do ! apply permutations jpiv to the solution (rhs) call stdlib${ii}$_${ri}$laswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) return end subroutine stdlib${ii}$_${ri}$gesc2 #:endif #:endfor pure module subroutine stdlib${ii}$_cgesc2( n, a, lda, rhs, ipiv, jpiv, scale ) !! CGESC2 solves a system of linear equations !! A * X = scale* RHS !! with a general N-by-N matrix A using the LU factorization with !! complete pivoting computed by CGETC2. ! -- 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 integer(${ik}$), intent(in) :: lda, n real(sp), intent(out) :: scale ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) complex(sp), intent(in) :: a(lda,*) complex(sp), intent(inout) :: rhs(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(sp) :: bignum, eps, smlnum complex(sp) :: temp ! Intrinsic Functions ! Executable Statements ! set constant to control overflow eps = stdlib${ii}$_slamch( 'P' ) smlnum = stdlib${ii}$_slamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_slabad( smlnum, bignum ) ! apply permutations ipiv to rhs call stdlib${ii}$_claswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l part do i = 1, n - 1 do j = i + 1, n rhs( j ) = rhs( j ) - a( j, i )*rhs( i ) end do end do ! solve for u part scale = one ! check for scaling i = stdlib${ii}$_icamax( n, rhs, 1_${ik}$ ) if( two*smlnum*abs( rhs( i ) )>abs( a( n, n ) ) ) then temp = cmplx( one / two, zero,KIND=sp) / abs( rhs( i ) ) call stdlib${ii}$_cscal( n, temp, rhs( 1_${ik}$ ), 1_${ik}$ ) scale = scale*real( temp,KIND=sp) end if do i = n, 1, -1 temp = cmplx( one, zero,KIND=sp) / a( i, i ) rhs( i ) = rhs( i )*temp do j = i + 1, n rhs( i ) = rhs( i ) - rhs( j )*( a( i, j )*temp ) end do end do ! apply permutations jpiv to the solution (rhs) call stdlib${ii}$_claswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) return end subroutine stdlib${ii}$_cgesc2 pure module subroutine stdlib${ii}$_zgesc2( n, a, lda, rhs, ipiv, jpiv, scale ) !! ZGESC2 solves a system of linear equations !! A * X = scale* RHS !! with a general N-by-N matrix A using the LU factorization with !! complete pivoting computed by ZGETC2. ! -- 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 integer(${ik}$), intent(in) :: lda, n real(dp), intent(out) :: scale ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) complex(dp), intent(in) :: a(lda,*) complex(dp), intent(inout) :: rhs(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(dp) :: bignum, eps, smlnum complex(dp) :: temp ! Intrinsic Functions ! Executable Statements ! set constant to control overflow eps = stdlib${ii}$_dlamch( 'P' ) smlnum = stdlib${ii}$_dlamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_dlabad( smlnum, bignum ) ! apply permutations ipiv to rhs call stdlib${ii}$_zlaswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l part do i = 1, n - 1 do j = i + 1, n rhs( j ) = rhs( j ) - a( j, i )*rhs( i ) end do end do ! solve for u part scale = one ! check for scaling i = stdlib${ii}$_izamax( n, rhs, 1_${ik}$ ) if( two*smlnum*abs( rhs( i ) )>abs( a( n, n ) ) ) then temp = cmplx( one / two, zero,KIND=dp) / abs( rhs( i ) ) call stdlib${ii}$_zscal( n, temp, rhs( 1_${ik}$ ), 1_${ik}$ ) scale = scale*real( temp,KIND=dp) end if do i = n, 1, -1 temp = cmplx( one, zero,KIND=dp) / a( i, i ) rhs( i ) = rhs( i )*temp do j = i + 1, n rhs( i ) = rhs( i ) - rhs( j )*( a( i, j )*temp ) end do end do ! apply permutations jpiv to the solution (rhs) call stdlib${ii}$_zlaswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) return end subroutine stdlib${ii}$_zgesc2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gesc2( n, a, lda, rhs, ipiv, jpiv, scale ) !! ZGESC2: solves a system of linear equations !! A * X = scale* RHS !! with a general N-by-N matrix A using the LU factorization with !! complete pivoting computed by ZGETC2. ! -- 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 integer(${ik}$), intent(in) :: lda, n real(${ck}$), intent(out) :: scale ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) complex(${ck}$), intent(in) :: a(lda,*) complex(${ck}$), intent(inout) :: rhs(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j real(${ck}$) :: bignum, eps, smlnum complex(${ck}$) :: temp ! Intrinsic Functions ! Executable Statements ! set constant to control overflow eps = stdlib${ii}$_${c2ri(ci)}$lamch( 'P' ) smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) / eps bignum = one / smlnum call stdlib${ii}$_${c2ri(ci)}$labad( smlnum, bignum ) ! apply permutations ipiv to rhs call stdlib${ii}$_${ci}$laswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l part do i = 1, n - 1 do j = i + 1, n rhs( j ) = rhs( j ) - a( j, i )*rhs( i ) end do end do ! solve for u part scale = one ! check for scaling i = stdlib${ii}$_i${ci}$amax( n, rhs, 1_${ik}$ ) if( two*smlnum*abs( rhs( i ) )>abs( a( n, n ) ) ) then temp = cmplx( one / two, zero,KIND=${ck}$) / abs( rhs( i ) ) call stdlib${ii}$_${ci}$scal( n, temp, rhs( 1_${ik}$ ), 1_${ik}$ ) scale = scale*real( temp,KIND=${ck}$) end if do i = n, 1, -1 temp = cmplx( one, zero,KIND=${ck}$) / a( i, i ) rhs( i ) = rhs( i )*temp do j = i + 1, n rhs( i ) = rhs( i ) - rhs( j )*( a( i, j )*temp ) end do end do ! apply permutations jpiv to the solution (rhs) call stdlib${ii}$_${ci}$laswp( 1_${ik}$, rhs, lda, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) return end subroutine stdlib${ii}$_${ci}$gesc2 #:endif #:endfor pure module subroutine stdlib${ii}$_slatdf( ijob, n, z, ldz, rhs, rdsum, rdscal, ipiv,jpiv ) !! SLATDF uses the LU factorization of the n-by-n matrix Z computed by !! SGETC2 and computes a contribution to the reciprocal Dif-estimate !! by solving Z * x = b for x, and choosing the r.h.s. b such that !! the norm of x is as large as possible. On entry RHS = b holds the !! contribution from earlier solved sub-systems, and on return RHS = x. !! The factorization of Z returned by SGETC2 has the form Z = P*L*U*Q, !! where P and Q are permutation matrices. L is lower triangular with !! unit diagonal elements and U is upper triangular. ! -- 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 integer(${ik}$), intent(in) :: ijob, ldz, n real(sp), intent(inout) :: rdscal, rdsum ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) real(sp), intent(inout) :: rhs(*), z(ldz,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: maxdim = 8_${ik}$ ! Local Scalars integer(${ik}$) :: i, info, j, k real(sp) :: bm, bp, pmone, sminu, splus, temp ! Local Arrays integer(${ik}$) :: iwork(maxdim) real(sp) :: work(4_${ik}$*maxdim), xm(maxdim), xp(maxdim) ! Intrinsic Functions ! Executable Statements if( ijob/=2_${ik}$ ) then ! apply permutations ipiv to rhs call stdlib${ii}$_slaswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l-part choosing rhs either to +1 or -1. pmone = -one loop_10: do j = 1, n - 1 bp = rhs( j ) + one bm = rhs( j ) - one splus = one ! look-ahead for l-part rhs(1:n-1) = + or -1, splus and ! smin computed more efficiently than in bsolve [1]. splus = splus + stdlib${ii}$_sdot( n-j, z( j+1, j ), 1_${ik}$, z( j+1, j ), 1_${ik}$ ) sminu = stdlib${ii}$_sdot( n-j, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) splus = splus*rhs( j ) if( splus>sminu ) then rhs( j ) = bp else if( sminu>splus ) then rhs( j ) = bm else ! in this case the updating sums are equal and we can ! choose rhs(j) +1 or -1. the first time this happens ! we choose -1, thereafter +1. this is a simple way to ! get good estimates of matrices like byers well-known ! example (see [1]). (not done in bsolve.) rhs( j ) = rhs( j ) + pmone pmone = one end if ! compute the remaining r.h.s. temp = -rhs( j ) call stdlib${ii}$_saxpy( n-j, temp, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) end do loop_10 ! solve for u-part, look-ahead for rhs(n) = +-1. this is not done ! in bsolve and will hopefully give us a better estimate because ! any ill-conditioning of the original matrix is transferred to u ! and not to l. u(n, n) is an approximation to sigma_min(lu). call stdlib${ii}$_scopy( n-1, rhs, 1_${ik}$, xp, 1_${ik}$ ) xp( n ) = rhs( n ) + one rhs( n ) = rhs( n ) - one splus = zero sminu = zero do i = n, 1, -1 temp = one / z( i, i ) xp( i ) = xp( i )*temp rhs( i ) = rhs( i )*temp do k = i + 1, n xp( i ) = xp( i ) - xp( k )*( z( i, k )*temp ) rhs( i ) = rhs( i ) - rhs( k )*( z( i, k )*temp ) end do splus = splus + abs( xp( i ) ) sminu = sminu + abs( rhs( i ) ) end do if( splus>sminu )call stdlib${ii}$_scopy( n, xp, 1_${ik}$, rhs, 1_${ik}$ ) ! apply the permutations jpiv to the computed solution (rhs) call stdlib${ii}$_slaswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_slassq( n, rhs, 1_${ik}$, rdscal, rdsum ) else ! ijob = 2, compute approximate nullvector xm of z call stdlib${ii}$_sgecon( 'I', n, z, ldz, one, temp, work, iwork, info ) call stdlib${ii}$_scopy( n, work( n+1 ), 1_${ik}$, xm, 1_${ik}$ ) ! compute rhs call stdlib${ii}$_slaswp( 1_${ik}$, xm, ldz, 1_${ik}$, n-1, ipiv, -1_${ik}$ ) temp = one / sqrt( stdlib${ii}$_sdot( n, xm, 1_${ik}$, xm, 1_${ik}$ ) ) call stdlib${ii}$_sscal( n, temp, xm, 1_${ik}$ ) call stdlib${ii}$_scopy( n, xm, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_saxpy( n, one, rhs, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_saxpy( n, -one, xm, 1_${ik}$, rhs, 1_${ik}$ ) call stdlib${ii}$_sgesc2( n, z, ldz, rhs, ipiv, jpiv, temp ) call stdlib${ii}$_sgesc2( n, z, ldz, xp, ipiv, jpiv, temp ) if( stdlib${ii}$_sasum( n, xp, 1_${ik}$ )>stdlib${ii}$_sasum( n, rhs, 1_${ik}$ ) )call stdlib${ii}$_scopy( n, xp, 1_${ik}$,& rhs, 1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_slassq( n, rhs, 1_${ik}$, rdscal, rdsum ) end if return end subroutine stdlib${ii}$_slatdf pure module subroutine stdlib${ii}$_dlatdf( ijob, n, z, ldz, rhs, rdsum, rdscal, ipiv,jpiv ) !! DLATDF uses the LU factorization of the n-by-n matrix Z computed by !! DGETC2 and computes a contribution to the reciprocal Dif-estimate !! by solving Z * x = b for x, and choosing the r.h.s. b such that !! the norm of x is as large as possible. On entry RHS = b holds the !! contribution from earlier solved sub-systems, and on return RHS = x. !! The factorization of Z returned by DGETC2 has the form Z = P*L*U*Q, !! where P and Q are permutation matrices. L is lower triangular with !! unit diagonal elements and U is upper triangular. ! -- 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 integer(${ik}$), intent(in) :: ijob, ldz, n real(dp), intent(inout) :: rdscal, rdsum ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) real(dp), intent(inout) :: rhs(*), z(ldz,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: maxdim = 8_${ik}$ ! Local Scalars integer(${ik}$) :: i, info, j, k real(dp) :: bm, bp, pmone, sminu, splus, temp ! Local Arrays integer(${ik}$) :: iwork(maxdim) real(dp) :: work(4_${ik}$*maxdim), xm(maxdim), xp(maxdim) ! Intrinsic Functions ! Executable Statements if( ijob/=2_${ik}$ ) then ! apply permutations ipiv to rhs call stdlib${ii}$_dlaswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l-part choosing rhs either to +1 or -1. pmone = -one loop_10: do j = 1, n - 1 bp = rhs( j ) + one bm = rhs( j ) - one splus = one ! look-ahead for l-part rhs(1:n-1) = + or -1, splus and ! smin computed more efficiently than in bsolve [1]. splus = splus + stdlib${ii}$_ddot( n-j, z( j+1, j ), 1_${ik}$, z( j+1, j ), 1_${ik}$ ) sminu = stdlib${ii}$_ddot( n-j, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) splus = splus*rhs( j ) if( splus>sminu ) then rhs( j ) = bp else if( sminu>splus ) then rhs( j ) = bm else ! in this case the updating sums are equal and we can ! choose rhs(j) +1 or -1. the first time this happens ! we choose -1, thereafter +1. this is a simple way to ! get good estimates of matrices like byers well-known ! example (see [1]). (not done in bsolve.) rhs( j ) = rhs( j ) + pmone pmone = one end if ! compute the remaining r.h.s. temp = -rhs( j ) call stdlib${ii}$_daxpy( n-j, temp, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) end do loop_10 ! solve for u-part, look-ahead for rhs(n) = +-1. this is not done ! in bsolve and will hopefully give us a better estimate because ! any ill-conditioning of the original matrix is transferred to u ! and not to l. u(n, n) is an approximation to sigma_min(lu). call stdlib${ii}$_dcopy( n-1, rhs, 1_${ik}$, xp, 1_${ik}$ ) xp( n ) = rhs( n ) + one rhs( n ) = rhs( n ) - one splus = zero sminu = zero do i = n, 1, -1 temp = one / z( i, i ) xp( i ) = xp( i )*temp rhs( i ) = rhs( i )*temp do k = i + 1, n xp( i ) = xp( i ) - xp( k )*( z( i, k )*temp ) rhs( i ) = rhs( i ) - rhs( k )*( z( i, k )*temp ) end do splus = splus + abs( xp( i ) ) sminu = sminu + abs( rhs( i ) ) end do if( splus>sminu )call stdlib${ii}$_dcopy( n, xp, 1_${ik}$, rhs, 1_${ik}$ ) ! apply the permutations jpiv to the computed solution (rhs) call stdlib${ii}$_dlaswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_dlassq( n, rhs, 1_${ik}$, rdscal, rdsum ) else ! ijob = 2, compute approximate nullvector xm of z call stdlib${ii}$_dgecon( 'I', n, z, ldz, one, temp, work, iwork, info ) call stdlib${ii}$_dcopy( n, work( n+1 ), 1_${ik}$, xm, 1_${ik}$ ) ! compute rhs call stdlib${ii}$_dlaswp( 1_${ik}$, xm, ldz, 1_${ik}$, n-1, ipiv, -1_${ik}$ ) temp = one / sqrt( stdlib${ii}$_ddot( n, xm, 1_${ik}$, xm, 1_${ik}$ ) ) call stdlib${ii}$_dscal( n, temp, xm, 1_${ik}$ ) call stdlib${ii}$_dcopy( n, xm, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_daxpy( n, one, rhs, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_daxpy( n, -one, xm, 1_${ik}$, rhs, 1_${ik}$ ) call stdlib${ii}$_dgesc2( n, z, ldz, rhs, ipiv, jpiv, temp ) call stdlib${ii}$_dgesc2( n, z, ldz, xp, ipiv, jpiv, temp ) if( stdlib${ii}$_dasum( n, xp, 1_${ik}$ )>stdlib${ii}$_dasum( n, rhs, 1_${ik}$ ) )call stdlib${ii}$_dcopy( n, xp, 1_${ik}$,& rhs, 1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_dlassq( n, rhs, 1_${ik}$, rdscal, rdsum ) end if return end subroutine stdlib${ii}$_dlatdf #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$latdf( ijob, n, z, ldz, rhs, rdsum, rdscal, ipiv,jpiv ) !! DLATDF: uses the LU factorization of the n-by-n matrix Z computed by !! DGETC2 and computes a contribution to the reciprocal Dif-estimate !! by solving Z * x = b for x, and choosing the r.h.s. b such that !! the norm of x is as large as possible. On entry RHS = b holds the !! contribution from earlier solved sub-systems, and on return RHS = x. !! The factorization of Z returned by DGETC2 has the form Z = P*L*U*Q, !! where P and Q are permutation matrices. L is lower triangular with !! unit diagonal elements and U is upper triangular. ! -- 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 integer(${ik}$), intent(in) :: ijob, ldz, n real(${rk}$), intent(inout) :: rdscal, rdsum ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) real(${rk}$), intent(inout) :: rhs(*), z(ldz,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: maxdim = 8_${ik}$ ! Local Scalars integer(${ik}$) :: i, info, j, k real(${rk}$) :: bm, bp, pmone, sminu, splus, temp ! Local Arrays integer(${ik}$) :: iwork(maxdim) real(${rk}$) :: work(4_${ik}$*maxdim), xm(maxdim), xp(maxdim) ! Intrinsic Functions ! Executable Statements if( ijob/=2_${ik}$ ) then ! apply permutations ipiv to rhs call stdlib${ii}$_${ri}$laswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l-part choosing rhs either to +1 or -1. pmone = -one loop_10: do j = 1, n - 1 bp = rhs( j ) + one bm = rhs( j ) - one splus = one ! look-ahead for l-part rhs(1:n-1) = + or -1, splus and ! smin computed more efficiently than in bsolve [1]. splus = splus + stdlib${ii}$_${ri}$dot( n-j, z( j+1, j ), 1_${ik}$, z( j+1, j ), 1_${ik}$ ) sminu = stdlib${ii}$_${ri}$dot( n-j, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) splus = splus*rhs( j ) if( splus>sminu ) then rhs( j ) = bp else if( sminu>splus ) then rhs( j ) = bm else ! in this case the updating sums are equal and we can ! choose rhs(j) +1 or -1. the first time this happens ! we choose -1, thereafter +1. this is a simple way to ! get good estimates of matrices like byers well-known ! example (see [1]). (not done in bsolve.) rhs( j ) = rhs( j ) + pmone pmone = one end if ! compute the remaining r.h.s. temp = -rhs( j ) call stdlib${ii}$_${ri}$axpy( n-j, temp, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) end do loop_10 ! solve for u-part, look-ahead for rhs(n) = +-1. this is not done ! in bsolve and will hopefully give us a better estimate because ! any ill-conditioning of the original matrix is transferred to u ! and not to l. u(n, n) is an approximation to sigma_min(lu). call stdlib${ii}$_${ri}$copy( n-1, rhs, 1_${ik}$, xp, 1_${ik}$ ) xp( n ) = rhs( n ) + one rhs( n ) = rhs( n ) - one splus = zero sminu = zero do i = n, 1, -1 temp = one / z( i, i ) xp( i ) = xp( i )*temp rhs( i ) = rhs( i )*temp do k = i + 1, n xp( i ) = xp( i ) - xp( k )*( z( i, k )*temp ) rhs( i ) = rhs( i ) - rhs( k )*( z( i, k )*temp ) end do splus = splus + abs( xp( i ) ) sminu = sminu + abs( rhs( i ) ) end do if( splus>sminu )call stdlib${ii}$_${ri}$copy( n, xp, 1_${ik}$, rhs, 1_${ik}$ ) ! apply the permutations jpiv to the computed solution (rhs) call stdlib${ii}$_${ri}$laswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_${ri}$lassq( n, rhs, 1_${ik}$, rdscal, rdsum ) else ! ijob = 2, compute approximate nullvector xm of z call stdlib${ii}$_${ri}$gecon( 'I', n, z, ldz, one, temp, work, iwork, info ) call stdlib${ii}$_${ri}$copy( n, work( n+1 ), 1_${ik}$, xm, 1_${ik}$ ) ! compute rhs call stdlib${ii}$_${ri}$laswp( 1_${ik}$, xm, ldz, 1_${ik}$, n-1, ipiv, -1_${ik}$ ) temp = one / sqrt( stdlib${ii}$_${ri}$dot( n, xm, 1_${ik}$, xm, 1_${ik}$ ) ) call stdlib${ii}$_${ri}$scal( n, temp, xm, 1_${ik}$ ) call stdlib${ii}$_${ri}$copy( n, xm, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_${ri}$axpy( n, one, rhs, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_${ri}$axpy( n, -one, xm, 1_${ik}$, rhs, 1_${ik}$ ) call stdlib${ii}$_${ri}$gesc2( n, z, ldz, rhs, ipiv, jpiv, temp ) call stdlib${ii}$_${ri}$gesc2( n, z, ldz, xp, ipiv, jpiv, temp ) if( stdlib${ii}$_${ri}$asum( n, xp, 1_${ik}$ )>stdlib${ii}$_${ri}$asum( n, rhs, 1_${ik}$ ) )call stdlib${ii}$_${ri}$copy( n, xp, 1_${ik}$,& rhs, 1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_${ri}$lassq( n, rhs, 1_${ik}$, rdscal, rdsum ) end if return end subroutine stdlib${ii}$_${ri}$latdf #:endif #:endfor pure module subroutine stdlib${ii}$_clatdf( ijob, n, z, ldz, rhs, rdsum, rdscal, ipiv,jpiv ) !! CLATDF computes the contribution to the reciprocal Dif-estimate !! by solving for x in Z * x = b, where b is chosen such that the norm !! of x is as large as possible. It is assumed that LU decomposition !! of Z has been computed by CGETC2. On entry RHS = f holds the !! contribution from earlier solved sub-systems, and on return RHS = x. !! The factorization of Z returned by CGETC2 has the form !! Z = P * L * U * Q, where P and Q are permutation matrices. L is lower !! triangular with unit diagonal elements and U is upper triangular. ! -- 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 integer(${ik}$), intent(in) :: ijob, ldz, n real(sp), intent(inout) :: rdscal, rdsum ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) complex(sp), intent(inout) :: rhs(*), z(ldz,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: maxdim = 2_${ik}$ ! Local Scalars integer(${ik}$) :: i, info, j, k real(sp) :: rtemp, scale, sminu, splus complex(sp) :: bm, bp, pmone, temp ! Local Arrays real(sp) :: rwork(maxdim) complex(sp) :: work(4_${ik}$*maxdim), xm(maxdim), xp(maxdim) ! Intrinsic Functions ! Executable Statements if( ijob/=2_${ik}$ ) then ! apply permutations ipiv to rhs call stdlib${ii}$_claswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l-part choosing rhs either to +1 or -1. pmone = -cone loop_10: do j = 1, n - 1 bp = rhs( j ) + cone bm = rhs( j ) - cone splus = one ! lockahead for l- part rhs(1:n-1) = +-1 ! splus and smin computed more efficiently than in bsolve[1]. splus = splus + real( stdlib${ii}$_cdotc( n-j, z( j+1, j ), 1_${ik}$, z( j+1,j ), 1_${ik}$ ),KIND=sp) sminu = real( stdlib${ii}$_cdotc( n-j, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ),KIND=sp) splus = splus*real( rhs( j ),KIND=sp) if( splus>sminu ) then rhs( j ) = bp else if( sminu>splus ) then rhs( j ) = bm else ! in this case the updating sums are equal and we can ! choose rhs(j) +1 or -1. the first time this happens we ! choose -1, thereafter +1. this is a simple way to get ! good estimates of matrices like byers well-known example ! (see [1]). (not done in bsolve.) rhs( j ) = rhs( j ) + pmone pmone = cone end if ! compute the remaining r.h.s. temp = -rhs( j ) call stdlib${ii}$_caxpy( n-j, temp, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) end do loop_10 ! solve for u- part, lockahead for rhs(n) = +-1. this is not done ! in bsolve and will hopefully give us a better estimate because ! any ill-conditioning of the original matrix is transferred to u ! and not to l. u(n, n) is an approximation to sigma_min(lu). call stdlib${ii}$_ccopy( n-1, rhs, 1_${ik}$, work, 1_${ik}$ ) work( n ) = rhs( n ) + cone rhs( n ) = rhs( n ) - cone splus = zero sminu = zero do i = n, 1, -1 temp = cone / z( i, i ) work( i ) = work( i )*temp rhs( i ) = rhs( i )*temp do k = i + 1, n work( i ) = work( i ) - work( k )*( z( i, k )*temp ) rhs( i ) = rhs( i ) - rhs( k )*( z( i, k )*temp ) end do splus = splus + abs( work( i ) ) sminu = sminu + abs( rhs( i ) ) end do if( splus>sminu )call stdlib${ii}$_ccopy( n, work, 1_${ik}$, rhs, 1_${ik}$ ) ! apply the permutations jpiv to the computed solution (rhs) call stdlib${ii}$_claswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_classq( n, rhs, 1_${ik}$, rdscal, rdsum ) return end if ! entry ijob = 2 ! compute approximate nullvector xm of z call stdlib${ii}$_cgecon( 'I', n, z, ldz, one, rtemp, work, rwork, info ) call stdlib${ii}$_ccopy( n, work( n+1 ), 1_${ik}$, xm, 1_${ik}$ ) ! compute rhs call stdlib${ii}$_claswp( 1_${ik}$, xm, ldz, 1_${ik}$, n-1, ipiv, -1_${ik}$ ) temp = cone / sqrt( stdlib${ii}$_cdotc( n, xm, 1_${ik}$, xm, 1_${ik}$ ) ) call stdlib${ii}$_cscal( n, temp, xm, 1_${ik}$ ) call stdlib${ii}$_ccopy( n, xm, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_caxpy( n, cone, rhs, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_caxpy( n, -cone, xm, 1_${ik}$, rhs, 1_${ik}$ ) call stdlib${ii}$_cgesc2( n, z, ldz, rhs, ipiv, jpiv, scale ) call stdlib${ii}$_cgesc2( n, z, ldz, xp, ipiv, jpiv, scale ) if( stdlib${ii}$_scasum( n, xp, 1_${ik}$ )>stdlib${ii}$_scasum( n, rhs, 1_${ik}$ ) )call stdlib${ii}$_ccopy( n, xp, 1_${ik}$, & rhs, 1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_classq( n, rhs, 1_${ik}$, rdscal, rdsum ) return end subroutine stdlib${ii}$_clatdf pure module subroutine stdlib${ii}$_zlatdf( ijob, n, z, ldz, rhs, rdsum, rdscal, ipiv,jpiv ) !! ZLATDF computes the contribution to the reciprocal Dif-estimate !! by solving for x in Z * x = b, where b is chosen such that the norm !! of x is as large as possible. It is assumed that LU decomposition !! of Z has been computed by ZGETC2. On entry RHS = f holds the !! contribution from earlier solved sub-systems, and on return RHS = x. !! The factorization of Z returned by ZGETC2 has the form !! Z = P * L * U * Q, where P and Q are permutation matrices. L is lower !! triangular with unit diagonal elements and U is upper triangular. ! -- 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 integer(${ik}$), intent(in) :: ijob, ldz, n real(dp), intent(inout) :: rdscal, rdsum ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) complex(dp), intent(inout) :: rhs(*), z(ldz,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: maxdim = 2_${ik}$ ! Local Scalars integer(${ik}$) :: i, info, j, k real(dp) :: rtemp, scale, sminu, splus complex(dp) :: bm, bp, pmone, temp ! Local Arrays real(dp) :: rwork(maxdim) complex(dp) :: work(4_${ik}$*maxdim), xm(maxdim), xp(maxdim) ! Intrinsic Functions ! Executable Statements if( ijob/=2_${ik}$ ) then ! apply permutations ipiv to rhs call stdlib${ii}$_zlaswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l-part choosing rhs either to +1 or -1. pmone = -cone loop_10: do j = 1, n - 1 bp = rhs( j ) + cone bm = rhs( j ) - cone splus = one ! lockahead for l- part rhs(1:n-1) = +-1 ! splus and smin computed more efficiently than in bsolve[1]. splus = splus + real( stdlib${ii}$_zdotc( n-j, z( j+1, j ), 1_${ik}$, z( j+1,j ), 1_${ik}$ ),KIND=dp) sminu = real( stdlib${ii}$_zdotc( n-j, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ),KIND=dp) splus = splus*real( rhs( j ),KIND=dp) if( splus>sminu ) then rhs( j ) = bp else if( sminu>splus ) then rhs( j ) = bm else ! in this case the updating sums are equal and we can ! choose rhs(j) +1 or -1. the first time this happens we ! choose -1, thereafter +1. this is a simple way to get ! good estimates of matrices like byers well-known example ! (see [1]). (not done in bsolve.) rhs( j ) = rhs( j ) + pmone pmone = cone end if ! compute the remaining r.h.s. temp = -rhs( j ) call stdlib${ii}$_zaxpy( n-j, temp, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) end do loop_10 ! solve for u- part, lockahead for rhs(n) = +-1. this is not done ! in bsolve and will hopefully give us a better estimate because ! any ill-conditioning of the original matrix is transferred to u ! and not to l. u(n, n) is an approximation to sigma_min(lu). call stdlib${ii}$_zcopy( n-1, rhs, 1_${ik}$, work, 1_${ik}$ ) work( n ) = rhs( n ) + cone rhs( n ) = rhs( n ) - cone splus = zero sminu = zero do i = n, 1, -1 temp = cone / z( i, i ) work( i ) = work( i )*temp rhs( i ) = rhs( i )*temp do k = i + 1, n work( i ) = work( i ) - work( k )*( z( i, k )*temp ) rhs( i ) = rhs( i ) - rhs( k )*( z( i, k )*temp ) end do splus = splus + abs( work( i ) ) sminu = sminu + abs( rhs( i ) ) end do if( splus>sminu )call stdlib${ii}$_zcopy( n, work, 1_${ik}$, rhs, 1_${ik}$ ) ! apply the permutations jpiv to the computed solution (rhs) call stdlib${ii}$_zlaswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_zlassq( n, rhs, 1_${ik}$, rdscal, rdsum ) return end if ! entry ijob = 2 ! compute approximate nullvector xm of z call stdlib${ii}$_zgecon( 'I', n, z, ldz, one, rtemp, work, rwork, info ) call stdlib${ii}$_zcopy( n, work( n+1 ), 1_${ik}$, xm, 1_${ik}$ ) ! compute rhs call stdlib${ii}$_zlaswp( 1_${ik}$, xm, ldz, 1_${ik}$, n-1, ipiv, -1_${ik}$ ) temp = cone / sqrt( stdlib${ii}$_zdotc( n, xm, 1_${ik}$, xm, 1_${ik}$ ) ) call stdlib${ii}$_zscal( n, temp, xm, 1_${ik}$ ) call stdlib${ii}$_zcopy( n, xm, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_zaxpy( n, cone, rhs, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_zaxpy( n, -cone, xm, 1_${ik}$, rhs, 1_${ik}$ ) call stdlib${ii}$_zgesc2( n, z, ldz, rhs, ipiv, jpiv, scale ) call stdlib${ii}$_zgesc2( n, z, ldz, xp, ipiv, jpiv, scale ) if( stdlib${ii}$_dzasum( n, xp, 1_${ik}$ )>stdlib${ii}$_dzasum( n, rhs, 1_${ik}$ ) )call stdlib${ii}$_zcopy( n, xp, 1_${ik}$, & rhs, 1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_zlassq( n, rhs, 1_${ik}$, rdscal, rdsum ) return end subroutine stdlib${ii}$_zlatdf #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$latdf( ijob, n, z, ldz, rhs, rdsum, rdscal, ipiv,jpiv ) !! ZLATDF: computes the contribution to the reciprocal Dif-estimate !! by solving for x in Z * x = b, where b is chosen such that the norm !! of x is as large as possible. It is assumed that LU decomposition !! of Z has been computed by ZGETC2. On entry RHS = f holds the !! contribution from earlier solved sub-systems, and on return RHS = x. !! The factorization of Z returned by ZGETC2 has the form !! Z = P * L * U * Q, where P and Q are permutation matrices. L is lower !! triangular with unit diagonal elements and U is upper triangular. ! -- 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 integer(${ik}$), intent(in) :: ijob, ldz, n real(${ck}$), intent(inout) :: rdscal, rdsum ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*), jpiv(*) complex(${ck}$), intent(inout) :: rhs(*), z(ldz,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: maxdim = 2_${ik}$ ! Local Scalars integer(${ik}$) :: i, info, j, k real(${ck}$) :: rtemp, scale, sminu, splus complex(${ck}$) :: bm, bp, pmone, temp ! Local Arrays real(${ck}$) :: rwork(maxdim) complex(${ck}$) :: work(4_${ik}$*maxdim), xm(maxdim), xp(maxdim) ! Intrinsic Functions ! Executable Statements if( ijob/=2_${ik}$ ) then ! apply permutations ipiv to rhs call stdlib${ii}$_${ci}$laswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, ipiv, 1_${ik}$ ) ! solve for l-part choosing rhs either to +1 or -1. pmone = -cone loop_10: do j = 1, n - 1 bp = rhs( j ) + cone bm = rhs( j ) - cone splus = one ! lockahead for l- part rhs(1:n-1) = +-1 ! splus and smin computed more efficiently than in bsolve[1]. splus = splus + real( stdlib${ii}$_${ci}$dotc( n-j, z( j+1, j ), 1_${ik}$, z( j+1,j ), 1_${ik}$ ),KIND=${ck}$) sminu = real( stdlib${ii}$_${ci}$dotc( n-j, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ),KIND=${ck}$) splus = splus*real( rhs( j ),KIND=${ck}$) if( splus>sminu ) then rhs( j ) = bp else if( sminu>splus ) then rhs( j ) = bm else ! in this case the updating sums are equal and we can ! choose rhs(j) +1 or -1. the first time this happens we ! choose -1, thereafter +1. this is a simple way to get ! good estimates of matrices like byers well-known example ! (see [1]). (not done in bsolve.) rhs( j ) = rhs( j ) + pmone pmone = cone end if ! compute the remaining r.h.s. temp = -rhs( j ) call stdlib${ii}$_${ci}$axpy( n-j, temp, z( j+1, j ), 1_${ik}$, rhs( j+1 ), 1_${ik}$ ) end do loop_10 ! solve for u- part, lockahead for rhs(n) = +-1. this is not done ! in bsolve and will hopefully give us a better estimate because ! any ill-conditioning of the original matrix is transferred to u ! and not to l. u(n, n) is an approximation to sigma_min(lu). call stdlib${ii}$_${ci}$copy( n-1, rhs, 1_${ik}$, work, 1_${ik}$ ) work( n ) = rhs( n ) + cone rhs( n ) = rhs( n ) - cone splus = zero sminu = zero do i = n, 1, -1 temp = cone / z( i, i ) work( i ) = work( i )*temp rhs( i ) = rhs( i )*temp do k = i + 1, n work( i ) = work( i ) - work( k )*( z( i, k )*temp ) rhs( i ) = rhs( i ) - rhs( k )*( z( i, k )*temp ) end do splus = splus + abs( work( i ) ) sminu = sminu + abs( rhs( i ) ) end do if( splus>sminu )call stdlib${ii}$_${ci}$copy( n, work, 1_${ik}$, rhs, 1_${ik}$ ) ! apply the permutations jpiv to the computed solution (rhs) call stdlib${ii}$_${ci}$laswp( 1_${ik}$, rhs, ldz, 1_${ik}$, n-1, jpiv, -1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_${ci}$lassq( n, rhs, 1_${ik}$, rdscal, rdsum ) return end if ! entry ijob = 2 ! compute approximate nullvector xm of z call stdlib${ii}$_${ci}$gecon( 'I', n, z, ldz, one, rtemp, work, rwork, info ) call stdlib${ii}$_${ci}$copy( n, work( n+1 ), 1_${ik}$, xm, 1_${ik}$ ) ! compute rhs call stdlib${ii}$_${ci}$laswp( 1_${ik}$, xm, ldz, 1_${ik}$, n-1, ipiv, -1_${ik}$ ) temp = cone / sqrt( stdlib${ii}$_${ci}$dotc( n, xm, 1_${ik}$, xm, 1_${ik}$ ) ) call stdlib${ii}$_${ci}$scal( n, temp, xm, 1_${ik}$ ) call stdlib${ii}$_${ci}$copy( n, xm, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_${ci}$axpy( n, cone, rhs, 1_${ik}$, xp, 1_${ik}$ ) call stdlib${ii}$_${ci}$axpy( n, -cone, xm, 1_${ik}$, rhs, 1_${ik}$ ) call stdlib${ii}$_${ci}$gesc2( n, z, ldz, rhs, ipiv, jpiv, scale ) call stdlib${ii}$_${ci}$gesc2( n, z, ldz, xp, ipiv, jpiv, scale ) if( stdlib${ii}$_${c2ri(ci)}$zasum( n, xp, 1_${ik}$ )>stdlib${ii}$_${c2ri(ci)}$zasum( n, rhs, 1_${ik}$ ) )call stdlib${ii}$_${ci}$copy( n, xp, 1_${ik}$, & rhs, 1_${ik}$ ) ! compute the sum of squares call stdlib${ii}$_${ci}$lassq( n, rhs, 1_${ik}$, rdscal, rdsum ) return end subroutine stdlib${ii}$_${ci}$latdf #:endif #:endfor real(sp) module function stdlib${ii}$_sla_gercond( trans, n, a, lda, af, ldaf, ipiv,cmode, c, info, work, & !! SLA_GERCOND 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. iwork ) ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(in) :: n, lda, ldaf, cmode integer(${ik}$), intent(out) :: info ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(in) :: a(lda,*), af(ldaf,*), c(*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: notrans integer(${ik}$) :: kase, i, j real(sp) :: ainvnm, tmp ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements stdlib${ii}$_sla_gercond = zero info = 0_${ik}$ notrans = stdlib_lsame( trans, 'N' ) if ( .not. notrans .and. .not. stdlib_lsame(trans, 'T').and. .not. stdlib_lsame(trans, & 'C') ) 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( ldaf<max( 1_${ik}$, n ) ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SLA_GERCOND', -info ) return end if if( n==0_${ik}$ ) then stdlib${ii}$_sla_gercond = one return end if ! compute the equilibration matrix r such that ! inv(r)*a*c has unit 1-norm. if (notrans) then do i = 1, n tmp = zero if ( cmode == 1_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( i, j ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( i, j ) ) end do else do j = 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, n tmp = tmp + abs( a( j, i ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( j, i ) ) end do else do j = 1, n tmp = tmp + abs( a( j, i ) / c( j ) ) end do end if work( 2_${ik}$*n+i ) = tmp end do end if ! 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 (notrans) then call stdlib${ii}$_sgetrs( 'NO TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) else call stdlib${ii}$_sgetrs( 'TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) end if ! 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 (notrans) then call stdlib${ii}$_sgetrs( 'TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) else call stdlib${ii}$_sgetrs( 'NO TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) end if ! 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_gercond = ( one / ainvnm ) return end function stdlib${ii}$_sla_gercond real(dp) module function stdlib${ii}$_dla_gercond( trans, n, a, lda, af,ldaf, ipiv, cmode, c,info, work, & !! DLA_GERCOND 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. iwork ) ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(in) :: n, lda, ldaf, cmode integer(${ik}$), intent(out) :: info ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(in) :: a(lda,*), af(ldaf,*), c(*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: notrans integer(${ik}$) :: kase, i, j real(dp) :: ainvnm, tmp ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements stdlib${ii}$_dla_gercond = zero info = 0_${ik}$ notrans = stdlib_lsame( trans, 'N' ) if ( .not. notrans .and. .not. stdlib_lsame(trans, 'T').and. .not. stdlib_lsame(trans, & 'C') ) 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( ldaf<max( 1_${ik}$, n ) ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DLA_GERCOND', -info ) return end if if( n==0_${ik}$ ) then stdlib${ii}$_dla_gercond = one return end if ! compute the equilibration matrix r such that ! inv(r)*a*c has unit 1-norm. if (notrans) then do i = 1, n tmp = zero if ( cmode == 1_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( i, j ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( i, j ) ) end do else do j = 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, n tmp = tmp + abs( a( j, i ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( j, i ) ) end do else do j = 1, n tmp = tmp + abs( a( j, i ) / c( j ) ) end do end if work( 2_${ik}$*n+i ) = tmp end do end if ! 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 (notrans) then call stdlib${ii}$_dgetrs( 'NO TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) else call stdlib${ii}$_dgetrs( 'TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) end if ! 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 (notrans) then call stdlib${ii}$_dgetrs( 'TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) else call stdlib${ii}$_dgetrs( 'NO TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) end if ! 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_gercond = ( one / ainvnm ) return end function stdlib${ii}$_dla_gercond #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] real(${rk}$) module function stdlib${ii}$_${ri}$la_gercond( trans, n, a, lda, af,ldaf, ipiv, cmode, c,info, work, & !! DLA_GERCOND: 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. iwork ) ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(in) :: n, lda, ldaf, cmode integer(${ik}$), intent(out) :: info ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(in) :: a(lda,*), af(ldaf,*), c(*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: notrans integer(${ik}$) :: kase, i, j real(${rk}$) :: ainvnm, tmp ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements stdlib${ii}$_${ri}$la_gercond = zero info = 0_${ik}$ notrans = stdlib_lsame( trans, 'N' ) if ( .not. notrans .and. .not. stdlib_lsame(trans, 'T').and. .not. stdlib_lsame(trans, & 'C') ) 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( ldaf<max( 1_${ik}$, n ) ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DLA_GERCOND', -info ) return end if if( n==0_${ik}$ ) then stdlib${ii}$_${ri}$la_gercond = one return end if ! compute the equilibration matrix r such that ! inv(r)*a*c has unit 1-norm. if (notrans) then do i = 1, n tmp = zero if ( cmode == 1_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( i, j ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( i, j ) ) end do else do j = 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, n tmp = tmp + abs( a( j, i ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = 1, n tmp = tmp + abs( a( j, i ) ) end do else do j = 1, n tmp = tmp + abs( a( j, i ) / c( j ) ) end do end if work( 2_${ik}$*n+i ) = tmp end do end if ! 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 (notrans) then call stdlib${ii}$_${ri}$getrs( 'NO TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) else call stdlib${ii}$_${ri}$getrs( 'TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) end if ! 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 (notrans) then call stdlib${ii}$_${ri}$getrs( 'TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) else call stdlib${ii}$_${ri}$getrs( 'NO TRANSPOSE', n, 1_${ik}$, af, ldaf, ipiv,work, n, info ) end if ! 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_gercond = ( one / ainvnm ) return end function stdlib${ii}$_${ri}$la_gercond #:endif #:endfor pure module subroutine stdlib${ii}$_sgbcon( norm, n, kl, ku, ab, ldab, ipiv, anorm, rcond,work, iwork, & !! SGBCON estimates the reciprocal of the condition number of a real !! general band matrix A, in either the 1-norm or the infinity-norm, !! using the LU factorization computed by SGBTRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * norm(inv(A)) ). 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, n real(sp), intent(in) :: anorm real(sp), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(in) :: ab(ldab,*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, onenrm character :: normin integer(${ik}$) :: ix, j, jp, kase, kase1, kd, lm real(sp) :: ainvnm, scale, smlnum, t ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<2_${ik}$*kl+ku+1 ) then info = -6_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBCON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kd = kl + ku + 1_${ik}$ lnoti = kl>0_${ik}$ 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==kase1 ) then ! multiply by inv(l). if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) jp = ipiv( j ) t = work( jp ) if( jp/=j ) then work( jp ) = work( j ) work( j ) = t end if call stdlib${ii}$_saxpy( lm, -t, ab( kd+1, j ), 1_${ik}$, work( j+1 ), 1_${ik}$ ) end do end if ! multiply by inv(u). call stdlib${ii}$_slatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, & ldab, work, scale, work( 2_${ik}$*n+1 ),info ) else ! multiply by inv(u**t). call stdlib${ii}$_slatbs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, ldab, & work, scale, work( 2_${ik}$*n+1 ),info ) ! multiply by inv(l**t). if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) work( j ) = work( j ) - stdlib${ii}$_sdot( lm, ab( kd+1, j ), 1_${ik}$,work( j+1 ), 1_${ik}$ ) jp = ipiv( j ) if( jp/=j ) then t = work( jp ) work( jp ) = work( j ) work( j ) = t end if end do end if end if ! divide x by 1/scale if doing so will not cause overflow. normin = 'Y' if( scale/=one ) then ix = stdlib${ii}$_isamax( n, work, 1_${ik}$ ) if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 40 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 40 continue return end subroutine stdlib${ii}$_sgbcon pure module subroutine stdlib${ii}$_dgbcon( norm, n, kl, ku, ab, ldab, ipiv, anorm, rcond,work, iwork, & !! DGBCON estimates the reciprocal of the condition number of a real !! general band matrix A, in either the 1-norm or the infinity-norm, !! using the LU factorization computed by DGBTRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * norm(inv(A)) ). 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, n real(dp), intent(in) :: anorm real(dp), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(in) :: ab(ldab,*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, onenrm character :: normin integer(${ik}$) :: ix, j, jp, kase, kase1, kd, lm real(dp) :: ainvnm, scale, smlnum, t ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<2_${ik}$*kl+ku+1 ) then info = -6_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBCON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kd = kl + ku + 1_${ik}$ lnoti = kl>0_${ik}$ 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==kase1 ) then ! multiply by inv(l). if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) jp = ipiv( j ) t = work( jp ) if( jp/=j ) then work( jp ) = work( j ) work( j ) = t end if call stdlib${ii}$_daxpy( lm, -t, ab( kd+1, j ), 1_${ik}$, work( j+1 ), 1_${ik}$ ) end do end if ! multiply by inv(u). call stdlib${ii}$_dlatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, & ldab, work, scale, work( 2_${ik}$*n+1 ),info ) else ! multiply by inv(u**t). call stdlib${ii}$_dlatbs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, ldab, & work, scale, work( 2_${ik}$*n+1 ),info ) ! multiply by inv(l**t). if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) work( j ) = work( j ) - stdlib${ii}$_ddot( lm, ab( kd+1, j ), 1_${ik}$,work( j+1 ), 1_${ik}$ ) jp = ipiv( j ) if( jp/=j ) then t = work( jp ) work( jp ) = work( j ) work( j ) = t end if end do end if end if ! divide x by 1/scale if doing so will not cause overflow. normin = 'Y' if( scale/=one ) then ix = stdlib${ii}$_idamax( n, work, 1_${ik}$ ) if( scale<abs( work( ix ) )*smlnum .or. scale==zero )go to 40 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 40 continue return end subroutine stdlib${ii}$_dgbcon #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbcon( norm, n, kl, ku, ab, ldab, ipiv, anorm, rcond,work, iwork, & !! DGBCON: estimates the reciprocal of the condition number of a real !! general band matrix A, in either the 1-norm or the infinity-norm, !! using the LU factorization computed by DGBTRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * norm(inv(A)) ). 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, n real(${rk}$), intent(in) :: anorm real(${rk}$), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(in) :: ab(ldab,*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, onenrm character :: normin integer(${ik}$) :: ix, j, jp, kase, kase1, kd, lm real(${rk}$) :: ainvnm, scale, smlnum, t ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<2_${ik}$*kl+ku+1 ) then info = -6_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBCON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kd = kl + ku + 1_${ik}$ lnoti = kl>0_${ik}$ 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==kase1 ) then ! multiply by inv(l). if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) jp = ipiv( j ) t = work( jp ) if( jp/=j ) then work( jp ) = work( j ) work( j ) = t end if call stdlib${ii}$_${ri}$axpy( lm, -t, ab( kd+1, j ), 1_${ik}$, work( j+1 ), 1_${ik}$ ) end do end if ! multiply by inv(u). call stdlib${ii}$_${ri}$latbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, & ldab, work, scale, work( 2_${ik}$*n+1 ),info ) else ! multiply by inv(u**t). call stdlib${ii}$_${ri}$latbs( 'UPPER', 'TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, ldab, & work, scale, work( 2_${ik}$*n+1 ),info ) ! multiply by inv(l**t). if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) work( j ) = work( j ) - stdlib${ii}$_${ri}$dot( lm, ab( kd+1, j ), 1_${ik}$,work( j+1 ), 1_${ik}$ ) jp = ipiv( j ) if( jp/=j ) then t = work( jp ) work( jp ) = work( j ) work( j ) = t end if end do end if end if ! divide x by 1/scale if doing so will not cause overflow. normin = 'Y' 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 40 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 40 continue return end subroutine stdlib${ii}$_${ri}$gbcon #:endif #:endfor pure module subroutine stdlib${ii}$_cgbcon( norm, n, kl, ku, ab, ldab, ipiv, anorm, rcond,work, rwork, & !! CGBCON estimates the reciprocal of the condition number of a complex !! general band matrix A, in either the 1-norm or the infinity-norm, !! using the LU factorization computed by CGBTRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * norm(inv(A)) ). 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, n real(sp), intent(in) :: anorm real(sp), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(out) :: rwork(*) complex(sp), intent(in) :: ab(ldab,*) complex(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, onenrm character :: normin integer(${ik}$) :: ix, j, jp, kase, kase1, kd, lm real(sp) :: ainvnm, scale, smlnum complex(sp) :: t, 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}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<2_${ik}$*kl+ku+1 ) then info = -6_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBCON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kd = kl + ku + 1_${ik}$ lnoti = kl>0_${ik}$ kase = 0_${ik}$ 10 continue call stdlib${ii}$_clacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(l). if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) jp = ipiv( j ) t = work( jp ) if( jp/=j ) then work( jp ) = work( j ) work( j ) = t end if call stdlib${ii}$_caxpy( lm, -t, ab( kd+1, j ), 1_${ik}$, work( j+1 ), 1_${ik}$ ) end do end if ! multiply by inv(u). call stdlib${ii}$_clatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, & ldab, work, scale, rwork, info ) else ! multiply by inv(u**h). call stdlib${ii}$_clatbs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kl+ku, & ab, ldab, work, scale, rwork,info ) ! multiply by inv(l**h). if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) work( j ) = work( j ) - stdlib${ii}$_cdotc( lm, ab( kd+1, j ), 1_${ik}$,work( j+1 ), 1_${ik}$ ) jp = ipiv( j ) if( jp/=j ) then t = work( jp ) work( jp ) = work( j ) work( j ) = t end if end do end if end if ! divide x by 1/scale if doing so will not cause overflow. normin = 'Y' if( scale/=one ) then ix = stdlib${ii}$_icamax( n, work, 1_${ik}$ ) if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 40 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 40 continue return end subroutine stdlib${ii}$_cgbcon pure module subroutine stdlib${ii}$_zgbcon( norm, n, kl, ku, ab, ldab, ipiv, anorm, rcond,work, rwork, & !! ZGBCON estimates the reciprocal of the condition number of a complex !! general band matrix A, in either the 1-norm or the infinity-norm, !! using the LU factorization computed by ZGBTRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * norm(inv(A)) ). 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, n real(dp), intent(in) :: anorm real(dp), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(out) :: rwork(*) complex(dp), intent(in) :: ab(ldab,*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, onenrm character :: normin integer(${ik}$) :: ix, j, jp, kase, kase1, kd, lm real(dp) :: ainvnm, scale, smlnum complex(dp) :: t, 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}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<2_${ik}$*kl+ku+1 ) then info = -6_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBCON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kd = kl + ku + 1_${ik}$ lnoti = kl>0_${ik}$ kase = 0_${ik}$ 10 continue call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(l). if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) jp = ipiv( j ) t = work( jp ) if( jp/=j ) then work( jp ) = work( j ) work( j ) = t end if call stdlib${ii}$_zaxpy( lm, -t, ab( kd+1, j ), 1_${ik}$, work( j+1 ), 1_${ik}$ ) end do end if ! multiply by inv(u). call stdlib${ii}$_zlatbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, & ldab, work, scale, rwork, info ) else ! multiply by inv(u**h). call stdlib${ii}$_zlatbs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kl+ku, & ab, ldab, work, scale, rwork,info ) ! multiply by inv(l**h). if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) work( j ) = work( j ) - stdlib${ii}$_zdotc( lm, ab( kd+1, j ), 1_${ik}$,work( j+1 ), 1_${ik}$ ) jp = ipiv( j ) if( jp/=j ) then t = work( jp ) work( jp ) = work( j ) work( j ) = t end if end do end if end if ! divide x by 1/scale if doing so will not cause overflow. normin = 'Y' if( scale/=one ) then ix = stdlib${ii}$_izamax( n, work, 1_${ik}$ ) if( scale<cabs1( work( ix ) )*smlnum .or. scale==zero )go to 40 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 40 continue return end subroutine stdlib${ii}$_zgbcon #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbcon( norm, n, kl, ku, ab, ldab, ipiv, anorm, rcond,work, rwork, & !! ZGBCON: estimates the reciprocal of the condition number of a complex !! general band matrix A, in either the 1-norm or the infinity-norm, !! using the LU factorization computed by ZGBTRF. !! An estimate is obtained for norm(inv(A)), and the reciprocal of the !! condition number is computed as !! RCOND = 1 / ( norm(A) * norm(inv(A)) ). 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, n real(${ck}$), intent(in) :: anorm real(${ck}$), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${ck}$), intent(out) :: rwork(*) complex(${ck}$), intent(in) :: ab(ldab,*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, onenrm character :: normin integer(${ik}$) :: ix, j, jp, kase, kase1, kd, lm real(${ck}$) :: ainvnm, scale, smlnum complex(${ck}$) :: t, 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}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<2_${ik}$*kl+ku+1 ) then info = -6_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBCON', -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 norm of inv(a). ainvnm = zero normin = 'N' if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kd = kl + ku + 1_${ik}$ lnoti = kl>0_${ik}$ kase = 0_${ik}$ 10 continue call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(l). if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) jp = ipiv( j ) t = work( jp ) if( jp/=j ) then work( jp ) = work( j ) work( j ) = t end if call stdlib${ii}$_${ci}$axpy( lm, -t, ab( kd+1, j ), 1_${ik}$, work( j+1 ), 1_${ik}$ ) end do end if ! multiply by inv(u). call stdlib${ii}$_${ci}$latbs( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', normin, n,kl+ku, ab, & ldab, work, scale, rwork, info ) else ! multiply by inv(u**h). call stdlib${ii}$_${ci}$latbs( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT',normin, n, kl+ku, & ab, ldab, work, scale, rwork,info ) ! multiply by inv(l**h). if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) work( j ) = work( j ) - stdlib${ii}$_${ci}$dotc( lm, ab( kd+1, j ), 1_${ik}$,work( j+1 ), 1_${ik}$ ) jp = ipiv( j ) if( jp/=j ) then t = work( jp ) work( jp ) = work( j ) work( j ) = t end if end do end if end if ! divide x by 1/scale if doing so will not cause overflow. normin = 'Y' 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 40 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 40 continue return end subroutine stdlib${ii}$_${ci}$gbcon #:endif #:endfor pure module subroutine stdlib${ii}$_sgbtrf( m, n, kl, ku, ab, ldab, ipiv, info ) !! SGBTRF computes an LU factorization of a real m-by-n band matrix A !! using partial pivoting with row interchanges. !! This is the blocked 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(sp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: nbmax = 64_${ik}$ integer(${ik}$), parameter :: ldwork = nbmax+1 ! Local Scalars integer(${ik}$) :: i, i2, i3, ii, ip, j, j2, j3, jb, jj, jm, jp, ju, k2, km, kv, nb, & nw real(sp) :: temp ! Local Arrays real(sp) :: work13(ldwork,nbmax), work31(ldwork,nbmax) ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBTRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'SGBTRF', ' ', m, n, kl, ku ) ! the block size must not exceed the limit set by the size of the ! local arrays work13 and work31. nb = min( nb, nbmax ) if( nb<=1_${ik}$ .or. nb>kl ) then ! use unblocked code call stdlib${ii}$_sgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) else ! use blocked code ! zero the superdiagonal elements of the work array work13 do j = 1, nb do i = 1, j - 1 work13( i, j ) = zero end do end do ! zero the subdiagonal elements of the work array work31 do j = 1, nb do i = j + 1, nb work31( i, j ) = zero end do end do ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to zero do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = zero end do end do ! ju is the index of the last column affected by the current ! stage of the factorization ju = 1_${ik}$ loop_180: do j = 1, min( m, n ), nb jb = min( nb, min( m, n )-j+1 ) ! the active part of the matrix is partitioned ! a11 a12 a13 ! a21 a22 a23 ! a31 a32 a33 ! here a11, a21 and a31 denote the current block of jb columns ! which is about to be factorized. the number of rows in the ! partitioning are jb, i2, i3 respectively, and the numbers ! of columns are jb, j2, j3. the superdiagonal elements of a13 ! and the subdiagonal elements of a31 lie outside the band. i2 = min( kl-jb, m-j-jb+1 ) i3 = min( jb, m-j-kl+1 ) ! j2 and j3 are computed after ju has been updated. ! factorize the current block of jb columns loop_80: do jj = j, j + jb - 1 ! set fill-in elements in column jj+kv to zero if( jj+kv<=n ) then do i = 1, kl ab( i, jj+kv ) = zero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-jj ) jp = stdlib${ii}$_isamax( km+1, ab( kv+1, jj ), 1_${ik}$ ) ipiv( jj ) = jp + jj - j if( ab( kv+jp, jj )/=zero ) then ju = max( ju, min( jj+ku+jp-1, n ) ) if( jp/=1_${ik}$ ) then ! apply interchange to columns j to j+jb-1 if( jp+jj-1<j+kl ) then call stdlib${ii}$_sswap( jb, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j )& , ldab-1 ) else ! the interchange affects columns j to jj-1 of a31 ! which are stored in the work array work31 call stdlib${ii}$_sswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-& kl, 1_${ik}$ ), ldwork ) call stdlib${ii}$_sswap( j+jb-jj, ab( kv+1, jj ), ldab-1,ab( kv+jp, jj ), & ldab-1 ) end if end if ! compute multipliers call stdlib${ii}$_sscal( km, one / ab( kv+1, jj ), ab( kv+2, jj ),1_${ik}$ ) ! update trailing submatrix within the band and within ! the current block. jm is the index of the last column ! which needs to be updated. jm = min( ju, j+jb-1 ) if( jm>jj )call stdlib${ii}$_sger( km, jm-jj, -one, ab( kv+2, jj ), 1_${ik}$,ab( kv, jj+& 1_${ik}$ ), ldab-1,ab( kv+1, jj+1 ), ldab-1 ) else ! if pivot is zero, set info to the index of the pivot ! unless a zero pivot has already been found. if( info==0_${ik}$ )info = jj end if ! copy current column of a31 into the work array work31 nw = min( jj-j+1, i3 ) if( nw>0_${ik}$ )call stdlib${ii}$_scopy( nw, ab( kv+kl+1-jj+j, jj ), 1_${ik}$,work31( 1_${ik}$, jj-j+1 )& , 1_${ik}$ ) end do loop_80 if( j+jb<=n ) then ! apply the row interchanges to the other blocks. j2 = min( ju-j+1, kv ) - jb j3 = max( 0_${ik}$, ju-j-kv+1 ) ! use stdlib_slaswp to apply the row interchanges to a12, a22, and ! a32. call stdlib${ii}$_slaswp( j2, ab( kv+1-jb, j+jb ), ldab-1, 1_${ik}$, jb,ipiv( j ), 1_${ik}$ ) ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do ! apply the row interchanges to a13, a23, and a33 ! columnwise. k2 = j - 1_${ik}$ + jb + j2 do i = 1, j3 jj = k2 + i do ii = j + i - 1, j + jb - 1 ip = ipiv( ii ) if( ip/=ii ) then temp = ab( kv+1+ii-jj, jj ) ab( kv+1+ii-jj, jj ) = ab( kv+1+ip-jj, jj ) ab( kv+1+ip-jj, jj ) = temp end if end do end do ! update the relevant part of the trailing submatrix if( j2>0_${ik}$ ) then ! update a12 call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j2, one, ab(& kv+1, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1 ) if( i2>0_${ik}$ ) then ! update a22 call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j2,jb, -one, ab( & kv+1+jb, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1, one,ab( kv+1, j+jb ), & ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a32 call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j2,jb, -one, & work31, ldwork,ab( kv+1-jb, j+jb ), ldab-1, one,ab( kv+kl+1-jb, j+jb ), & ldab-1 ) end if end if if( j3>0_${ik}$ ) then ! copy the lower triangle of a13 into the work array ! work13 do jj = 1, j3 do ii = jj, jb work13( ii, jj ) = ab( ii-jj+1, jj+j+kv-1 ) end do end do ! update a13 in the work array call stdlib${ii}$_strsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j3, one, ab(& kv+1, j ), ldab-1,work13, ldwork ) if( i2>0_${ik}$ ) then ! update a23 call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j3,jb, -one, ab( & kv+1+jb, j ), ldab-1,work13, ldwork, one, ab( 1_${ik}$+jb, j+kv ),ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a33 call stdlib${ii}$_sgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j3,jb, -one, & work31, ldwork, work13,ldwork, one, ab( 1_${ik}$+kl, j+kv ), ldab-1 ) end if ! copy the lower triangle of a13 back into place do jj = 1, j3 do ii = jj, jb ab( ii-jj+1, jj+j+kv-1 ) = work13( ii, jj ) end do end do end if else ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do end if ! partially undo the interchanges in the current block to ! restore the upper triangular form of a31 and copy the upper ! triangle of a31 back into place do jj = j + jb - 1, j, -1 jp = ipiv( jj ) - jj + 1_${ik}$ if( jp/=1_${ik}$ ) then ! apply interchange to columns j to jj-1 if( jp+jj-1<j+kl ) then ! the interchange does not affect a31 call stdlib${ii}$_sswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j ),& ldab-1 ) else ! the interchange does affect a31 call stdlib${ii}$_sswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-kl, & 1_${ik}$ ), ldwork ) end if end if ! copy the current column of a31 back into place nw = min( i3, jj-j+1 ) if( nw>0_${ik}$ )call stdlib${ii}$_scopy( nw, work31( 1_${ik}$, jj-j+1 ), 1_${ik}$,ab( kv+kl+1-jj+j, jj )& , 1_${ik}$ ) end do end do loop_180 end if return end subroutine stdlib${ii}$_sgbtrf pure module subroutine stdlib${ii}$_dgbtrf( m, n, kl, ku, ab, ldab, ipiv, info ) !! DGBTRF computes an LU factorization of a real m-by-n band matrix A !! using partial pivoting with row interchanges. !! This is the blocked 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(dp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: nbmax = 64_${ik}$ integer(${ik}$), parameter :: ldwork = nbmax+1 ! Local Scalars integer(${ik}$) :: i, i2, i3, ii, ip, j, j2, j3, jb, jj, jm, jp, ju, k2, km, kv, nb, & nw real(dp) :: temp ! Local Arrays real(dp) :: work13(ldwork,nbmax), work31(ldwork,nbmax) ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBTRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGBTRF', ' ', m, n, kl, ku ) ! the block size must not exceed the limit set by the size of the ! local arrays work13 and work31. nb = min( nb, nbmax ) if( nb<=1_${ik}$ .or. nb>kl ) then ! use unblocked code call stdlib${ii}$_dgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) else ! use blocked code ! zero the superdiagonal elements of the work array work13 do j = 1, nb do i = 1, j - 1 work13( i, j ) = zero end do end do ! zero the subdiagonal elements of the work array work31 do j = 1, nb do i = j + 1, nb work31( i, j ) = zero end do end do ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to zero do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = zero end do end do ! ju is the index of the last column affected by the current ! stage of the factorization ju = 1_${ik}$ loop_180: do j = 1, min( m, n ), nb jb = min( nb, min( m, n )-j+1 ) ! the active part of the matrix is partitioned ! a11 a12 a13 ! a21 a22 a23 ! a31 a32 a33 ! here a11, a21 and a31 denote the current block of jb columns ! which is about to be factorized. the number of rows in the ! partitioning are jb, i2, i3 respectively, and the numbers ! of columns are jb, j2, j3. the superdiagonal elements of a13 ! and the subdiagonal elements of a31 lie outside the band. i2 = min( kl-jb, m-j-jb+1 ) i3 = min( jb, m-j-kl+1 ) ! j2 and j3 are computed after ju has been updated. ! factorize the current block of jb columns loop_80: do jj = j, j + jb - 1 ! set fill-in elements in column jj+kv to zero if( jj+kv<=n ) then do i = 1, kl ab( i, jj+kv ) = zero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-jj ) jp = stdlib${ii}$_idamax( km+1, ab( kv+1, jj ), 1_${ik}$ ) ipiv( jj ) = jp + jj - j if( ab( kv+jp, jj )/=zero ) then ju = max( ju, min( jj+ku+jp-1, n ) ) if( jp/=1_${ik}$ ) then ! apply interchange to columns j to j+jb-1 if( jp+jj-1<j+kl ) then call stdlib${ii}$_dswap( jb, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j )& , ldab-1 ) else ! the interchange affects columns j to jj-1 of a31 ! which are stored in the work array work31 call stdlib${ii}$_dswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-& kl, 1_${ik}$ ), ldwork ) call stdlib${ii}$_dswap( j+jb-jj, ab( kv+1, jj ), ldab-1,ab( kv+jp, jj ), & ldab-1 ) end if end if ! compute multipliers call stdlib${ii}$_dscal( km, one / ab( kv+1, jj ), ab( kv+2, jj ),1_${ik}$ ) ! update trailing submatrix within the band and within ! the current block. jm is the index of the last column ! which needs to be updated. jm = min( ju, j+jb-1 ) if( jm>jj )call stdlib${ii}$_dger( km, jm-jj, -one, ab( kv+2, jj ), 1_${ik}$,ab( kv, jj+& 1_${ik}$ ), ldab-1,ab( kv+1, jj+1 ), ldab-1 ) else ! if pivot is zero, set info to the index of the pivot ! unless a zero pivot has already been found. if( info==0_${ik}$ )info = jj end if ! copy current column of a31 into the work array work31 nw = min( jj-j+1, i3 ) if( nw>0_${ik}$ )call stdlib${ii}$_dcopy( nw, ab( kv+kl+1-jj+j, jj ), 1_${ik}$,work31( 1_${ik}$, jj-j+1 )& , 1_${ik}$ ) end do loop_80 if( j+jb<=n ) then ! apply the row interchanges to the other blocks. j2 = min( ju-j+1, kv ) - jb j3 = max( 0_${ik}$, ju-j-kv+1 ) ! use stdlib_dlaswp to apply the row interchanges to a12, a22, and ! a32. call stdlib${ii}$_dlaswp( j2, ab( kv+1-jb, j+jb ), ldab-1, 1_${ik}$, jb,ipiv( j ), 1_${ik}$ ) ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do ! apply the row interchanges to a13, a23, and a33 ! columnwise. k2 = j - 1_${ik}$ + jb + j2 do i = 1, j3 jj = k2 + i do ii = j + i - 1, j + jb - 1 ip = ipiv( ii ) if( ip/=ii ) then temp = ab( kv+1+ii-jj, jj ) ab( kv+1+ii-jj, jj ) = ab( kv+1+ip-jj, jj ) ab( kv+1+ip-jj, jj ) = temp end if end do end do ! update the relevant part of the trailing submatrix if( j2>0_${ik}$ ) then ! update a12 call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j2, one, ab(& kv+1, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1 ) if( i2>0_${ik}$ ) then ! update a22 call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j2,jb, -one, ab( & kv+1+jb, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1, one,ab( kv+1, j+jb ), & ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a32 call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j2,jb, -one, & work31, ldwork,ab( kv+1-jb, j+jb ), ldab-1, one,ab( kv+kl+1-jb, j+jb ), & ldab-1 ) end if end if if( j3>0_${ik}$ ) then ! copy the lower triangle of a13 into the work array ! work13 do jj = 1, j3 do ii = jj, jb work13( ii, jj ) = ab( ii-jj+1, jj+j+kv-1 ) end do end do ! update a13 in the work array call stdlib${ii}$_dtrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j3, one, ab(& kv+1, j ), ldab-1,work13, ldwork ) if( i2>0_${ik}$ ) then ! update a23 call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j3,jb, -one, ab( & kv+1+jb, j ), ldab-1,work13, ldwork, one, ab( 1_${ik}$+jb, j+kv ),ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a33 call stdlib${ii}$_dgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j3,jb, -one, & work31, ldwork, work13,ldwork, one, ab( 1_${ik}$+kl, j+kv ), ldab-1 ) end if ! copy the lower triangle of a13 back into place do jj = 1, j3 do ii = jj, jb ab( ii-jj+1, jj+j+kv-1 ) = work13( ii, jj ) end do end do end if else ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do end if ! partially undo the interchanges in the current block to ! restore the upper triangular form of a31 and copy the upper ! triangle of a31 back into place do jj = j + jb - 1, j, -1 jp = ipiv( jj ) - jj + 1_${ik}$ if( jp/=1_${ik}$ ) then ! apply interchange to columns j to jj-1 if( jp+jj-1<j+kl ) then ! the interchange does not affect a31 call stdlib${ii}$_dswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j ),& ldab-1 ) else ! the interchange does affect a31 call stdlib${ii}$_dswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-kl, & 1_${ik}$ ), ldwork ) end if end if ! copy the current column of a31 back into place nw = min( i3, jj-j+1 ) if( nw>0_${ik}$ )call stdlib${ii}$_dcopy( nw, work31( 1_${ik}$, jj-j+1 ), 1_${ik}$,ab( kv+kl+1-jj+j, jj )& , 1_${ik}$ ) end do end do loop_180 end if return end subroutine stdlib${ii}$_dgbtrf #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbtrf( m, n, kl, ku, ab, ldab, ipiv, info ) !! DGBTRF: computes an LU factorization of a real m-by-n band matrix A !! using partial pivoting with row interchanges. !! This is the blocked 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(${rk}$), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: nbmax = 64_${ik}$ integer(${ik}$), parameter :: ldwork = nbmax+1 ! Local Scalars integer(${ik}$) :: i, i2, i3, ii, ip, j, j2, j3, jb, jj, jm, jp, ju, k2, km, kv, nb, & nw real(${rk}$) :: temp ! Local Arrays real(${rk}$) :: work13(ldwork,nbmax), work31(ldwork,nbmax) ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBTRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'DGBTRF', ' ', m, n, kl, ku ) ! the block size must not exceed the limit set by the size of the ! local arrays work13 and work31. nb = min( nb, nbmax ) if( nb<=1_${ik}$ .or. nb>kl ) then ! use unblocked code call stdlib${ii}$_${ri}$gbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) else ! use blocked code ! zero the superdiagonal elements of the work array work13 do j = 1, nb do i = 1, j - 1 work13( i, j ) = zero end do end do ! zero the subdiagonal elements of the work array work31 do j = 1, nb do i = j + 1, nb work31( i, j ) = zero end do end do ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to zero do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = zero end do end do ! ju is the index of the last column affected by the current ! stage of the factorization ju = 1_${ik}$ loop_180: do j = 1, min( m, n ), nb jb = min( nb, min( m, n )-j+1 ) ! the active part of the matrix is partitioned ! a11 a12 a13 ! a21 a22 a23 ! a31 a32 a33 ! here a11, a21 and a31 denote the current block of jb columns ! which is about to be factorized. the number of rows in the ! partitioning are jb, i2, i3 respectively, and the numbers ! of columns are jb, j2, j3. the superdiagonal elements of a13 ! and the subdiagonal elements of a31 lie outside the band. i2 = min( kl-jb, m-j-jb+1 ) i3 = min( jb, m-j-kl+1 ) ! j2 and j3 are computed after ju has been updated. ! factorize the current block of jb columns loop_80: do jj = j, j + jb - 1 ! set fill-in elements in column jj+kv to zero if( jj+kv<=n ) then do i = 1, kl ab( i, jj+kv ) = zero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-jj ) jp = stdlib${ii}$_i${ri}$amax( km+1, ab( kv+1, jj ), 1_${ik}$ ) ipiv( jj ) = jp + jj - j if( ab( kv+jp, jj )/=zero ) then ju = max( ju, min( jj+ku+jp-1, n ) ) if( jp/=1_${ik}$ ) then ! apply interchange to columns j to j+jb-1 if( jp+jj-1<j+kl ) then call stdlib${ii}$_${ri}$swap( jb, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j )& , ldab-1 ) else ! the interchange affects columns j to jj-1 of a31 ! which are stored in the work array work31 call stdlib${ii}$_${ri}$swap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-& kl, 1_${ik}$ ), ldwork ) call stdlib${ii}$_${ri}$swap( j+jb-jj, ab( kv+1, jj ), ldab-1,ab( kv+jp, jj ), & ldab-1 ) end if end if ! compute multipliers call stdlib${ii}$_${ri}$scal( km, one / ab( kv+1, jj ), ab( kv+2, jj ),1_${ik}$ ) ! update trailing submatrix within the band and within ! the current block. jm is the index of the last column ! which needs to be updated. jm = min( ju, j+jb-1 ) if( jm>jj )call stdlib${ii}$_${ri}$ger( km, jm-jj, -one, ab( kv+2, jj ), 1_${ik}$,ab( kv, jj+& 1_${ik}$ ), ldab-1,ab( kv+1, jj+1 ), ldab-1 ) else ! if pivot is zero, set info to the index of the pivot ! unless a zero pivot has already been found. if( info==0_${ik}$ )info = jj end if ! copy current column of a31 into the work array work31 nw = min( jj-j+1, i3 ) if( nw>0_${ik}$ )call stdlib${ii}$_${ri}$copy( nw, ab( kv+kl+1-jj+j, jj ), 1_${ik}$,work31( 1_${ik}$, jj-j+1 )& , 1_${ik}$ ) end do loop_80 if( j+jb<=n ) then ! apply the row interchanges to the other blocks. j2 = min( ju-j+1, kv ) - jb j3 = max( 0_${ik}$, ju-j-kv+1 ) ! use stdlib_${ri}$laswp to apply the row interchanges to a12, a22, and ! a32. call stdlib${ii}$_${ri}$laswp( j2, ab( kv+1-jb, j+jb ), ldab-1, 1_${ik}$, jb,ipiv( j ), 1_${ik}$ ) ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do ! apply the row interchanges to a13, a23, and a33 ! columnwise. k2 = j - 1_${ik}$ + jb + j2 do i = 1, j3 jj = k2 + i do ii = j + i - 1, j + jb - 1 ip = ipiv( ii ) if( ip/=ii ) then temp = ab( kv+1+ii-jj, jj ) ab( kv+1+ii-jj, jj ) = ab( kv+1+ip-jj, jj ) ab( kv+1+ip-jj, jj ) = temp end if end do end do ! update the relevant part of the trailing submatrix if( j2>0_${ik}$ ) then ! update a12 call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j2, one, ab(& kv+1, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1 ) if( i2>0_${ik}$ ) then ! update a22 call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j2,jb, -one, ab( & kv+1+jb, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1, one,ab( kv+1, j+jb ), & ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a32 call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j2,jb, -one, & work31, ldwork,ab( kv+1-jb, j+jb ), ldab-1, one,ab( kv+kl+1-jb, j+jb ), & ldab-1 ) end if end if if( j3>0_${ik}$ ) then ! copy the lower triangle of a13 into the work array ! work13 do jj = 1, j3 do ii = jj, jb work13( ii, jj ) = ab( ii-jj+1, jj+j+kv-1 ) end do end do ! update a13 in the work array call stdlib${ii}$_${ri}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j3, one, ab(& kv+1, j ), ldab-1,work13, ldwork ) if( i2>0_${ik}$ ) then ! update a23 call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j3,jb, -one, ab( & kv+1+jb, j ), ldab-1,work13, ldwork, one, ab( 1_${ik}$+jb, j+kv ),ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a33 call stdlib${ii}$_${ri}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j3,jb, -one, & work31, ldwork, work13,ldwork, one, ab( 1_${ik}$+kl, j+kv ), ldab-1 ) end if ! copy the lower triangle of a13 back into place do jj = 1, j3 do ii = jj, jb ab( ii-jj+1, jj+j+kv-1 ) = work13( ii, jj ) end do end do end if else ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do end if ! partially undo the interchanges in the current block to ! restore the upper triangular form of a31 and copy the upper ! triangle of a31 back into place do jj = j + jb - 1, j, -1 jp = ipiv( jj ) - jj + 1_${ik}$ if( jp/=1_${ik}$ ) then ! apply interchange to columns j to jj-1 if( jp+jj-1<j+kl ) then ! the interchange does not affect a31 call stdlib${ii}$_${ri}$swap( jj-j, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j ),& ldab-1 ) else ! the interchange does affect a31 call stdlib${ii}$_${ri}$swap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-kl, & 1_${ik}$ ), ldwork ) end if end if ! copy the current column of a31 back into place nw = min( i3, jj-j+1 ) if( nw>0_${ik}$ )call stdlib${ii}$_${ri}$copy( nw, work31( 1_${ik}$, jj-j+1 ), 1_${ik}$,ab( kv+kl+1-jj+j, jj )& , 1_${ik}$ ) end do end do loop_180 end if return end subroutine stdlib${ii}$_${ri}$gbtrf #:endif #:endfor pure module subroutine stdlib${ii}$_cgbtrf( m, n, kl, ku, ab, ldab, ipiv, info ) !! CGBTRF computes an LU factorization of a complex m-by-n band matrix A !! using partial pivoting with row interchanges. !! This is the blocked 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(sp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: nbmax = 64_${ik}$ integer(${ik}$), parameter :: ldwork = nbmax+1 ! Local Scalars integer(${ik}$) :: i, i2, i3, ii, ip, j, j2, j3, jb, jj, jm, jp, ju, k2, km, kv, nb, & nw complex(sp) :: temp ! Local Arrays complex(sp) :: work13(ldwork,nbmax), work31(ldwork,nbmax) ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBTRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'CGBTRF', ' ', m, n, kl, ku ) ! the block size must not exceed the limit set by the size of the ! local arrays work13 and work31. nb = min( nb, nbmax ) if( nb<=1_${ik}$ .or. nb>kl ) then ! use unblocked code call stdlib${ii}$_cgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) else ! use blocked code ! czero the superdiagonal elements of the work array work13 do j = 1, nb do i = 1, j - 1 work13( i, j ) = czero end do end do ! czero the subdiagonal elements of the work array work31 do j = 1, nb do i = j + 1, nb work31( i, j ) = czero end do end do ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to czero do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = czero end do end do ! ju is the index of the last column affected by the current ! stage of the factorization ju = 1_${ik}$ loop_180: do j = 1, min( m, n ), nb jb = min( nb, min( m, n )-j+1 ) ! the active part of the matrix is partitioned ! a11 a12 a13 ! a21 a22 a23 ! a31 a32 a33 ! here a11, a21 and a31 denote the current block of jb columns ! which is about to be factorized. the number of rows in the ! partitioning are jb, i2, i3 respectively, and the numbers ! of columns are jb, j2, j3. the superdiagonal elements of a13 ! and the subdiagonal elements of a31 lie outside the band. i2 = min( kl-jb, m-j-jb+1 ) i3 = min( jb, m-j-kl+1 ) ! j2 and j3 are computed after ju has been updated. ! factorize the current block of jb columns loop_80: do jj = j, j + jb - 1 ! set fill-in elements in column jj+kv to czero if( jj+kv<=n ) then do i = 1, kl ab( i, jj+kv ) = czero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-jj ) jp = stdlib${ii}$_icamax( km+1, ab( kv+1, jj ), 1_${ik}$ ) ipiv( jj ) = jp + jj - j if( ab( kv+jp, jj )/=czero ) then ju = max( ju, min( jj+ku+jp-1, n ) ) if( jp/=1_${ik}$ ) then ! apply interchange to columns j to j+jb-1 if( jp+jj-1<j+kl ) then call stdlib${ii}$_cswap( jb, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j )& , ldab-1 ) else ! the interchange affects columns j to jj-1 of a31 ! which are stored in the work array work31 call stdlib${ii}$_cswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-& kl, 1_${ik}$ ), ldwork ) call stdlib${ii}$_cswap( j+jb-jj, ab( kv+1, jj ), ldab-1,ab( kv+jp, jj ), & ldab-1 ) end if end if ! compute multipliers call stdlib${ii}$_cscal( km, cone / ab( kv+1, jj ), ab( kv+2, jj ),1_${ik}$ ) ! update trailing submatrix within the band and within ! the current block. jm is the index of the last column ! which needs to be updated. jm = min( ju, j+jb-1 ) if( jm>jj )call stdlib${ii}$_cgeru( km, jm-jj, -cone, ab( kv+2, jj ), 1_${ik}$,ab( kv, & jj+1 ), ldab-1,ab( kv+1, jj+1 ), ldab-1 ) else ! if pivot is czero, set info to the index of the pivot ! unless a czero pivot has already been found. if( info==0_${ik}$ )info = jj end if ! copy current column of a31 into the work array work31 nw = min( jj-j+1, i3 ) if( nw>0_${ik}$ )call stdlib${ii}$_ccopy( nw, ab( kv+kl+1-jj+j, jj ), 1_${ik}$,work31( 1_${ik}$, jj-j+1 )& , 1_${ik}$ ) end do loop_80 if( j+jb<=n ) then ! apply the row interchanges to the other blocks. j2 = min( ju-j+1, kv ) - jb j3 = max( 0_${ik}$, ju-j-kv+1 ) ! use stdlib_claswp to apply the row interchanges to a12, a22, and ! a32. call stdlib${ii}$_claswp( j2, ab( kv+1-jb, j+jb ), ldab-1, 1_${ik}$, jb,ipiv( j ), 1_${ik}$ ) ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do ! apply the row interchanges to a13, a23, and a33 ! columnwise. k2 = j - 1_${ik}$ + jb + j2 do i = 1, j3 jj = k2 + i do ii = j + i - 1, j + jb - 1 ip = ipiv( ii ) if( ip/=ii ) then temp = ab( kv+1+ii-jj, jj ) ab( kv+1+ii-jj, jj ) = ab( kv+1+ip-jj, jj ) ab( kv+1+ip-jj, jj ) = temp end if end do end do ! update the relevant part of the trailing submatrix if( j2>0_${ik}$ ) then ! update a12 call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j2, cone, & ab( kv+1, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1 ) if( i2>0_${ik}$ ) then ! update a22 call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j2,jb, -cone, ab(& kv+1+jb, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1, cone,ab( kv+1, j+jb )& , ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a32 call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j2,jb, -cone, & work31, ldwork,ab( kv+1-jb, j+jb ), ldab-1, cone,ab( kv+kl+1-jb, j+jb ),& ldab-1 ) end if end if if( j3>0_${ik}$ ) then ! copy the lower triangle of a13 into the work array ! work13 do jj = 1, j3 do ii = jj, jb work13( ii, jj ) = ab( ii-jj+1, jj+j+kv-1 ) end do end do ! update a13 in the work array call stdlib${ii}$_ctrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j3, cone, & ab( kv+1, j ), ldab-1,work13, ldwork ) if( i2>0_${ik}$ ) then ! update a23 call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j3,jb, -cone, ab(& kv+1+jb, j ), ldab-1,work13, ldwork, cone, ab( 1_${ik}$+jb, j+kv ),ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a33 call stdlib${ii}$_cgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j3,jb, -cone, & work31, ldwork, work13,ldwork, cone, ab( 1_${ik}$+kl, j+kv ), ldab-1 ) end if ! copy the lower triangle of a13 back into place do jj = 1, j3 do ii = jj, jb ab( ii-jj+1, jj+j+kv-1 ) = work13( ii, jj ) end do end do end if else ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do end if ! partially undo the interchanges in the current block to ! restore the upper triangular form of a31 and copy the upper ! triangle of a31 back into place do jj = j + jb - 1, j, -1 jp = ipiv( jj ) - jj + 1_${ik}$ if( jp/=1_${ik}$ ) then ! apply interchange to columns j to jj-1 if( jp+jj-1<j+kl ) then ! the interchange does not affect a31 call stdlib${ii}$_cswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j ),& ldab-1 ) else ! the interchange does affect a31 call stdlib${ii}$_cswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-kl, & 1_${ik}$ ), ldwork ) end if end if ! copy the current column of a31 back into place nw = min( i3, jj-j+1 ) if( nw>0_${ik}$ )call stdlib${ii}$_ccopy( nw, work31( 1_${ik}$, jj-j+1 ), 1_${ik}$,ab( kv+kl+1-jj+j, jj )& , 1_${ik}$ ) end do end do loop_180 end if return end subroutine stdlib${ii}$_cgbtrf pure module subroutine stdlib${ii}$_zgbtrf( m, n, kl, ku, ab, ldab, ipiv, info ) !! ZGBTRF computes an LU factorization of a complex m-by-n band matrix A !! using partial pivoting with row interchanges. !! This is the blocked 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(dp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: nbmax = 64_${ik}$ integer(${ik}$), parameter :: ldwork = nbmax+1 ! Local Scalars integer(${ik}$) :: i, i2, i3, ii, ip, j, j2, j3, jb, jj, jm, jp, ju, k2, km, kv, nb, & nw complex(dp) :: temp ! Local Arrays complex(dp) :: work13(ldwork,nbmax), work31(ldwork,nbmax) ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBTRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGBTRF', ' ', m, n, kl, ku ) ! the block size must not exceed the limit set by the size of the ! local arrays work13 and work31. nb = min( nb, nbmax ) if( nb<=1_${ik}$ .or. nb>kl ) then ! use unblocked code call stdlib${ii}$_zgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) else ! use blocked code ! czero the superdiagonal elements of the work array work13 do j = 1, nb do i = 1, j - 1 work13( i, j ) = czero end do end do ! czero the subdiagonal elements of the work array work31 do j = 1, nb do i = j + 1, nb work31( i, j ) = czero end do end do ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to czero do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = czero end do end do ! ju is the index of the last column affected by the current ! stage of the factorization ju = 1_${ik}$ loop_180: do j = 1, min( m, n ), nb jb = min( nb, min( m, n )-j+1 ) ! the active part of the matrix is partitioned ! a11 a12 a13 ! a21 a22 a23 ! a31 a32 a33 ! here a11, a21 and a31 denote the current block of jb columns ! which is about to be factorized. the number of rows in the ! partitioning are jb, i2, i3 respectively, and the numbers ! of columns are jb, j2, j3. the superdiagonal elements of a13 ! and the subdiagonal elements of a31 lie outside the band. i2 = min( kl-jb, m-j-jb+1 ) i3 = min( jb, m-j-kl+1 ) ! j2 and j3 are computed after ju has been updated. ! factorize the current block of jb columns loop_80: do jj = j, j + jb - 1 ! set fill-in elements in column jj+kv to czero if( jj+kv<=n ) then do i = 1, kl ab( i, jj+kv ) = czero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-jj ) jp = stdlib${ii}$_izamax( km+1, ab( kv+1, jj ), 1_${ik}$ ) ipiv( jj ) = jp + jj - j if( ab( kv+jp, jj )/=czero ) then ju = max( ju, min( jj+ku+jp-1, n ) ) if( jp/=1_${ik}$ ) then ! apply interchange to columns j to j+jb-1 if( jp+jj-1<j+kl ) then call stdlib${ii}$_zswap( jb, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j )& , ldab-1 ) else ! the interchange affects columns j to jj-1 of a31 ! which are stored in the work array work31 call stdlib${ii}$_zswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-& kl, 1_${ik}$ ), ldwork ) call stdlib${ii}$_zswap( j+jb-jj, ab( kv+1, jj ), ldab-1,ab( kv+jp, jj ), & ldab-1 ) end if end if ! compute multipliers call stdlib${ii}$_zscal( km, cone / ab( kv+1, jj ), ab( kv+2, jj ),1_${ik}$ ) ! update trailing submatrix within the band and within ! the current block. jm is the index of the last column ! which needs to be updated. jm = min( ju, j+jb-1 ) if( jm>jj )call stdlib${ii}$_zgeru( km, jm-jj, -cone, ab( kv+2, jj ), 1_${ik}$,ab( kv, & jj+1 ), ldab-1,ab( kv+1, jj+1 ), ldab-1 ) else ! if pivot is czero, set info to the index of the pivot ! unless a czero pivot has already been found. if( info==0_${ik}$ )info = jj end if ! copy current column of a31 into the work array work31 nw = min( jj-j+1, i3 ) if( nw>0_${ik}$ )call stdlib${ii}$_zcopy( nw, ab( kv+kl+1-jj+j, jj ), 1_${ik}$,work31( 1_${ik}$, jj-j+1 )& , 1_${ik}$ ) end do loop_80 if( j+jb<=n ) then ! apply the row interchanges to the other blocks. j2 = min( ju-j+1, kv ) - jb j3 = max( 0_${ik}$, ju-j-kv+1 ) ! use stdlib_zlaswp to apply the row interchanges to a12, a22, and ! a32. call stdlib${ii}$_zlaswp( j2, ab( kv+1-jb, j+jb ), ldab-1, 1_${ik}$, jb,ipiv( j ), 1_${ik}$ ) ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do ! apply the row interchanges to a13, a23, and a33 ! columnwise. k2 = j - 1_${ik}$ + jb + j2 do i = 1, j3 jj = k2 + i do ii = j + i - 1, j + jb - 1 ip = ipiv( ii ) if( ip/=ii ) then temp = ab( kv+1+ii-jj, jj ) ab( kv+1+ii-jj, jj ) = ab( kv+1+ip-jj, jj ) ab( kv+1+ip-jj, jj ) = temp end if end do end do ! update the relevant part of the trailing submatrix if( j2>0_${ik}$ ) then ! update a12 call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j2, cone, & ab( kv+1, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1 ) if( i2>0_${ik}$ ) then ! update a22 call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j2,jb, -cone, ab(& kv+1+jb, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1, cone,ab( kv+1, j+jb )& , ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a32 call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j2,jb, -cone, & work31, ldwork,ab( kv+1-jb, j+jb ), ldab-1, cone,ab( kv+kl+1-jb, j+jb ),& ldab-1 ) end if end if if( j3>0_${ik}$ ) then ! copy the lower triangle of a13 into the work array ! work13 do jj = 1, j3 do ii = jj, jb work13( ii, jj ) = ab( ii-jj+1, jj+j+kv-1 ) end do end do ! update a13 in the work array call stdlib${ii}$_ztrsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j3, cone, & ab( kv+1, j ), ldab-1,work13, ldwork ) if( i2>0_${ik}$ ) then ! update a23 call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j3,jb, -cone, ab(& kv+1+jb, j ), ldab-1,work13, ldwork, cone, ab( 1_${ik}$+jb, j+kv ),ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a33 call stdlib${ii}$_zgemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j3,jb, -cone, & work31, ldwork, work13,ldwork, cone, ab( 1_${ik}$+kl, j+kv ), ldab-1 ) end if ! copy the lower triangle of a13 back into place do jj = 1, j3 do ii = jj, jb ab( ii-jj+1, jj+j+kv-1 ) = work13( ii, jj ) end do end do end if else ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do end if ! partially undo the interchanges in the current block to ! restore the upper triangular form of a31 and copy the upper ! triangle of a31 back into place do jj = j + jb - 1, j, -1 jp = ipiv( jj ) - jj + 1_${ik}$ if( jp/=1_${ik}$ ) then ! apply interchange to columns j to jj-1 if( jp+jj-1<j+kl ) then ! the interchange does not affect a31 call stdlib${ii}$_zswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j ),& ldab-1 ) else ! the interchange does affect a31 call stdlib${ii}$_zswap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-kl, & 1_${ik}$ ), ldwork ) end if end if ! copy the current column of a31 back into place nw = min( i3, jj-j+1 ) if( nw>0_${ik}$ )call stdlib${ii}$_zcopy( nw, work31( 1_${ik}$, jj-j+1 ), 1_${ik}$,ab( kv+kl+1-jj+j, jj )& , 1_${ik}$ ) end do end do loop_180 end if return end subroutine stdlib${ii}$_zgbtrf #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbtrf( m, n, kl, ku, ab, ldab, ipiv, info ) !! ZGBTRF: computes an LU factorization of a complex m-by-n band matrix A !! using partial pivoting with row interchanges. !! This is the blocked 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(${ck}$), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: nbmax = 64_${ik}$ integer(${ik}$), parameter :: ldwork = nbmax+1 ! Local Scalars integer(${ik}$) :: i, i2, i3, ii, ip, j, j2, j3, jb, jj, jm, jp, ju, k2, km, kv, nb, & nw complex(${ck}$) :: temp ! Local Arrays complex(${ck}$) :: work13(ldwork,nbmax), work31(ldwork,nbmax) ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBTRF', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! determine the block size for this environment nb = stdlib${ii}$_ilaenv( 1_${ik}$, 'ZGBTRF', ' ', m, n, kl, ku ) ! the block size must not exceed the limit set by the size of the ! local arrays work13 and work31. nb = min( nb, nbmax ) if( nb<=1_${ik}$ .or. nb>kl ) then ! use unblocked code call stdlib${ii}$_${ci}$gbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) else ! use blocked code ! czero the superdiagonal elements of the work array work13 do j = 1, nb do i = 1, j - 1 work13( i, j ) = czero end do end do ! czero the subdiagonal elements of the work array work31 do j = 1, nb do i = j + 1, nb work31( i, j ) = czero end do end do ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to czero do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = czero end do end do ! ju is the index of the last column affected by the current ! stage of the factorization ju = 1_${ik}$ loop_180: do j = 1, min( m, n ), nb jb = min( nb, min( m, n )-j+1 ) ! the active part of the matrix is partitioned ! a11 a12 a13 ! a21 a22 a23 ! a31 a32 a33 ! here a11, a21 and a31 denote the current block of jb columns ! which is about to be factorized. the number of rows in the ! partitioning are jb, i2, i3 respectively, and the numbers ! of columns are jb, j2, j3. the superdiagonal elements of a13 ! and the subdiagonal elements of a31 lie outside the band. i2 = min( kl-jb, m-j-jb+1 ) i3 = min( jb, m-j-kl+1 ) ! j2 and j3 are computed after ju has been updated. ! factorize the current block of jb columns loop_80: do jj = j, j + jb - 1 ! set fill-in elements in column jj+kv to czero if( jj+kv<=n ) then do i = 1, kl ab( i, jj+kv ) = czero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-jj ) jp = stdlib${ii}$_i${ci}$amax( km+1, ab( kv+1, jj ), 1_${ik}$ ) ipiv( jj ) = jp + jj - j if( ab( kv+jp, jj )/=czero ) then ju = max( ju, min( jj+ku+jp-1, n ) ) if( jp/=1_${ik}$ ) then ! apply interchange to columns j to j+jb-1 if( jp+jj-1<j+kl ) then call stdlib${ii}$_${ci}$swap( jb, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j )& , ldab-1 ) else ! the interchange affects columns j to jj-1 of a31 ! which are stored in the work array work31 call stdlib${ii}$_${ci}$swap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-& kl, 1_${ik}$ ), ldwork ) call stdlib${ii}$_${ci}$swap( j+jb-jj, ab( kv+1, jj ), ldab-1,ab( kv+jp, jj ), & ldab-1 ) end if end if ! compute multipliers call stdlib${ii}$_${ci}$scal( km, cone / ab( kv+1, jj ), ab( kv+2, jj ),1_${ik}$ ) ! update trailing submatrix within the band and within ! the current block. jm is the index of the last column ! which needs to be updated. jm = min( ju, j+jb-1 ) if( jm>jj )call stdlib${ii}$_${ci}$geru( km, jm-jj, -cone, ab( kv+2, jj ), 1_${ik}$,ab( kv, & jj+1 ), ldab-1,ab( kv+1, jj+1 ), ldab-1 ) else ! if pivot is czero, set info to the index of the pivot ! unless a czero pivot has already been found. if( info==0_${ik}$ )info = jj end if ! copy current column of a31 into the work array work31 nw = min( jj-j+1, i3 ) if( nw>0_${ik}$ )call stdlib${ii}$_${ci}$copy( nw, ab( kv+kl+1-jj+j, jj ), 1_${ik}$,work31( 1_${ik}$, jj-j+1 )& , 1_${ik}$ ) end do loop_80 if( j+jb<=n ) then ! apply the row interchanges to the other blocks. j2 = min( ju-j+1, kv ) - jb j3 = max( 0_${ik}$, ju-j-kv+1 ) ! use stdlib_${ci}$laswp to apply the row interchanges to a12, a22, and ! a32. call stdlib${ii}$_${ci}$laswp( j2, ab( kv+1-jb, j+jb ), ldab-1, 1_${ik}$, jb,ipiv( j ), 1_${ik}$ ) ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do ! apply the row interchanges to a13, a23, and a33 ! columnwise. k2 = j - 1_${ik}$ + jb + j2 do i = 1, j3 jj = k2 + i do ii = j + i - 1, j + jb - 1 ip = ipiv( ii ) if( ip/=ii ) then temp = ab( kv+1+ii-jj, jj ) ab( kv+1+ii-jj, jj ) = ab( kv+1+ip-jj, jj ) ab( kv+1+ip-jj, jj ) = temp end if end do end do ! update the relevant part of the trailing submatrix if( j2>0_${ik}$ ) then ! update a12 call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j2, cone, & ab( kv+1, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1 ) if( i2>0_${ik}$ ) then ! update a22 call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j2,jb, -cone, ab(& kv+1+jb, j ), ldab-1,ab( kv+1-jb, j+jb ), ldab-1, cone,ab( kv+1, j+jb )& , ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a32 call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j2,jb, -cone, & work31, ldwork,ab( kv+1-jb, j+jb ), ldab-1, cone,ab( kv+kl+1-jb, j+jb ),& ldab-1 ) end if end if if( j3>0_${ik}$ ) then ! copy the lower triangle of a13 into the work array ! work13 do jj = 1, j3 do ii = jj, jb work13( ii, jj ) = ab( ii-jj+1, jj+j+kv-1 ) end do end do ! update a13 in the work array call stdlib${ii}$_${ci}$trsm( 'LEFT', 'LOWER', 'NO TRANSPOSE', 'UNIT',jb, j3, cone, & ab( kv+1, j ), ldab-1,work13, ldwork ) if( i2>0_${ik}$ ) then ! update a23 call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i2, j3,jb, -cone, ab(& kv+1+jb, j ), ldab-1,work13, ldwork, cone, ab( 1_${ik}$+jb, j+kv ),ldab-1 ) end if if( i3>0_${ik}$ ) then ! update a33 call stdlib${ii}$_${ci}$gemm( 'NO TRANSPOSE', 'NO TRANSPOSE', i3, j3,jb, -cone, & work31, ldwork, work13,ldwork, cone, ab( 1_${ik}$+kl, j+kv ), ldab-1 ) end if ! copy the lower triangle of a13 back into place do jj = 1, j3 do ii = jj, jb ab( ii-jj+1, jj+j+kv-1 ) = work13( ii, jj ) end do end do end if else ! adjust the pivot indices. do i = j, j + jb - 1 ipiv( i ) = ipiv( i ) + j - 1_${ik}$ end do end if ! partially undo the interchanges in the current block to ! restore the upper triangular form of a31 and copy the upper ! triangle of a31 back into place do jj = j + jb - 1, j, -1 jp = ipiv( jj ) - jj + 1_${ik}$ if( jp/=1_${ik}$ ) then ! apply interchange to columns j to jj-1 if( jp+jj-1<j+kl ) then ! the interchange does not affect a31 call stdlib${ii}$_${ci}$swap( jj-j, ab( kv+1+jj-j, j ), ldab-1,ab( kv+jp+jj-j, j ),& ldab-1 ) else ! the interchange does affect a31 call stdlib${ii}$_${ci}$swap( jj-j, ab( kv+1+jj-j, j ), ldab-1,work31( jp+jj-j-kl, & 1_${ik}$ ), ldwork ) end if end if ! copy the current column of a31 back into place nw = min( i3, jj-j+1 ) if( nw>0_${ik}$ )call stdlib${ii}$_${ci}$copy( nw, work31( 1_${ik}$, jj-j+1 ), 1_${ik}$,ab( kv+kl+1-jj+j, jj )& , 1_${ik}$ ) end do end do loop_180 end if return end subroutine stdlib${ii}$_${ci}$gbtrf #:endif #:endfor pure module subroutine stdlib${ii}$_sgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) !! SGBTF2 computes an LU factorization of a real m-by-n band matrix A !! using partial pivoting with row interchanges. !! 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(sp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, jp, ju, km, kv ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in. kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBTF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to zero. do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = zero end do end do ! ju is the index of the last column affected by the current stage ! of the factorization. ju = 1_${ik}$ loop_40: do j = 1, min( m, n ) ! set fill-in elements in column j+kv to zero. if( j+kv<=n ) then do i = 1, kl ab( i, j+kv ) = zero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-j ) jp = stdlib${ii}$_isamax( km+1, ab( kv+1, j ), 1_${ik}$ ) ipiv( j ) = jp + j - 1_${ik}$ if( ab( kv+jp, j )/=zero ) then ju = max( ju, min( j+ku+jp-1, n ) ) ! apply interchange to columns j to ju. if( jp/=1_${ik}$ )call stdlib${ii}$_sswap( ju-j+1, ab( kv+jp, j ), ldab-1,ab( kv+1, j ), ldab-& 1_${ik}$ ) if( km>0_${ik}$ ) then ! compute multipliers. call stdlib${ii}$_sscal( km, one / ab( kv+1, j ), ab( kv+2, j ), 1_${ik}$ ) ! update trailing submatrix within the band. if( ju>j )call stdlib${ii}$_sger( km, ju-j, -one, ab( kv+2, j ), 1_${ik}$,ab( kv, j+1 ), & ldab-1, ab( kv+1, j+1 ),ldab-1 ) end if else ! if pivot is zero, set info to the index of the pivot ! unless a zero pivot has already been found. if( info==0_${ik}$ )info = j end if end do loop_40 return end subroutine stdlib${ii}$_sgbtf2 pure module subroutine stdlib${ii}$_dgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) !! DGBTF2 computes an LU factorization of a real m-by-n band matrix A !! using partial pivoting with row interchanges. !! 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(dp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, jp, ju, km, kv ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in. kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBTF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to zero. do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = zero end do end do ! ju is the index of the last column affected by the current stage ! of the factorization. ju = 1_${ik}$ loop_40: do j = 1, min( m, n ) ! set fill-in elements in column j+kv to zero. if( j+kv<=n ) then do i = 1, kl ab( i, j+kv ) = zero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-j ) jp = stdlib${ii}$_idamax( km+1, ab( kv+1, j ), 1_${ik}$ ) ipiv( j ) = jp + j - 1_${ik}$ if( ab( kv+jp, j )/=zero ) then ju = max( ju, min( j+ku+jp-1, n ) ) ! apply interchange to columns j to ju. if( jp/=1_${ik}$ )call stdlib${ii}$_dswap( ju-j+1, ab( kv+jp, j ), ldab-1,ab( kv+1, j ), ldab-& 1_${ik}$ ) if( km>0_${ik}$ ) then ! compute multipliers. call stdlib${ii}$_dscal( km, one / ab( kv+1, j ), ab( kv+2, j ), 1_${ik}$ ) ! update trailing submatrix within the band. if( ju>j )call stdlib${ii}$_dger( km, ju-j, -one, ab( kv+2, j ), 1_${ik}$,ab( kv, j+1 ), & ldab-1, ab( kv+1, j+1 ),ldab-1 ) end if else ! if pivot is zero, set info to the index of the pivot ! unless a zero pivot has already been found. if( info==0_${ik}$ )info = j end if end do loop_40 return end subroutine stdlib${ii}$_dgbtf2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) !! DGBTF2: computes an LU factorization of a real m-by-n band matrix A !! using partial pivoting with row interchanges. !! 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) real(${rk}$), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, jp, ju, km, kv ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in. kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBTF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to zero. do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = zero end do end do ! ju is the index of the last column affected by the current stage ! of the factorization. ju = 1_${ik}$ loop_40: do j = 1, min( m, n ) ! set fill-in elements in column j+kv to zero. if( j+kv<=n ) then do i = 1, kl ab( i, j+kv ) = zero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-j ) jp = stdlib${ii}$_i${ri}$amax( km+1, ab( kv+1, j ), 1_${ik}$ ) ipiv( j ) = jp + j - 1_${ik}$ if( ab( kv+jp, j )/=zero ) then ju = max( ju, min( j+ku+jp-1, n ) ) ! apply interchange to columns j to ju. if( jp/=1_${ik}$ )call stdlib${ii}$_${ri}$swap( ju-j+1, ab( kv+jp, j ), ldab-1,ab( kv+1, j ), ldab-& 1_${ik}$ ) if( km>0_${ik}$ ) then ! compute multipliers. call stdlib${ii}$_${ri}$scal( km, one / ab( kv+1, j ), ab( kv+2, j ), 1_${ik}$ ) ! update trailing submatrix within the band. if( ju>j )call stdlib${ii}$_${ri}$ger( km, ju-j, -one, ab( kv+2, j ), 1_${ik}$,ab( kv, j+1 ), & ldab-1, ab( kv+1, j+1 ),ldab-1 ) end if else ! if pivot is zero, set info to the index of the pivot ! unless a zero pivot has already been found. if( info==0_${ik}$ )info = j end if end do loop_40 return end subroutine stdlib${ii}$_${ri}$gbtf2 #:endif #:endfor pure module subroutine stdlib${ii}$_cgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) !! CGBTF2 computes an LU factorization of a complex m-by-n band matrix !! A using partial pivoting with row interchanges. !! 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(sp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, jp, ju, km, kv ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in. kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBTF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to czero. do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = czero end do end do ! ju is the index of the last column affected by the current stage ! of the factorization. ju = 1_${ik}$ loop_40: do j = 1, min( m, n ) ! set fill-in elements in column j+kv to czero. if( j+kv<=n ) then do i = 1, kl ab( i, j+kv ) = czero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-j ) jp = stdlib${ii}$_icamax( km+1, ab( kv+1, j ), 1_${ik}$ ) ipiv( j ) = jp + j - 1_${ik}$ if( ab( kv+jp, j )/=czero ) then ju = max( ju, min( j+ku+jp-1, n ) ) ! apply interchange to columns j to ju. if( jp/=1_${ik}$ )call stdlib${ii}$_cswap( ju-j+1, ab( kv+jp, j ), ldab-1,ab( kv+1, j ), ldab-& 1_${ik}$ ) if( km>0_${ik}$ ) then ! compute multipliers. call stdlib${ii}$_cscal( km, cone / ab( kv+1, j ), ab( kv+2, j ), 1_${ik}$ ) ! update trailing submatrix within the band. if( ju>j )call stdlib${ii}$_cgeru( km, ju-j, -cone, ab( kv+2, j ), 1_${ik}$,ab( kv, j+1 ), & ldab-1, ab( kv+1, j+1 ),ldab-1 ) end if else ! if pivot is czero, set info to the index of the pivot ! unless a czero pivot has already been found. if( info==0_${ik}$ )info = j end if end do loop_40 return end subroutine stdlib${ii}$_cgbtf2 pure module subroutine stdlib${ii}$_zgbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) !! ZGBTF2 computes an LU factorization of a complex m-by-n band matrix !! A using partial pivoting with row interchanges. !! 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(dp), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, jp, ju, km, kv ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in. kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBTF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to czero. do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = czero end do end do ! ju is the index of the last column affected by the current stage ! of the factorization. ju = 1_${ik}$ loop_40: do j = 1, min( m, n ) ! set fill-in elements in column j+kv to czero. if( j+kv<=n ) then do i = 1, kl ab( i, j+kv ) = czero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-j ) jp = stdlib${ii}$_izamax( km+1, ab( kv+1, j ), 1_${ik}$ ) ipiv( j ) = jp + j - 1_${ik}$ if( ab( kv+jp, j )/=czero ) then ju = max( ju, min( j+ku+jp-1, n ) ) ! apply interchange to columns j to ju. if( jp/=1_${ik}$ )call stdlib${ii}$_zswap( ju-j+1, ab( kv+jp, j ), ldab-1,ab( kv+1, j ), ldab-& 1_${ik}$ ) if( km>0_${ik}$ ) then ! compute multipliers. call stdlib${ii}$_zscal( km, cone / ab( kv+1, j ), ab( kv+2, j ), 1_${ik}$ ) ! update trailing submatrix within the band. if( ju>j )call stdlib${ii}$_zgeru( km, ju-j, -cone, ab( kv+2, j ), 1_${ik}$,ab( kv, j+1 ), & ldab-1, ab( kv+1, j+1 ),ldab-1 ) end if else ! if pivot is czero, set info to the index of the pivot ! unless a czero pivot has already been found. if( info==0_${ik}$ )info = j end if end do loop_40 return end subroutine stdlib${ii}$_zgbtf2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbtf2( m, n, kl, ku, ab, ldab, ipiv, info ) !! ZGBTF2: computes an LU factorization of a complex m-by-n band matrix !! A using partial pivoting with row interchanges. !! 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 integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, m, n ! Array Arguments integer(${ik}$), intent(out) :: ipiv(*) complex(${ck}$), intent(inout) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, jp, ju, km, kv ! Intrinsic Functions ! Executable Statements ! kv is the number of superdiagonals in the factor u, allowing for ! fill-in. kv = ku + kl ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+kv+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBTF2', -info ) return end if ! quick return if possible if( m==0 .or. n==0 )return ! gaussian elimination with partial pivoting ! set fill-in elements in columns ku+2 to kv to czero. do j = ku + 2, min( kv, n ) do i = kv - j + 2, kl ab( i, j ) = czero end do end do ! ju is the index of the last column affected by the current stage ! of the factorization. ju = 1_${ik}$ loop_40: do j = 1, min( m, n ) ! set fill-in elements in column j+kv to czero. if( j+kv<=n ) then do i = 1, kl ab( i, j+kv ) = czero end do end if ! find pivot and test for singularity. km is the number of ! subdiagonal elements in the current column. km = min( kl, m-j ) jp = stdlib${ii}$_i${ci}$amax( km+1, ab( kv+1, j ), 1_${ik}$ ) ipiv( j ) = jp + j - 1_${ik}$ if( ab( kv+jp, j )/=czero ) then ju = max( ju, min( j+ku+jp-1, n ) ) ! apply interchange to columns j to ju. if( jp/=1_${ik}$ )call stdlib${ii}$_${ci}$swap( ju-j+1, ab( kv+jp, j ), ldab-1,ab( kv+1, j ), ldab-& 1_${ik}$ ) if( km>0_${ik}$ ) then ! compute multipliers. call stdlib${ii}$_${ci}$scal( km, cone / ab( kv+1, j ), ab( kv+2, j ), 1_${ik}$ ) ! update trailing submatrix within the band. if( ju>j )call stdlib${ii}$_${ci}$geru( km, ju-j, -cone, ab( kv+2, j ), 1_${ik}$,ab( kv, j+1 ), & ldab-1, ab( kv+1, j+1 ),ldab-1 ) end if else ! if pivot is czero, set info to the index of the pivot ! unless a czero pivot has already been found. if( info==0_${ik}$ )info = j end if end do loop_40 return end subroutine stdlib${ii}$_${ci}$gbtf2 #:endif #:endfor pure module subroutine stdlib${ii}$_sgbtrs( trans, n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb,info ) !! SGBTRS solves a system of linear equations !! A * X = B or A**T * X = B !! with a general band matrix A using the LU factorization computed !! by SGBTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(in) :: ab(ldab,*) real(sp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, notran integer(${ik}$) :: i, j, kd, l, lm ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<( 2_${ik}$*kl+ku+1 ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return kd = ku + kl + 1_${ik}$ lnoti = kl>0_${ik}$ if( notran ) then ! solve a*x = b. ! solve l*x = b, overwriting b with x. ! l is represented as a product of permutations and unit lower ! triangular matrices l = p(1) * l(1) * ... * p(n-1) * l(n-1), ! where each transformation l(i) is a rank-one modification of ! the identity matrix. if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_sswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_sger( lm, nrhs, -one, ab( kd+1, j ), 1_${ik}$, b( j, 1_${ik}$ ),ldb, b( j+1, 1_${ik}$ )& , ldb ) end do end if do i = 1, nrhs ! solve u*x = b, overwriting b with x. call stdlib${ii}$_stbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kl+ku,ab, ldab, b( 1_${ik}$, & i ), 1_${ik}$ ) end do else ! solve a**t*x = b. do i = 1, nrhs ! solve u**t*x = b, overwriting b with x. call stdlib${ii}$_stbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kl+ku, ab,ldab, b( 1_${ik}$, i )& , 1_${ik}$ ) end do ! solve l**t*x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_sgemv( 'TRANSPOSE', lm, nrhs, -one, b( j+1, 1_${ik}$ ),ldb, ab( kd+1, j )& , 1_${ik}$, one, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_sswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if end if return end subroutine stdlib${ii}$_sgbtrs pure module subroutine stdlib${ii}$_dgbtrs( trans, n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb,info ) !! DGBTRS solves a system of linear equations !! A * X = B or A**T * X = B !! with a general band matrix A using the LU factorization computed !! by DGBTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(in) :: ab(ldab,*) real(dp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, notran integer(${ik}$) :: i, j, kd, l, lm ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<( 2_${ik}$*kl+ku+1 ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return kd = ku + kl + 1_${ik}$ lnoti = kl>0_${ik}$ if( notran ) then ! solve a*x = b. ! solve l*x = b, overwriting b with x. ! l is represented as a product of permutations and unit lower ! triangular matrices l = p(1) * l(1) * ... * p(n-1) * l(n-1), ! where each transformation l(i) is a rank-one modification of ! the identity matrix. if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_dswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_dger( lm, nrhs, -one, ab( kd+1, j ), 1_${ik}$, b( j, 1_${ik}$ ),ldb, b( j+1, 1_${ik}$ )& , ldb ) end do end if do i = 1, nrhs ! solve u*x = b, overwriting b with x. call stdlib${ii}$_dtbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kl+ku,ab, ldab, b( 1_${ik}$, & i ), 1_${ik}$ ) end do else ! solve a**t*x = b. do i = 1, nrhs ! solve u**t*x = b, overwriting b with x. call stdlib${ii}$_dtbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kl+ku, ab,ldab, b( 1_${ik}$, i )& , 1_${ik}$ ) end do ! solve l**t*x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_dgemv( 'TRANSPOSE', lm, nrhs, -one, b( j+1, 1_${ik}$ ),ldb, ab( kd+1, j )& , 1_${ik}$, one, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_dswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if end if return end subroutine stdlib${ii}$_dgbtrs #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbtrs( trans, n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb,info ) !! DGBTRS: solves a system of linear equations !! A * X = B or A**T * X = B !! with a general band matrix A using the LU factorization computed !! by DGBTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(in) :: ab(ldab,*) real(${rk}$), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, notran integer(${ik}$) :: i, j, kd, l, lm ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<( 2_${ik}$*kl+ku+1 ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return kd = ku + kl + 1_${ik}$ lnoti = kl>0_${ik}$ if( notran ) then ! solve a*x = b. ! solve l*x = b, overwriting b with x. ! l is represented as a product of permutations and unit lower ! triangular matrices l = p(1) * l(1) * ... * p(n-1) * l(n-1), ! where each transformation l(i) is a rank-one modification of ! the identity matrix. if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_${ri}$swap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_${ri}$ger( lm, nrhs, -one, ab( kd+1, j ), 1_${ik}$, b( j, 1_${ik}$ ),ldb, b( j+1, 1_${ik}$ )& , ldb ) end do end if do i = 1, nrhs ! solve u*x = b, overwriting b with x. call stdlib${ii}$_${ri}$tbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kl+ku,ab, ldab, b( 1_${ik}$, & i ), 1_${ik}$ ) end do else ! solve a**t*x = b. do i = 1, nrhs ! solve u**t*x = b, overwriting b with x. call stdlib${ii}$_${ri}$tbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kl+ku, ab,ldab, b( 1_${ik}$, i )& , 1_${ik}$ ) end do ! solve l**t*x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_${ri}$gemv( 'TRANSPOSE', lm, nrhs, -one, b( j+1, 1_${ik}$ ),ldb, ab( kd+1, j )& , 1_${ik}$, one, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_${ri}$swap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if end if return end subroutine stdlib${ii}$_${ri}$gbtrs #:endif #:endfor pure module subroutine stdlib${ii}$_cgbtrs( trans, n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb,info ) !! CGBTRS solves a system of linear equations !! A * X = B, A**T * X = B, or A**H * X = B !! with a general band matrix A using the LU factorization computed !! by CGBTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(sp), intent(in) :: ab(ldab,*) complex(sp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, notran integer(${ik}$) :: i, j, kd, l, lm ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<( 2_${ik}$*kl+ku+1 ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return kd = ku + kl + 1_${ik}$ lnoti = kl>0_${ik}$ if( notran ) then ! solve a*x = b. ! solve l*x = b, overwriting b with x. ! l is represented as a product of permutations and unit lower ! triangular matrices l = p(1) * l(1) * ... * p(n-1) * l(n-1), ! where each transformation l(i) is a rank-cone modification of ! the identity matrix. if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_cswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_cgeru( lm, nrhs, -cone, ab( kd+1, j ), 1_${ik}$, b( j, 1_${ik}$ ),ldb, b( j+1, & 1_${ik}$ ), ldb ) end do end if do i = 1, nrhs ! solve u*x = b, overwriting b with x. call stdlib${ii}$_ctbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kl+ku,ab, ldab, b( 1_${ik}$, & i ), 1_${ik}$ ) end do else if( stdlib_lsame( trans, 'T' ) ) then ! solve a**t * x = b. do i = 1, nrhs ! solve u**t * x = b, overwriting b with x. call stdlib${ii}$_ctbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kl+ku, ab,ldab, b( 1_${ik}$, i )& , 1_${ik}$ ) end do ! solve l**t * x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_cgemv( 'TRANSPOSE', lm, nrhs, -cone, b( j+1, 1_${ik}$ ),ldb, ab( kd+1, j & ), 1_${ik}$, cone, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_cswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if else ! solve a**h * x = b. do i = 1, nrhs ! solve u**h * x = b, overwriting b with x. call stdlib${ii}$_ctbsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kl+ku, ab, ldab,& b( 1_${ik}$, i ), 1_${ik}$ ) end do ! solve l**h * x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_clacgv( nrhs, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_cgemv( 'CONJUGATE TRANSPOSE', lm, nrhs, -cone,b( j+1, 1_${ik}$ ), ldb, & ab( kd+1, j ), 1_${ik}$, cone,b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_clacgv( nrhs, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_cswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if end if return end subroutine stdlib${ii}$_cgbtrs pure module subroutine stdlib${ii}$_zgbtrs( trans, n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb,info ) !! ZGBTRS solves a system of linear equations !! A * X = B, A**T * X = B, or A**H * X = B !! with a general band matrix A using the LU factorization computed !! by ZGBTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(dp), intent(in) :: ab(ldab,*) complex(dp), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, notran integer(${ik}$) :: i, j, kd, l, lm ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<( 2_${ik}$*kl+ku+1 ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return kd = ku + kl + 1_${ik}$ lnoti = kl>0_${ik}$ if( notran ) then ! solve a*x = b. ! solve l*x = b, overwriting b with x. ! l is represented as a product of permutations and unit lower ! triangular matrices l = p(1) * l(1) * ... * p(n-1) * l(n-1), ! where each transformation l(i) is a rank-cone modification of ! the identity matrix. if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_zswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_zgeru( lm, nrhs, -cone, ab( kd+1, j ), 1_${ik}$, b( j, 1_${ik}$ ),ldb, b( j+1, & 1_${ik}$ ), ldb ) end do end if do i = 1, nrhs ! solve u*x = b, overwriting b with x. call stdlib${ii}$_ztbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kl+ku,ab, ldab, b( 1_${ik}$, & i ), 1_${ik}$ ) end do else if( stdlib_lsame( trans, 'T' ) ) then ! solve a**t * x = b. do i = 1, nrhs ! solve u**t * x = b, overwriting b with x. call stdlib${ii}$_ztbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kl+ku, ab,ldab, b( 1_${ik}$, i )& , 1_${ik}$ ) end do ! solve l**t * x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_zgemv( 'TRANSPOSE', lm, nrhs, -cone, b( j+1, 1_${ik}$ ),ldb, ab( kd+1, j & ), 1_${ik}$, cone, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_zswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if else ! solve a**h * x = b. do i = 1, nrhs ! solve u**h * x = b, overwriting b with x. call stdlib${ii}$_ztbsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kl+ku, ab, ldab,& b( 1_${ik}$, i ), 1_${ik}$ ) end do ! solve l**h * x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_zlacgv( nrhs, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_zgemv( 'CONJUGATE TRANSPOSE', lm, nrhs, -cone,b( j+1, 1_${ik}$ ), ldb, & ab( kd+1, j ), 1_${ik}$, cone,b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_zlacgv( nrhs, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_zswap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if end if return end subroutine stdlib${ii}$_zgbtrs #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbtrs( trans, n, kl, ku, nrhs, ab, ldab, ipiv, b, ldb,info ) !! ZGBTRS: solves a system of linear equations !! A * X = B, A**T * X = B, or A**H * X = B !! with a general band matrix A using the LU factorization computed !! by ZGBTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(in) :: ab(ldab,*) complex(${ck}$), intent(inout) :: b(ldb,*) ! ===================================================================== ! Local Scalars logical(lk) :: lnoti, notran integer(${ik}$) :: i, j, kd, l, lm ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<( 2_${ik}$*kl+ku+1 ) ) then info = -7_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return kd = ku + kl + 1_${ik}$ lnoti = kl>0_${ik}$ if( notran ) then ! solve a*x = b. ! solve l*x = b, overwriting b with x. ! l is represented as a product of permutations and unit lower ! triangular matrices l = p(1) * l(1) * ... * p(n-1) * l(n-1), ! where each transformation l(i) is a rank-cone modification of ! the identity matrix. if( lnoti ) then do j = 1, n - 1 lm = min( kl, n-j ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_${ci}$swap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_${ci}$geru( lm, nrhs, -cone, ab( kd+1, j ), 1_${ik}$, b( j, 1_${ik}$ ),ldb, b( j+1, & 1_${ik}$ ), ldb ) end do end if do i = 1, nrhs ! solve u*x = b, overwriting b with x. call stdlib${ii}$_${ci}$tbsv( 'UPPER', 'NO TRANSPOSE', 'NON-UNIT', n, kl+ku,ab, ldab, b( 1_${ik}$, & i ), 1_${ik}$ ) end do else if( stdlib_lsame( trans, 'T' ) ) then ! solve a**t * x = b. do i = 1, nrhs ! solve u**t * x = b, overwriting b with x. call stdlib${ii}$_${ci}$tbsv( 'UPPER', 'TRANSPOSE', 'NON-UNIT', n, kl+ku, ab,ldab, b( 1_${ik}$, i )& , 1_${ik}$ ) end do ! solve l**t * x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_${ci}$gemv( 'TRANSPOSE', lm, nrhs, -cone, b( j+1, 1_${ik}$ ),ldb, ab( kd+1, j & ), 1_${ik}$, cone, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_${ci}$swap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if else ! solve a**h * x = b. do i = 1, nrhs ! solve u**h * x = b, overwriting b with x. call stdlib${ii}$_${ci}$tbsv( 'UPPER', 'CONJUGATE TRANSPOSE', 'NON-UNIT', n,kl+ku, ab, ldab,& b( 1_${ik}$, i ), 1_${ik}$ ) end do ! solve l**h * x = b, overwriting b with x. if( lnoti ) then do j = n - 1, 1, -1 lm = min( kl, n-j ) call stdlib${ii}$_${ci}$lacgv( nrhs, b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_${ci}$gemv( 'CONJUGATE TRANSPOSE', lm, nrhs, -cone,b( j+1, 1_${ik}$ ), ldb, & ab( kd+1, j ), 1_${ik}$, cone,b( j, 1_${ik}$ ), ldb ) call stdlib${ii}$_${ci}$lacgv( nrhs, b( j, 1_${ik}$ ), ldb ) l = ipiv( j ) if( l/=j )call stdlib${ii}$_${ci}$swap( nrhs, b( l, 1_${ik}$ ), ldb, b( j, 1_${ik}$ ), ldb ) end do end if end if return end subroutine stdlib${ii}$_${ci}$gbtrs #:endif #:endfor pure module subroutine stdlib${ii}$_sgbrfs( trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb,ipiv, b, ldb, x, & !! SGBRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is banded, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldafb, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transt integer(${ik}$) :: count, i, 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<kl+ku+1 ) then info = -7_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -9_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -14_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBRFS', -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 if( notran ) then transt = 'T' else transt = 'N' end if ! nz = maximum number of nonzero elements in each row of a, plus 1 nz = min( kl+ku+2, n+1 ) 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_scopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_sgbmv( trans, n, n, kl, ku, -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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n kk = ku + 1_${ik}$ - k xk = abs( x( k, j ) ) do i = max( 1, k-ku ), min( n, k+kl ) work( i ) = work( i ) + abs( ab( kk+i, k ) )*xk end do end do else do k = 1, n s = zero kk = ku + 1_${ik}$ - k do i = max( 1, k-ku ), min( n, k+kl ) s = s + abs( ab( kk+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}$_sgbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_slacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**t). call stdlib${ii}$_sgbtrs( transt, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work( n+1 ), n, & info ) do i = 1, n work( n+i ) = work( n+i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( n+i )*work( i ) end do call stdlib${ii}$_sgbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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}$_sgbrfs pure module subroutine stdlib${ii}$_dgbrfs( trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb,ipiv, b, ldb, x, & !! DGBRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is banded, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldafb, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transt integer(${ik}$) :: count, i, 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<kl+ku+1 ) then info = -7_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -9_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -14_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBRFS', -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 if( notran ) then transt = 'T' else transt = 'N' end if ! nz = maximum number of nonzero elements in each row of a, plus 1 nz = min( kl+ku+2, n+1 ) 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_dcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_dgbmv( trans, n, n, kl, ku, -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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n kk = ku + 1_${ik}$ - k xk = abs( x( k, j ) ) do i = max( 1, k-ku ), min( n, k+kl ) work( i ) = work( i ) + abs( ab( kk+i, k ) )*xk end do end do else do k = 1, n s = zero kk = ku + 1_${ik}$ - k do i = max( 1, k-ku ), min( n, k+kl ) s = s + abs( ab( kk+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}$_dgbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_dlacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**t). call stdlib${ii}$_dgbtrs( transt, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work( n+1 ), n, & info ) do i = 1, n work( n+i ) = work( n+i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( n+i )*work( i ) end do call stdlib${ii}$_dgbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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}$_dgbrfs #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbrfs( trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb,ipiv, b, ldb, x, & !! DGBRFS: improves the computed solution to a system of linear !! equations when the coefficient matrix is banded, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldafb, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transt integer(${ik}$) :: count, i, 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<kl+ku+1 ) then info = -7_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -9_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -14_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBRFS', -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 if( notran ) then transt = 'T' else transt = 'N' end if ! nz = maximum number of nonzero elements in each row of a, plus 1 nz = min( kl+ku+2, n+1 ) 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_${ri}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_${ri}$gbmv( trans, n, n, kl, ku, -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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n kk = ku + 1_${ik}$ - k xk = abs( x( k, j ) ) do i = max( 1, k-ku ), min( n, k+kl ) work( i ) = work( i ) + abs( ab( kk+i, k ) )*xk end do end do else do k = 1, n s = zero kk = ku + 1_${ik}$ - k do i = max( 1, k-ku ), min( n, k+kl ) s = s + abs( ab( kk+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}$gbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_${ri}$lacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**t). call stdlib${ii}$_${ri}$gbtrs( transt, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work( n+1 ), n, & info ) do i = 1, n work( n+i ) = work( n+i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( n+i )*work( i ) end do call stdlib${ii}$_${ri}$gbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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}$gbrfs #:endif #:endfor pure module subroutine stdlib${ii}$_cgbrfs( trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb,ipiv, b, ldb, x, & !! CGBRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is banded, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldafb, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transn, transt integer(${ik}$) :: count, i, 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<kl+ku+1 ) then info = -7_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -9_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -14_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBRFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' end if ! nz = maximum number of nonzero elements in each row of a, plus 1 nz = min( kl+ku+2, n+1 ) 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_ccopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_cgbmv( trans, n, n, kl, ku, -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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n kk = ku + 1_${ik}$ - k xk = cabs1( x( k, j ) ) do i = max( 1, k-ku ), min( n, k+kl ) rwork( i ) = rwork( i ) + cabs1( ab( kk+i, k ) )*xk end do end do else do k = 1, n s = zero kk = ku + 1_${ik}$ - k do i = max( 1, k-ku ), min( n, k+kl ) s = s + cabs1( ab( kk+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}$_cgbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_clacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**h). call stdlib${ii}$_cgbtrs( transt, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_cgbtrs( transn, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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}$_cgbrfs pure module subroutine stdlib${ii}$_zgbrfs( trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb,ipiv, b, ldb, x, & !! ZGBRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is banded, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldafb, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transn, transt integer(${ik}$) :: count, i, 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<kl+ku+1 ) then info = -7_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -9_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -14_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBRFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' end if ! nz = maximum number of nonzero elements in each row of a, plus 1 nz = min( kl+ku+2, n+1 ) 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_zcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_zgbmv( trans, n, n, kl, ku, -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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n kk = ku + 1_${ik}$ - k xk = cabs1( x( k, j ) ) do i = max( 1, k-ku ), min( n, k+kl ) rwork( i ) = rwork( i ) + cabs1( ab( kk+i, k ) )*xk end do end do else do k = 1, n s = zero kk = ku + 1_${ik}$ - k do i = max( 1, k-ku ), min( n, k+kl ) s = s + cabs1( ab( kk+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}$_zgbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_zlacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**h). call stdlib${ii}$_zgbtrs( transt, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_zgbtrs( transn, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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}$_zgbrfs #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbrfs( trans, n, kl, ku, nrhs, ab, ldab, afb, ldafb,ipiv, b, ldb, x, & !! ZGBRFS: improves the computed solution to a system of linear !! equations when the coefficient matrix is banded, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: kl, ku, ldab, ldafb, ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) 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) :: notran character :: transn, transt integer(${ik}$) :: count, i, 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( nrhs<0_${ik}$ ) then info = -5_${ik}$ else if( ldab<kl+ku+1 ) then info = -7_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -9_${ik}$ else if( ldb<max( 1_${ik}$, n ) ) then info = -12_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -14_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBRFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' end if ! nz = maximum number of nonzero elements in each row of a, plus 1 nz = min( kl+ku+2, n+1 ) 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 - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_${ci}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_${ci}$gbmv( trans, n, n, kl, ku, -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(op(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(op(a))*abs(x) + abs(b). if( notran ) then do k = 1, n kk = ku + 1_${ik}$ - k xk = cabs1( x( k, j ) ) do i = max( 1, k-ku ), min( n, k+kl ) rwork( i ) = rwork( i ) + cabs1( ab( kk+i, k ) )*xk end do end do else do k = 1, n s = zero kk = ku + 1_${ik}$ - k do i = max( 1, k-ku ), min( n, k+kl ) s = s + cabs1( ab( kk+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}$gbtrs( trans, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_${ci}$lacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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(op(a)**h). call stdlib${ii}$_${ci}$gbtrs( transt, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_${ci}$gbtrs( transn, n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,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}$gbrfs #:endif #:endfor pure module subroutine stdlib${ii}$_sgbequ( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! SGBEQU computes row and column scalings intended to equilibrate an !! M-by-N band matrix A and reduce its condition number. R returns the !! row scale factors and C the column scale factors, chosen to try to !! make the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack 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) :: kl, ku, ldab, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(in) :: ab(ldab,*) real(sp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(sp) :: bignum, rcmax, rcmin, smlnum ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), abs( ab( kd+i-j, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), abs( ab( kd+i-j, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_sgbequ pure module subroutine stdlib${ii}$_dgbequ( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! DGBEQU computes row and column scalings intended to equilibrate an !! M-by-N band matrix A and reduce its condition number. R returns the !! row scale factors and C the column scale factors, chosen to try to !! make the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack 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) :: kl, ku, ldab, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(in) :: ab(ldab,*) real(dp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(dp) :: bignum, rcmax, rcmin, smlnum ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), abs( ab( kd+i-j, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), abs( ab( kd+i-j, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_dgbequ #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbequ( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! DGBEQU: computes row and column scalings intended to equilibrate an !! M-by-N band matrix A and reduce its condition number. R returns the !! row scale factors and C the column scale factors, chosen to try to !! make the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack 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) :: kl, ku, ldab, m, n real(${rk}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${rk}$), intent(in) :: ab(ldab,*) real(${rk}$), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(${rk}$) :: bignum, rcmax, rcmin, smlnum ! Intrinsic Functions ! Executable Statements ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), abs( ab( kd+i-j, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), abs( ab( kd+i-j, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ri}$gbequ #:endif #:endfor pure module subroutine stdlib${ii}$_cgbequ( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! CGBEQU computes row and column scalings intended to equilibrate an !! M-by-N band matrix A and reduce its condition number. R returns the !! row scale factors and C the column scale factors, chosen to try to !! make the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack 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) :: kl, ku, ldab, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(out) :: c(*), r(*) complex(sp), intent(in) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(sp) :: bignum, rcmax, rcmin, smlnum 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 ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), cabs1( ab( kd+i-j, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), cabs1( ab( kd+i-j, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_cgbequ pure module subroutine stdlib${ii}$_zgbequ( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! ZGBEQU computes row and column scalings intended to equilibrate an !! M-by-N band matrix A and reduce its condition number. R returns the !! row scale factors and C the column scale factors, chosen to try to !! make the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack 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) :: kl, ku, ldab, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(out) :: c(*), r(*) complex(dp), intent(in) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(dp) :: bignum, rcmax, rcmin, smlnum 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 ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), cabs1( ab( kd+i-j, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), cabs1( ab( kd+i-j, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_zgbequ #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbequ( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! ZGBEQU: computes row and column scalings intended to equilibrate an !! M-by-N band matrix A and reduce its condition number. R returns the !! row scale factors and C the column scale factors, chosen to try to !! make the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have absolute value 1. !! R(i) and C(j) are restricted to be between SMLNUM = smallest safe !! number and BIGNUM = largest safe number. Use of these scaling !! factors is not guaranteed to reduce the condition number of A but !! works well in practice. ! -- lapack computational routine -- ! -- lapack 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) :: kl, ku, ldab, m, n real(${ck}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${ck}$), intent(out) :: c(*), r(*) complex(${ck}$), intent(in) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(${ck}$) :: bignum, rcmax, rcmin, smlnum 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 ! test the input parameters info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBEQU', -info ) return end if ! quick return if possible if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) bignum = one / smlnum ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), cabs1( ab( kd+i-j, j ) ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)) rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), cabs1( ab( kd+i-j, j ) )*r( i ) ) end do end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)) colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ci}$gbequ #:endif #:endfor pure module subroutine stdlib${ii}$_sgbequb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! SGBEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from SGEEQU 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 entries' magnitudes 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) :: kl, ku, ldab, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(in) :: ab(ldab,*) real(sp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(sp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGBEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_slamch( 'B' ) logrdx = log(radix) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), abs( ab( kd+i-j, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), abs( ab( kd+i-j, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_sgbequb pure module subroutine stdlib${ii}$_dgbequb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! DGBEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from DGEEQU 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 entries' magnitudes 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) :: kl, ku, ldab, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(in) :: ab(ldab,*) real(dp), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(dp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_dlamch( 'B' ) logrdx = log(radix) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), abs( ab( kd+i-j, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), abs( ab( kd+i-j, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_dgbequb #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gbequb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! DGBEQUB: computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from DGEEQU 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 entries' magnitudes 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) :: kl, ku, ldab, m, n real(${rk}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${rk}$), intent(in) :: ab(ldab,*) real(${rk}$), intent(out) :: c(*), r(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(${rk}$) :: bignum, rcmax, rcmin, smlnum, radix, logrdx ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGBEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_${ri}$lamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_${ri}$lamch( 'B' ) logrdx = log(radix) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), abs( ab( kd+i-j, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), abs( ab( kd+i-j, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ri}$gbequb #:endif #:endfor pure module subroutine stdlib${ii}$_cgbequb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! CGBEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from CGEEQU 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 entries' magnitudes 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) :: kl, ku, ldab, m, n real(sp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(out) :: c(*), r(*) complex(sp), intent(in) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(sp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGBEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_slamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_slamch( 'B' ) logrdx = log(radix) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), cabs1( ab( kd+i-j, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), cabs1( ab( kd+i-j, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_cgbequb pure module subroutine stdlib${ii}$_zgbequb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! ZGBEQUB computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from ZGEEQU 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 entries' magnitudes 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) :: kl, ku, ldab, m, n real(dp), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(out) :: c(*), r(*) complex(dp), intent(in) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(dp) :: bignum, rcmax, rcmin, smlnum, radix, logrdx 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_dlamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_dlamch( 'B' ) logrdx = log(radix) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), cabs1( ab( kd+i-j, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), cabs1( ab( kd+i-j, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_zgbequb #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gbequb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, info ) !! ZGBEQUB: computes row and column scalings intended to equilibrate an !! M-by-N matrix A and reduce its condition number. R returns the row !! scale factors and C the column scale factors, chosen to try to make !! the largest element in each row and column of the matrix B with !! elements B(i,j)=R(i)*A(i,j)*C(j) have an absolute value of at most !! the radix. !! R(i) and C(j) are restricted to be a power of the radix between !! SMLNUM = smallest safe number and BIGNUM = largest safe number. Use !! of these scaling factors is not guaranteed to reduce the condition !! number of A but works well in practice. !! This routine differs from ZGEEQU 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 entries' magnitudes 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) :: kl, ku, ldab, m, n real(${ck}$), intent(out) :: amax, colcnd, rowcnd ! Array Arguments real(${ck}$), intent(out) :: c(*), r(*) complex(${ck}$), intent(in) :: ab(ldab,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(${ck}$) :: bignum, rcmax, rcmin, smlnum, radix, logrdx 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 ! test the input parameters. info = 0_${ik}$ if( m<0_${ik}$ ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ ) then info = -3_${ik}$ else if( ku<0_${ik}$ ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGBEQUB', -info ) return end if ! quick return if possible. if( m==0_${ik}$ .or. n==0_${ik}$ ) then rowcnd = one colcnd = one amax = zero return end if ! get machine constants. assume smlnum is a power of the radix. smlnum = stdlib${ii}$_${c2ri(ci)}$lamch( 'S' ) bignum = one / smlnum radix = stdlib${ii}$_${c2ri(ci)}$lamch( 'B' ) logrdx = log(radix) ! compute row scale factors. do i = 1, m r( i ) = zero end do ! find the maximum element in each row. kd = ku + 1_${ik}$ do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) r( i ) = max( r( i ), cabs1( ab( kd+i-j, j ) ) ) end do end do do i = 1, m if( r( i )>zero ) then r( i ) = radix**int( log( r( i ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do i = 1, m rcmax = max( rcmax, r( i ) ) rcmin = min( rcmin, r( i ) ) end do amax = rcmax if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do i = 1, m if( r( i )==zero ) then info = i return end if end do else ! invert the scale factors. do i = 1, m r( i ) = one / min( max( r( i ), smlnum ), bignum ) end do ! compute rowcnd = min(r(i)) / max(r(i)). rowcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if ! compute column scale factors. do j = 1, n c( j ) = zero end do ! find the maximum element in each column, ! assuming the row scaling computed above. do j = 1, n do i = max( j-ku, 1 ), min( j+kl, m ) c( j ) = max( c( j ), cabs1( ab( kd+i-j, j ) )*r( i ) ) end do if( c( j )>zero ) then c( j ) = radix**int( log( c( j ) ) / logrdx,KIND=${ik}$) end if end do ! find the maximum and minimum scale factors. rcmin = bignum rcmax = zero do j = 1, n rcmin = min( rcmin, c( j ) ) rcmax = max( rcmax, c( j ) ) end do if( rcmin==zero ) then ! find the first zero scale factor and return an error code. do j = 1, n if( c( j )==zero ) then info = m + j return end if end do else ! invert the scale factors. do j = 1, n c( j ) = one / min( max( c( j ), smlnum ), bignum ) end do ! compute colcnd = min(c(j)) / max(c(j)). colcnd = max( rcmin, smlnum ) / min( rcmax, bignum ) end if return end subroutine stdlib${ii}$_${ci}$gbequb #:endif #:endfor pure module subroutine stdlib${ii}$_slaqgb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, equed ) !! SLAQGB equilibrates a general M by N band matrix A with KL !! subdiagonals and KU superdiagonals using the row and scaling factors !! in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: kl, ku, ldab, m, n real(sp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(inout) :: ab(ldab,*) real(sp), intent(in) :: c(*), r(*) ! ===================================================================== ! 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( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*ab( ku+1+i-j, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = r( i )*ab( ku+1+i-j, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*r( i )*ab( ku+1+i-j, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_slaqgb pure module subroutine stdlib${ii}$_dlaqgb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, equed ) !! DLAQGB equilibrates a general M by N band matrix A with KL !! subdiagonals and KU superdiagonals using the row and scaling factors !! in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: kl, ku, ldab, m, n real(dp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(inout) :: ab(ldab,*) real(dp), intent(in) :: c(*), r(*) ! ===================================================================== ! 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( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*ab( ku+1+i-j, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = r( i )*ab( ku+1+i-j, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*r( i )*ab( ku+1+i-j, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_dlaqgb #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$laqgb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, equed ) !! DLAQGB: equilibrates a general M by N band matrix A with KL !! subdiagonals and KU superdiagonals using the row and scaling factors !! in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: kl, ku, ldab, m, n real(${rk}$), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(${rk}$), intent(inout) :: ab(ldab,*) real(${rk}$), intent(in) :: c(*), r(*) ! ===================================================================== ! Parameters real(${rk}$), parameter :: thresh = 0.1e+0_${rk}$ ! Local Scalars integer(${ik}$) :: i, j real(${rk}$) :: cj, large, small ! Intrinsic Functions ! Executable Statements ! quick return if possible if( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*ab( ku+1+i-j, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = r( i )*ab( ku+1+i-j, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*r( i )*ab( ku+1+i-j, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_${ri}$laqgb #:endif #:endfor pure module subroutine stdlib${ii}$_claqgb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, equed ) !! CLAQGB equilibrates a general M by N band matrix A with KL !! subdiagonals and KU superdiagonals using the row and scaling factors !! in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: kl, ku, ldab, m, n real(sp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(sp), intent(in) :: c(*), r(*) 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( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*ab( ku+1+i-j, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = r( i )*ab( ku+1+i-j, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*r( i )*ab( ku+1+i-j, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_claqgb pure module subroutine stdlib${ii}$_zlaqgb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, equed ) !! ZLAQGB equilibrates a general M by N band matrix A with KL !! subdiagonals and KU superdiagonals using the row and scaling factors !! in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: kl, ku, ldab, m, n real(dp), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(dp), intent(in) :: c(*), r(*) 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( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*ab( ku+1+i-j, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = r( i )*ab( ku+1+i-j, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*r( i )*ab( ku+1+i-j, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_zlaqgb #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$laqgb( m, n, kl, ku, ab, ldab, r, c, rowcnd, colcnd,amax, equed ) !! ZLAQGB: equilibrates a general M by N band matrix A with KL !! subdiagonals and KU superdiagonals using the row and scaling factors !! in the vectors R and C. ! -- 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 integer(${ik}$), intent(in) :: kl, ku, ldab, m, n real(${ck}$), intent(in) :: amax, colcnd, rowcnd ! Array Arguments real(${ck}$), intent(in) :: c(*), r(*) 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( m<=0_${ik}$ .or. 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( rowcnd>=thresh .and. amax>=small .and. amax<=large )then ! no row scaling if( colcnd>=thresh ) then ! no column scaling equed = 'N' else ! column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*ab( ku+1+i-j, j ) end do end do equed = 'C' end if else if( colcnd>=thresh ) then ! row scaling, no column scaling do j = 1, n do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = r( i )*ab( ku+1+i-j, j ) end do end do equed = 'R' else ! row and column scaling do j = 1, n cj = c( j ) do i = max( 1, j-ku ), min( m, j+kl ) ab( ku+1+i-j, j ) = cj*r( i )*ab( ku+1+i-j, j ) end do end do equed = 'B' end if return end subroutine stdlib${ii}$_${ci}$laqgb #:endif #:endfor real(sp) module function stdlib${ii}$_sla_gbrcond( trans, n, kl, ku, ab, ldab, afb, ldafb,ipiv, cmode, c, & !! SLA_GBRCOND 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. info, work, iwork ) ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(in) :: n, ldab, ldafb, kl, ku, cmode integer(${ik}$), intent(out) :: info ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(in) :: ab(ldab,*), afb(ldafb,*), c(*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: notrans integer(${ik}$) :: kase, i, j, kd, ke real(sp) :: ainvnm, tmp ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements stdlib${ii}$_sla_gbrcond = zero info = 0_${ik}$ notrans = stdlib_lsame( trans, 'N' ) if ( .not. notrans .and. .not. stdlib_lsame(trans, 'T').and. .not. stdlib_lsame(trans, & 'C') ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ .or. kl>n-1 ) then info = -3_${ik}$ else if( ku<0_${ik}$ .or. ku>n-1 ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SLA_GBRCOND', -info ) return end if if( n==0_${ik}$ ) then stdlib${ii}$_sla_gbrcond = one return end if ! compute the equilibration matrix r such that ! inv(r)*a*c has unit 1-norm. kd = ku + 1_${ik}$ ke = kl + 1_${ik}$ if ( notrans ) then do i = 1, n tmp = zero if ( cmode == 1_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, j ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, j ) ) end do else do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, 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 = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) ) end do else do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) / c( j ) ) end do end if work( 2_${ik}$*n+i ) = tmp end do end if ! 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 ( notrans ) then call stdlib${ii}$_sgbtrs( 'NO TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb,ipiv, work, n, & info ) else call stdlib${ii}$_sgbtrs( 'TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info & ) end if ! 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 ( notrans ) then call stdlib${ii}$_sgbtrs( 'TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info & ) else call stdlib${ii}$_sgbtrs( 'NO TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb,ipiv, work, n, & info ) end if ! 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_gbrcond = ( one / ainvnm ) return end function stdlib${ii}$_sla_gbrcond real(dp) module function stdlib${ii}$_dla_gbrcond( trans, n, kl, ku, ab, ldab,afb, ldafb, ipiv, cmode, c,& !! DLA_GBRCOND 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. info, work, iwork ) ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(in) :: n, ldab, ldafb, kl, ku, cmode integer(${ik}$), intent(out) :: info ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(in) :: ab(ldab,*), afb(ldafb,*), c(*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: notrans integer(${ik}$) :: kase, i, j, kd, ke real(dp) :: ainvnm, tmp ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements stdlib${ii}$_dla_gbrcond = zero info = 0_${ik}$ notrans = stdlib_lsame( trans, 'N' ) if ( .not. notrans .and. .not. stdlib_lsame(trans, 'T').and. .not. stdlib_lsame(trans, & 'C') ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ .or. kl>n-1 ) then info = -3_${ik}$ else if( ku<0_${ik}$ .or. ku>n-1 ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DLA_GBRCOND', -info ) return end if if( n==0_${ik}$ ) then stdlib${ii}$_dla_gbrcond = one return end if ! compute the equilibration matrix r such that ! inv(r)*a*c has unit 1-norm. kd = ku + 1_${ik}$ ke = kl + 1_${ik}$ if ( notrans ) then do i = 1, n tmp = zero if ( cmode == 1_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, j ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, j ) ) end do else do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, 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 = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) ) end do else do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) / c( j ) ) end do end if work( 2_${ik}$*n+i ) = tmp end do end if ! 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 ( notrans ) then call stdlib${ii}$_dgbtrs( 'NO TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb,ipiv, work, n, & info ) else call stdlib${ii}$_dgbtrs( 'TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info & ) end if ! 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 ( notrans ) then call stdlib${ii}$_dgbtrs( 'TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info & ) else call stdlib${ii}$_dgbtrs( 'NO TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb,ipiv, work, n, & info ) end if ! 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_gbrcond = ( one / ainvnm ) return end function stdlib${ii}$_dla_gbrcond #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] real(${rk}$) module function stdlib${ii}$_${ri}$la_gbrcond( trans, n, kl, ku, ab, ldab,afb, ldafb, ipiv, cmode, c,& !! DLA_GBRCOND: 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. info, work, iwork ) ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(in) :: n, ldab, ldafb, kl, ku, cmode integer(${ik}$), intent(out) :: info ! Array Arguments integer(${ik}$), intent(out) :: iwork(*) integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(in) :: ab(ldab,*), afb(ldafb,*), c(*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: notrans integer(${ik}$) :: kase, i, j, kd, ke real(${rk}$) :: ainvnm, tmp ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements stdlib${ii}$_${ri}$la_gbrcond = zero info = 0_${ik}$ notrans = stdlib_lsame( trans, 'N' ) if ( .not. notrans .and. .not. stdlib_lsame(trans, 'T').and. .not. stdlib_lsame(trans, & 'C') ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( kl<0_${ik}$ .or. kl>n-1 ) then info = -3_${ik}$ else if( ku<0_${ik}$ .or. ku>n-1 ) then info = -4_${ik}$ else if( ldab<kl+ku+1 ) then info = -6_${ik}$ else if( ldafb<2_${ik}$*kl+ku+1 ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DLA_GBRCOND', -info ) return end if if( n==0_${ik}$ ) then stdlib${ii}$_${ri}$la_gbrcond = one return end if ! compute the equilibration matrix r such that ! inv(r)*a*c has unit 1-norm. kd = ku + 1_${ik}$ ke = kl + 1_${ik}$ if ( notrans ) then do i = 1, n tmp = zero if ( cmode == 1_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, j ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, j ) ) end do else do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( kd+i-j, 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 = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) * c( j ) ) end do else if ( cmode == 0_${ik}$ ) then do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) ) end do else do j = max( i-kl, 1 ), min( i+ku, n ) tmp = tmp + abs( ab( ke-i+j, i ) / c( j ) ) end do end if work( 2_${ik}$*n+i ) = tmp end do end if ! 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 ( notrans ) then call stdlib${ii}$_${ri}$gbtrs( 'NO TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb,ipiv, work, n, & info ) else call stdlib${ii}$_${ri}$gbtrs( 'TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info & ) end if ! 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 ( notrans ) then call stdlib${ii}$_${ri}$gbtrs( 'TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb, ipiv,work, n, info & ) else call stdlib${ii}$_${ri}$gbtrs( 'NO TRANSPOSE', n, kl, ku, 1_${ik}$, afb, ldafb,ipiv, work, n, & info ) end if ! 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_gbrcond = ( one / ainvnm ) return end function stdlib${ii}$_${ri}$la_gbrcond #:endif #:endfor pure real(sp) module function stdlib${ii}$_sla_gbrpvgrw( n, kl, ku, ncols, ab, ldab, afb,ldafb ) !! SLA_GBRPVGRW 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 integer(${ik}$), intent(in) :: n, kl, ku, ncols, ldab, ldafb ! Array Arguments real(sp), intent(in) :: ab(ldab,*), afb(ldafb,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(sp) :: amax, umax, rpvgrw ! Intrinsic Functions ! Executable Statements rpvgrw = one kd = ku + 1_${ik}$ do j = 1, ncols amax = zero umax = zero do i = max( j-ku, 1 ), min( j+kl, n ) amax = max( abs( ab( kd+i-j, j)), amax ) end do do i = max( j-ku, 1 ), j umax = max( abs( afb( kd+i-j, j ) ), umax ) end do if ( umax /= 0.0_sp ) then rpvgrw = min( amax / umax, rpvgrw ) end if end do stdlib${ii}$_sla_gbrpvgrw = rpvgrw end function stdlib${ii}$_sla_gbrpvgrw pure real(dp) module function stdlib${ii}$_dla_gbrpvgrw( n, kl, ku, ncols, ab,ldab, afb, ldafb ) !! DLA_GBRPVGRW 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 integer(${ik}$), intent(in) :: n, kl, ku, ncols, ldab, ldafb ! Array Arguments real(dp), intent(in) :: ab(ldab,*), afb(ldafb,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(dp) :: amax, umax, rpvgrw ! Intrinsic Functions ! Executable Statements rpvgrw = one kd = ku + 1_${ik}$ do j = 1, ncols amax = zero umax = zero do i = max( j-ku, 1 ), min( j+kl, n ) amax = max( abs( ab( kd+i-j, j)), amax ) end do do i = max( j-ku, 1 ), j umax = max( abs( afb( kd+i-j, j ) ), umax ) end do if ( umax /= zero ) then rpvgrw = min( amax / umax, rpvgrw ) end if end do stdlib${ii}$_dla_gbrpvgrw = rpvgrw end function stdlib${ii}$_dla_gbrpvgrw #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure real(${rk}$) module function stdlib${ii}$_${ri}$la_gbrpvgrw( n, kl, ku, ncols, ab,ldab, afb, ldafb ) !! DLA_GBRPVGRW: 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 integer(${ik}$), intent(in) :: n, kl, ku, ncols, ldab, ldafb ! Array Arguments real(${rk}$), intent(in) :: ab(ldab,*), afb(ldafb,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(${rk}$) :: amax, umax, rpvgrw ! Intrinsic Functions ! Executable Statements rpvgrw = one kd = ku + 1_${ik}$ do j = 1, ncols amax = zero umax = zero do i = max( j-ku, 1 ), min( j+kl, n ) amax = max( abs( ab( kd+i-j, j)), amax ) end do do i = max( j-ku, 1 ), j umax = max( abs( afb( kd+i-j, j ) ), umax ) end do if ( umax /= zero ) then rpvgrw = min( amax / umax, rpvgrw ) end if end do stdlib${ii}$_${ri}$la_gbrpvgrw = rpvgrw end function stdlib${ii}$_${ri}$la_gbrpvgrw #:endif #:endfor pure real(sp) module function stdlib${ii}$_cla_gbrpvgrw( n, kl, ku, ncols, ab, ldab, afb,ldafb ) !! CLA_GBRPVGRW 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 integer(${ik}$), intent(in) :: n, kl, ku, ncols, ldab, ldafb ! Array Arguments complex(sp), intent(in) :: ab(ldab,*), afb(ldafb,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(sp) :: amax, umax, rpvgrw 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 rpvgrw = one kd = ku + 1_${ik}$ do j = 1, ncols amax = zero umax = zero do i = max( j-ku, 1 ), min( j+kl, n ) amax = max( cabs1( ab( kd+i-j, j ) ), amax ) end do do i = max( j-ku, 1 ), j umax = max( cabs1( afb( kd+i-j, j ) ), umax ) end do if ( umax /= 0.0_sp ) then rpvgrw = min( amax / umax, rpvgrw ) end if end do stdlib${ii}$_cla_gbrpvgrw = rpvgrw end function stdlib${ii}$_cla_gbrpvgrw pure real(dp) module function stdlib${ii}$_zla_gbrpvgrw( n, kl, ku, ncols, ab,ldab, afb, ldafb ) !! ZLA_GBRPVGRW 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 integer(${ik}$), intent(in) :: n, kl, ku, ncols, ldab, ldafb ! Array Arguments complex(dp), intent(in) :: ab(ldab,*), afb(ldafb,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(dp) :: amax, umax, rpvgrw 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 rpvgrw = one kd = ku + 1_${ik}$ do j = 1, ncols amax = zero umax = zero do i = max( j-ku, 1 ), min( j+kl, n ) amax = max( cabs1( ab( kd+i-j, j ) ), amax ) end do do i = max( j-ku, 1 ), j umax = max( cabs1( afb( kd+i-j, j ) ), umax ) end do if ( umax /= zero ) then rpvgrw = min( amax / umax, rpvgrw ) end if end do stdlib${ii}$_zla_gbrpvgrw = rpvgrw end function stdlib${ii}$_zla_gbrpvgrw #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure real(${ck}$) module function stdlib${ii}$_${ci}$la_gbrpvgrw( n, kl, ku, ncols, ab,ldab, afb, ldafb ) !! ZLA_GBRPVGRW: 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 integer(${ik}$), intent(in) :: n, kl, ku, ncols, ldab, ldafb ! Array Arguments complex(${ck}$), intent(in) :: ab(ldab,*), afb(ldafb,*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j, kd real(${ck}$) :: amax, umax, rpvgrw 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 rpvgrw = one kd = ku + 1_${ik}$ do j = 1, ncols amax = zero umax = zero do i = max( j-ku, 1 ), min( j+kl, n ) amax = max( cabs1( ab( kd+i-j, j ) ), amax ) end do do i = max( j-ku, 1 ), j umax = max( cabs1( afb( kd+i-j, j ) ), umax ) end do if ( umax /= zero ) then rpvgrw = min( amax / umax, rpvgrw ) end if end do stdlib${ii}$_${ci}$la_gbrpvgrw = rpvgrw end function stdlib${ii}$_${ci}$la_gbrpvgrw #:endif #:endfor pure module subroutine stdlib${ii}$_sgtcon( norm, n, dl, d, du, du2, ipiv, anorm, rcond,work, iwork, info & !! SGTCON estimates the reciprocal of the condition number of a real !! tridiagonal matrix A using the LU factorization as computed by !! SGTTRF. !! 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) :: norm 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(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(in) :: d(*), dl(*), du(*), du2(*) real(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: onenrm integer(${ik}$) :: i, kase, kase1 real(sp) :: ainvnm ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Executable Statements ! test the input arguments. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGTCON', -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 non-zero. do i = 1, n if( d( i )==zero )return end do ainvnm = zero if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 20 continue call stdlib${ii}$_slacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(u)*inv(l). call stdlib${ii}$_sgttrs( 'NO TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv,work, n, info ) else ! multiply by inv(l**t)*inv(u**t). call stdlib${ii}$_sgttrs( 'TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv, work,n, info ) end if go to 20 end if ! compute the estimate of the reciprocal condition number. if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm return end subroutine stdlib${ii}$_sgtcon pure module subroutine stdlib${ii}$_dgtcon( norm, n, dl, d, du, du2, ipiv, anorm, rcond,work, iwork, info & !! DGTCON estimates the reciprocal of the condition number of a real !! tridiagonal matrix A using the LU factorization as computed by !! DGTTRF. !! 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) :: norm 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(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(in) :: d(*), dl(*), du(*), du2(*) real(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: onenrm integer(${ik}$) :: i, kase, kase1 real(dp) :: ainvnm ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Executable Statements ! test the input arguments. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGTCON', -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 non-zero. do i = 1, n if( d( i )==zero )return end do ainvnm = zero if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 20 continue call stdlib${ii}$_dlacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(u)*inv(l). call stdlib${ii}$_dgttrs( 'NO TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv,work, n, info ) else ! multiply by inv(l**t)*inv(u**t). call stdlib${ii}$_dgttrs( 'TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv, work,n, info ) end if go to 20 end if ! compute the estimate of the reciprocal condition number. if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm return end subroutine stdlib${ii}$_dgtcon #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gtcon( norm, n, dl, d, du, du2, ipiv, anorm, rcond,work, iwork, info & !! DGTCON: estimates the reciprocal of the condition number of a real !! tridiagonal matrix A using the LU factorization as computed by !! DGTTRF. !! 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) :: norm 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(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(in) :: d(*), dl(*), du(*), du2(*) real(${rk}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: onenrm integer(${ik}$) :: i, kase, kase1 real(${rk}$) :: ainvnm ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Executable Statements ! test the input arguments. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGTCON', -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 non-zero. do i = 1, n if( d( i )==zero )return end do ainvnm = zero if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 20 continue call stdlib${ii}$_${ri}$lacn2( n, work( n+1 ), work, iwork, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(u)*inv(l). call stdlib${ii}$_${ri}$gttrs( 'NO TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv,work, n, info ) else ! multiply by inv(l**t)*inv(u**t). call stdlib${ii}$_${ri}$gttrs( 'TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv, work,n, info ) end if go to 20 end if ! compute the estimate of the reciprocal condition number. if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm return end subroutine stdlib${ii}$_${ri}$gtcon #:endif #:endfor pure module subroutine stdlib${ii}$_cgtcon( norm, n, dl, d, du, du2, ipiv, anorm, rcond,work, info ) !! CGTCON estimates the reciprocal of the condition number of a complex !! tridiagonal matrix A using the LU factorization as computed by !! CGTTRF. !! 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) :: norm 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(in) :: ipiv(*) complex(sp), intent(in) :: d(*), dl(*), du(*), du2(*) complex(sp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: onenrm integer(${ik}$) :: i, kase, kase1 real(sp) :: ainvnm ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input arguments. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGTCON', -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 non-zero. do i = 1, n if( d( i )==cmplx( zero,KIND=sp) )return end do ainvnm = zero if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 20 continue call stdlib${ii}$_clacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(u)*inv(l). call stdlib${ii}$_cgttrs( 'NO TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv,work, n, info ) else ! multiply by inv(l**h)*inv(u**h). call stdlib${ii}$_cgttrs( 'CONJUGATE TRANSPOSE', n, 1_${ik}$, dl, d, du, du2,ipiv, work, n, & info ) end if go to 20 end if ! compute the estimate of the reciprocal condition number. if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm return end subroutine stdlib${ii}$_cgtcon pure module subroutine stdlib${ii}$_zgtcon( norm, n, dl, d, du, du2, ipiv, anorm, rcond,work, info ) !! ZGTCON estimates the reciprocal of the condition number of a complex !! tridiagonal matrix A using the LU factorization as computed by !! ZGTTRF. !! 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) :: norm 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(in) :: ipiv(*) complex(dp), intent(in) :: d(*), dl(*), du(*), du2(*) complex(dp), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: onenrm integer(${ik}$) :: i, kase, kase1 real(dp) :: ainvnm ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input arguments. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGTCON', -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 non-zero. do i = 1, n if( d( i )==cmplx( zero,KIND=dp) )return end do ainvnm = zero if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 20 continue call stdlib${ii}$_zlacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(u)*inv(l). call stdlib${ii}$_zgttrs( 'NO TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv,work, n, info ) else ! multiply by inv(l**h)*inv(u**h). call stdlib${ii}$_zgttrs( 'CONJUGATE TRANSPOSE', n, 1_${ik}$, dl, d, du, du2,ipiv, work, n, & info ) end if go to 20 end if ! compute the estimate of the reciprocal condition number. if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm return end subroutine stdlib${ii}$_zgtcon #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gtcon( norm, n, dl, d, du, du2, ipiv, anorm, rcond,work, info ) !! ZGTCON: estimates the reciprocal of the condition number of a complex !! tridiagonal matrix A using the LU factorization as computed by !! ZGTTRF. !! 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) :: norm integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: n real(${ck}$), intent(in) :: anorm real(${ck}$), intent(out) :: rcond ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(in) :: d(*), dl(*), du(*), du2(*) complex(${ck}$), intent(out) :: work(*) ! ===================================================================== ! Local Scalars logical(lk) :: onenrm integer(${ik}$) :: i, kase, kase1 real(${ck}$) :: ainvnm ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input arguments. info = 0_${ik}$ onenrm = norm=='1' .or. stdlib_lsame( norm, 'O' ) if( .not.onenrm .and. .not.stdlib_lsame( norm, 'I' ) ) then info = -1_${ik}$ else if( n<0_${ik}$ ) then info = -2_${ik}$ else if( anorm<zero ) then info = -8_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGTCON', -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 non-zero. do i = 1, n if( d( i )==cmplx( zero,KIND=${ck}$) )return end do ainvnm = zero if( onenrm ) then kase1 = 1_${ik}$ else kase1 = 2_${ik}$ end if kase = 0_${ik}$ 20 continue call stdlib${ii}$_${ci}$lacn2( n, work( n+1 ), work, ainvnm, kase, isave ) if( kase/=0_${ik}$ ) then if( kase==kase1 ) then ! multiply by inv(u)*inv(l). call stdlib${ii}$_${ci}$gttrs( 'NO TRANSPOSE', n, 1_${ik}$, dl, d, du, du2, ipiv,work, n, info ) else ! multiply by inv(l**h)*inv(u**h). call stdlib${ii}$_${ci}$gttrs( 'CONJUGATE TRANSPOSE', n, 1_${ik}$, dl, d, du, du2,ipiv, work, n, & info ) end if go to 20 end if ! compute the estimate of the reciprocal condition number. if( ainvnm/=zero )rcond = ( one / ainvnm ) / anorm return end subroutine stdlib${ii}$_${ci}$gtcon #:endif #:endfor pure module subroutine stdlib${ii}$_sgttrf( n, dl, d, du, du2, ipiv, info ) !! SGTTRF computes an LU factorization of a real tridiagonal matrix A !! using elimination with partial pivoting and row interchanges. !! The factorization has the form !! A = L * U !! where L is a product of permutation and unit lower bidiagonal !! matrices and U is upper triangular with nonzeros in only the main !! diagonal and first two superdiagonals. ! -- lapack computational routine -- ! -- lapack 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 integer(${ik}$), intent(out) :: ipiv(*) real(sp), intent(inout) :: d(*), dl(*), du(*) real(sp), intent(out) :: du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i real(sp) :: fact, temp ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ if( n<0_${ik}$ ) then info = -1_${ik}$ call stdlib${ii}$_xerbla( 'SGTTRF', -info ) return end if ! quick return if possible if( n==0 )return ! initialize ipiv(i) = i and du2(i) = 0 do i = 1, n ipiv( i ) = i end do do i = 1, n - 2 du2( i ) = zero end do do i = 1, n - 2 if( abs( d( i ) )>=abs( dl( i ) ) ) then ! no row interchange required, eliminate dl(i) if( d( i )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else ! interchange rows i and i+1, eliminate dl(i) fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) du2( i ) = du( i+1 ) du( i+1 ) = -fact*du( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end do if( n>1_${ik}$ ) then i = n - 1_${ik}$ if( abs( d( i ) )>=abs( dl( i ) ) ) then if( d( i )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end if ! check for a zero on the diagonal of u. do i = 1, n if( d( i )==zero ) then info = i go to 50 end if end do 50 continue return end subroutine stdlib${ii}$_sgttrf pure module subroutine stdlib${ii}$_dgttrf( n, dl, d, du, du2, ipiv, info ) !! DGTTRF computes an LU factorization of a real tridiagonal matrix A !! using elimination with partial pivoting and row interchanges. !! The factorization has the form !! A = L * U !! where L is a product of permutation and unit lower bidiagonal !! matrices and U is upper triangular with nonzeros in only the main !! diagonal and first two superdiagonals. ! -- lapack computational routine -- ! -- lapack 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 integer(${ik}$), intent(out) :: ipiv(*) real(dp), intent(inout) :: d(*), dl(*), du(*) real(dp), intent(out) :: du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i real(dp) :: fact, temp ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ if( n<0_${ik}$ ) then info = -1_${ik}$ call stdlib${ii}$_xerbla( 'DGTTRF', -info ) return end if ! quick return if possible if( n==0 )return ! initialize ipiv(i) = i and du2(i) = 0 do i = 1, n ipiv( i ) = i end do do i = 1, n - 2 du2( i ) = zero end do do i = 1, n - 2 if( abs( d( i ) )>=abs( dl( i ) ) ) then ! no row interchange required, eliminate dl(i) if( d( i )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else ! interchange rows i and i+1, eliminate dl(i) fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) du2( i ) = du( i+1 ) du( i+1 ) = -fact*du( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end do if( n>1_${ik}$ ) then i = n - 1_${ik}$ if( abs( d( i ) )>=abs( dl( i ) ) ) then if( d( i )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end if ! check for a zero on the diagonal of u. do i = 1, n if( d( i )==zero ) then info = i go to 50 end if end do 50 continue return end subroutine stdlib${ii}$_dgttrf #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gttrf( n, dl, d, du, du2, ipiv, info ) !! DGTTRF: computes an LU factorization of a real tridiagonal matrix A !! using elimination with partial pivoting and row interchanges. !! The factorization has the form !! A = L * U !! where L is a product of permutation and unit lower bidiagonal !! matrices and U is upper triangular with nonzeros in only the main !! diagonal and first two superdiagonals. ! -- lapack computational routine -- ! -- lapack 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 integer(${ik}$), intent(out) :: ipiv(*) real(${rk}$), intent(inout) :: d(*), dl(*), du(*) real(${rk}$), intent(out) :: du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i real(${rk}$) :: fact, temp ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ if( n<0_${ik}$ ) then info = -1_${ik}$ call stdlib${ii}$_xerbla( 'DGTTRF', -info ) return end if ! quick return if possible if( n==0 )return ! initialize ipiv(i) = i and du2(i) = 0 do i = 1, n ipiv( i ) = i end do do i = 1, n - 2 du2( i ) = zero end do do i = 1, n - 2 if( abs( d( i ) )>=abs( dl( i ) ) ) then ! no row interchange required, eliminate dl(i) if( d( i )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else ! interchange rows i and i+1, eliminate dl(i) fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) du2( i ) = du( i+1 ) du( i+1 ) = -fact*du( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end do if( n>1_${ik}$ ) then i = n - 1_${ik}$ if( abs( d( i ) )>=abs( dl( i ) ) ) then if( d( i )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end if ! check for a zero on the diagonal of u. do i = 1, n if( d( i )==zero ) then info = i go to 50 end if end do 50 continue return end subroutine stdlib${ii}$_${ri}$gttrf #:endif #:endfor pure module subroutine stdlib${ii}$_cgttrf( n, dl, d, du, du2, ipiv, info ) !! CGTTRF computes an LU factorization of a complex tridiagonal matrix A !! using elimination with partial pivoting and row interchanges. !! The factorization has the form !! A = L * U !! where L is a product of permutation and unit lower bidiagonal !! matrices and U is upper triangular with nonzeros in only the main !! diagonal and first two superdiagonals. ! -- lapack computational routine -- ! -- lapack 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 integer(${ik}$), intent(out) :: ipiv(*) complex(sp), intent(inout) :: d(*), dl(*), du(*) complex(sp), intent(out) :: du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i complex(sp) :: fact, temp, zdum ! Intrinsic Functions ! Statement Functions real(sp) :: cabs1 ! Statement Function Definitions cabs1( zdum ) = abs( real( zdum,KIND=sp) ) + abs( aimag( zdum ) ) ! Executable Statements info = 0_${ik}$ if( n<0_${ik}$ ) then info = -1_${ik}$ call stdlib${ii}$_xerbla( 'CGTTRF', -info ) return end if ! quick return if possible if( n==0 )return ! initialize ipiv(i) = i and du2(i) = 0 do i = 1, n ipiv( i ) = i end do do i = 1, n - 2 du2( i ) = zero end do do i = 1, n - 2 if( cabs1( d( i ) )>=cabs1( dl( i ) ) ) then ! no row interchange required, eliminate dl(i) if( cabs1( d( i ) )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else ! interchange rows i and i+1, eliminate dl(i) fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) du2( i ) = du( i+1 ) du( i+1 ) = -fact*du( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end do if( n>1_${ik}$ ) then i = n - 1_${ik}$ if( cabs1( d( i ) )>=cabs1( dl( i ) ) ) then if( cabs1( d( i ) )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end if ! check for a zero on the diagonal of u. do i = 1, n if( cabs1( d( i ) )==zero ) then info = i go to 50 end if end do 50 continue return end subroutine stdlib${ii}$_cgttrf pure module subroutine stdlib${ii}$_zgttrf( n, dl, d, du, du2, ipiv, info ) !! ZGTTRF computes an LU factorization of a complex tridiagonal matrix A !! using elimination with partial pivoting and row interchanges. !! The factorization has the form !! A = L * U !! where L is a product of permutation and unit lower bidiagonal !! matrices and U is upper triangular with nonzeros in only the main !! diagonal and first two superdiagonals. ! -- lapack computational routine -- ! -- lapack 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 integer(${ik}$), intent(out) :: ipiv(*) complex(dp), intent(inout) :: d(*), dl(*), du(*) complex(dp), intent(out) :: du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i complex(dp) :: fact, temp, zdum ! Intrinsic Functions ! Statement Functions real(dp) :: cabs1 ! Statement Function Definitions cabs1( zdum ) = abs( real( zdum,KIND=dp) ) + abs( aimag( zdum ) ) ! Executable Statements info = 0_${ik}$ if( n<0_${ik}$ ) then info = -1_${ik}$ call stdlib${ii}$_xerbla( 'ZGTTRF', -info ) return end if ! quick return if possible if( n==0 )return ! initialize ipiv(i) = i and du2(i) = 0 do i = 1, n ipiv( i ) = i end do do i = 1, n - 2 du2( i ) = zero end do do i = 1, n - 2 if( cabs1( d( i ) )>=cabs1( dl( i ) ) ) then ! no row interchange required, eliminate dl(i) if( cabs1( d( i ) )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else ! interchange rows i and i+1, eliminate dl(i) fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) du2( i ) = du( i+1 ) du( i+1 ) = -fact*du( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end do if( n>1_${ik}$ ) then i = n - 1_${ik}$ if( cabs1( d( i ) )>=cabs1( dl( i ) ) ) then if( cabs1( d( i ) )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end if ! check for a zero on the diagonal of u. do i = 1, n if( cabs1( d( i ) )==zero ) then info = i go to 50 end if end do 50 continue return end subroutine stdlib${ii}$_zgttrf #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gttrf( n, dl, d, du, du2, ipiv, info ) !! ZGTTRF: computes an LU factorization of a complex tridiagonal matrix A !! using elimination with partial pivoting and row interchanges. !! The factorization has the form !! A = L * U !! where L is a product of permutation and unit lower bidiagonal !! matrices and U is upper triangular with nonzeros in only the main !! diagonal and first two superdiagonals. ! -- lapack computational routine -- ! -- lapack 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 integer(${ik}$), intent(out) :: ipiv(*) complex(${ck}$), intent(inout) :: d(*), dl(*), du(*) complex(${ck}$), intent(out) :: du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i complex(${ck}$) :: fact, temp, zdum ! Intrinsic Functions ! Statement Functions real(${ck}$) :: cabs1 ! Statement Function Definitions cabs1( zdum ) = abs( real( zdum,KIND=${ck}$) ) + abs( aimag( zdum ) ) ! Executable Statements info = 0_${ik}$ if( n<0_${ik}$ ) then info = -1_${ik}$ call stdlib${ii}$_xerbla( 'ZGTTRF', -info ) return end if ! quick return if possible if( n==0 )return ! initialize ipiv(i) = i and du2(i) = 0 do i = 1, n ipiv( i ) = i end do do i = 1, n - 2 du2( i ) = zero end do do i = 1, n - 2 if( cabs1( d( i ) )>=cabs1( dl( i ) ) ) then ! no row interchange required, eliminate dl(i) if( cabs1( d( i ) )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else ! interchange rows i and i+1, eliminate dl(i) fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) du2( i ) = du( i+1 ) du( i+1 ) = -fact*du( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end do if( n>1_${ik}$ ) then i = n - 1_${ik}$ if( cabs1( d( i ) )>=cabs1( dl( i ) ) ) then if( cabs1( d( i ) )/=zero ) then fact = dl( i ) / d( i ) dl( i ) = fact d( i+1 ) = d( i+1 ) - fact*du( i ) end if else fact = d( i ) / dl( i ) d( i ) = dl( i ) dl( i ) = fact temp = du( i ) du( i ) = d( i+1 ) d( i+1 ) = temp - fact*d( i+1 ) ipiv( i ) = i + 1_${ik}$ end if end if ! check for a zero on the diagonal of u. do i = 1, n if( cabs1( d( i ) )==zero ) then info = i go to 50 end if end do 50 continue return end subroutine stdlib${ii}$_${ci}$gttrf #:endif #:endfor pure module subroutine stdlib${ii}$_sgttrs( trans, n, nrhs, dl, d, du, du2, ipiv, b, ldb,info ) !! SGTTRS solves one of the systems of equations !! A*X = B or A**T*X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by SGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(inout) :: b(ldb,*) real(sp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars logical(lk) :: notran integer(${ik}$) :: itrans, j, jb, nb ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ notran = ( trans=='N' .or. trans=='N' ) if( .not.notran .and. .not.( trans=='T' .or. trans=='T' ) .and. .not.( trans=='C' .or. & trans=='C' ) ) 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( n, 1_${ik}$ ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGTTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return ! decode trans if( notran ) then itrans = 0_${ik}$ else itrans = 1_${ik}$ end if ! 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}$, 'SGTTRS', trans, n, nrhs, -1_${ik}$, -1_${ik}$ ) ) end if if( nb>=nrhs ) then call stdlib${ii}$_sgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) else do j = 1, nrhs, nb jb = min( nrhs-j+1, nb ) call stdlib${ii}$_sgtts2( itrans, n, jb, dl, d, du, du2, ipiv, b( 1_${ik}$, j ),ldb ) end do end if end subroutine stdlib${ii}$_sgttrs pure module subroutine stdlib${ii}$_dgttrs( trans, n, nrhs, dl, d, du, du2, ipiv, b, ldb,info ) !! DGTTRS solves one of the systems of equations !! A*X = B or A**T*X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by DGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(inout) :: b(ldb,*) real(dp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars logical(lk) :: notran integer(${ik}$) :: itrans, j, jb, nb ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ notran = ( trans=='N' .or. trans=='N' ) if( .not.notran .and. .not.( trans=='T' .or. trans=='T' ) .and. .not.( trans=='C' .or. & trans=='C' ) ) 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( n, 1_${ik}$ ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGTTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return ! decode trans if( notran ) then itrans = 0_${ik}$ else itrans = 1_${ik}$ end if ! 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}$, 'DGTTRS', trans, n, nrhs, -1_${ik}$, -1_${ik}$ ) ) end if if( nb>=nrhs ) then call stdlib${ii}$_dgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) else do j = 1, nrhs, nb jb = min( nrhs-j+1, nb ) call stdlib${ii}$_dgtts2( itrans, n, jb, dl, d, du, du2, ipiv, b( 1_${ik}$, j ),ldb ) end do end if end subroutine stdlib${ii}$_dgttrs #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gttrs( trans, n, nrhs, dl, d, du, du2, ipiv, b, ldb,info ) !! DGTTRS: solves one of the systems of equations !! A*X = B or A**T*X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by DGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(inout) :: b(ldb,*) real(${rk}$), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars logical(lk) :: notran integer(${ik}$) :: itrans, j, jb, nb ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ notran = ( trans=='N' .or. trans=='N' ) if( .not.notran .and. .not.( trans=='T' .or. trans=='T' ) .and. .not.( trans=='C' .or. & trans=='C' ) ) 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( n, 1_${ik}$ ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGTTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return ! decode trans if( notran ) then itrans = 0_${ik}$ else itrans = 1_${ik}$ end if ! 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}$, 'DGTTRS', trans, n, nrhs, -1_${ik}$, -1_${ik}$ ) ) end if if( nb>=nrhs ) then call stdlib${ii}$_${ri}$gtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) else do j = 1, nrhs, nb jb = min( nrhs-j+1, nb ) call stdlib${ii}$_${ri}$gtts2( itrans, n, jb, dl, d, du, du2, ipiv, b( 1_${ik}$, j ),ldb ) end do end if end subroutine stdlib${ii}$_${ri}$gttrs #:endif #:endfor pure module subroutine stdlib${ii}$_cgttrs( trans, n, nrhs, dl, d, du, du2, ipiv, b, ldb,info ) !! CGTTRS solves one of the systems of equations !! A * X = B, A**T * X = B, or A**H * X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by CGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(sp), intent(inout) :: b(ldb,*) complex(sp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars logical(lk) :: notran integer(${ik}$) :: itrans, j, jb, nb ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ notran = ( trans=='N' .or. trans=='N' ) if( .not.notran .and. .not.( trans=='T' .or. trans=='T' ) .and. .not.( trans=='C' .or. & trans=='C' ) ) 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( n, 1_${ik}$ ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGTTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return ! decode trans if( notran ) then itrans = 0_${ik}$ else if( trans=='T' .or. trans=='T' ) then itrans = 1_${ik}$ else itrans = 2_${ik}$ end if ! 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}$, 'CGTTRS', trans, n, nrhs, -1_${ik}$, -1_${ik}$ ) ) end if if( nb>=nrhs ) then call stdlib${ii}$_cgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) else do j = 1, nrhs, nb jb = min( nrhs-j+1, nb ) call stdlib${ii}$_cgtts2( itrans, n, jb, dl, d, du, du2, ipiv, b( 1_${ik}$, j ),ldb ) end do end if end subroutine stdlib${ii}$_cgttrs pure module subroutine stdlib${ii}$_zgttrs( trans, n, nrhs, dl, d, du, du2, ipiv, b, ldb,info ) !! ZGTTRS solves one of the systems of equations !! A * X = B, A**T * X = B, or A**H * X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by ZGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(dp), intent(inout) :: b(ldb,*) complex(dp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars logical(lk) :: notran integer(${ik}$) :: itrans, j, jb, nb ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ notran = ( trans=='N' .or. trans=='N' ) if( .not.notran .and. .not.( trans=='T' .or. trans=='T' ) .and. .not.( trans=='C' .or. & trans=='C' ) ) 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( n, 1_${ik}$ ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGTTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return ! decode trans if( notran ) then itrans = 0_${ik}$ else if( trans=='T' .or. trans=='T' ) then itrans = 1_${ik}$ else itrans = 2_${ik}$ end if ! 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}$, 'ZGTTRS', trans, n, nrhs, -1_${ik}$, -1_${ik}$ ) ) end if if( nb>=nrhs ) then call stdlib${ii}$_zgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) else do j = 1, nrhs, nb jb = min( nrhs-j+1, nb ) call stdlib${ii}$_zgtts2( itrans, n, jb, dl, d, du, du2, ipiv, b( 1_${ik}$, j ),ldb ) end do end if end subroutine stdlib${ii}$_zgttrs #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gttrs( trans, n, nrhs, dl, d, du, du2, ipiv, b, ldb,info ) !! ZGTTRS: solves one of the systems of equations !! A * X = B, A**T * X = B, or A**H * X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by ZGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(inout) :: b(ldb,*) complex(${ck}$), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars logical(lk) :: notran integer(${ik}$) :: itrans, j, jb, nb ! Intrinsic Functions ! Executable Statements info = 0_${ik}$ notran = ( trans=='N' .or. trans=='N' ) if( .not.notran .and. .not.( trans=='T' .or. trans=='T' ) .and. .not.( trans=='C' .or. & trans=='C' ) ) 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( n, 1_${ik}$ ) ) then info = -10_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGTTRS', -info ) return end if ! quick return if possible if( n==0 .or. nrhs==0 )return ! decode trans if( notran ) then itrans = 0_${ik}$ else if( trans=='T' .or. trans=='T' ) then itrans = 1_${ik}$ else itrans = 2_${ik}$ end if ! 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}$, 'ZGTTRS', trans, n, nrhs, -1_${ik}$, -1_${ik}$ ) ) end if if( nb>=nrhs ) then call stdlib${ii}$_${ci}$gtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) else do j = 1, nrhs, nb jb = min( nrhs-j+1, nb ) call stdlib${ii}$_${ci}$gtts2( itrans, n, jb, dl, d, du, du2, ipiv, b( 1_${ik}$, j ),ldb ) end do end if end subroutine stdlib${ii}$_${ci}$gttrs #:endif #:endfor pure module subroutine stdlib${ii}$_sgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) !! SGTTS2 solves one of the systems of equations !! A*X = B or A**T*X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by SGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: itrans, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(inout) :: b(ldb,*) real(sp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, j real(sp) :: temp ! Executable Statements ! quick return if possible if( n==0 .or. nrhs==0 )return if( itrans==0_${ik}$ ) then ! solve a*x = b using the lu factorization of a, ! overwriting each right hand side vector with its solution. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 10 continue ! solve l*x = b. do i = 1, n - 1 ip = ipiv( i ) temp = b( i+1-ip+i, j ) - dl( i )*b( ip, j ) b( i, j ) = b( ip, j ) b( i+1, j ) = temp end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do if( j<nrhs ) then j = j + 1_${ik}$ go to 10 end if else do j = 1, nrhs ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do end do end if else ! solve a**t * x = b. if( nrhs<=1_${ik}$ ) then ! solve u**t*x = b. j = 1_${ik}$ 70 continue b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d( i & ) end do ! solve l**t*x = b. do i = n - 1, 1, -1 ip = ipiv( i ) temp = b( i, j ) - dl( i )*b( i+1, j ) b( i, j ) = b( ip, j ) b( ip, j ) = temp end do if( j<nrhs ) then j = j + 1_${ik}$ go to 70 end if else do j = 1, nrhs ! solve u**t*x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d(& i ) end do do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do end do end if end if end subroutine stdlib${ii}$_sgtts2 pure module subroutine stdlib${ii}$_dgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) !! DGTTS2 solves one of the systems of equations !! A*X = B or A**T*X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by DGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: itrans, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(inout) :: b(ldb,*) real(dp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, j real(dp) :: temp ! Executable Statements ! quick return if possible if( n==0 .or. nrhs==0 )return if( itrans==0_${ik}$ ) then ! solve a*x = b using the lu factorization of a, ! overwriting each right hand side vector with its solution. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 10 continue ! solve l*x = b. do i = 1, n - 1 ip = ipiv( i ) temp = b( i+1-ip+i, j ) - dl( i )*b( ip, j ) b( i, j ) = b( ip, j ) b( i+1, j ) = temp end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do if( j<nrhs ) then j = j + 1_${ik}$ go to 10 end if else do j = 1, nrhs ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do end do end if else ! solve a**t * x = b. if( nrhs<=1_${ik}$ ) then ! solve u**t*x = b. j = 1_${ik}$ 70 continue b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d( i & ) end do ! solve l**t*x = b. do i = n - 1, 1, -1 ip = ipiv( i ) temp = b( i, j ) - dl( i )*b( i+1, j ) b( i, j ) = b( ip, j ) b( ip, j ) = temp end do if( j<nrhs ) then j = j + 1_${ik}$ go to 70 end if else do j = 1, nrhs ! solve u**t*x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d(& i ) end do do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do end do end if end if end subroutine stdlib${ii}$_dgtts2 #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) !! DGTTS2: solves one of the systems of equations !! A*X = B or A**T*X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by DGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: itrans, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${rk}$), intent(inout) :: b(ldb,*) real(${rk}$), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, ip, j real(${rk}$) :: temp ! Executable Statements ! quick return if possible if( n==0 .or. nrhs==0 )return if( itrans==0_${ik}$ ) then ! solve a*x = b using the lu factorization of a, ! overwriting each right hand side vector with its solution. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 10 continue ! solve l*x = b. do i = 1, n - 1 ip = ipiv( i ) temp = b( i+1-ip+i, j ) - dl( i )*b( ip, j ) b( i, j ) = b( ip, j ) b( i+1, j ) = temp end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do if( j<nrhs ) then j = j + 1_${ik}$ go to 10 end if else do j = 1, nrhs ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do end do end if else ! solve a**t * x = b. if( nrhs<=1_${ik}$ ) then ! solve u**t*x = b. j = 1_${ik}$ 70 continue b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d( i & ) end do ! solve l**t*x = b. do i = n - 1, 1, -1 ip = ipiv( i ) temp = b( i, j ) - dl( i )*b( i+1, j ) b( i, j ) = b( ip, j ) b( ip, j ) = temp end do if( j<nrhs ) then j = j + 1_${ik}$ go to 70 end if else do j = 1, nrhs ! solve u**t*x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d(& i ) end do do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do end do end if end if end subroutine stdlib${ii}$_${ri}$gtts2 #:endif #:endfor pure module subroutine stdlib${ii}$_cgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) !! CGTTS2 solves one of the systems of equations !! A * X = B, A**T * X = B, or A**H * X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by CGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: itrans, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(sp), intent(inout) :: b(ldb,*) complex(sp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j complex(sp) :: temp ! Intrinsic Functions ! Executable Statements ! quick return if possible if( n==0 .or. nrhs==0 )return if( itrans==0_${ik}$ ) then ! solve a*x = b using the lu factorization of a, ! overwriting each right hand side vector with its solution. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 10 continue ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do if( j<nrhs ) then j = j + 1_${ik}$ go to 10 end if else do j = 1, nrhs ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do end do end if else if( itrans==1_${ik}$ ) then ! solve a**t * x = b. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 70 continue ! solve u**t * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d( i & ) end do ! solve l**t * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do if( j<nrhs ) then j = j + 1_${ik}$ go to 70 end if else do j = 1, nrhs ! solve u**t * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d(& i ) end do ! solve l**t * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do end do end if else ! solve a**h * x = b. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 130 continue ! solve u**h * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / conjg( d( 1_${ik}$ ) ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-conjg( du( 1_${ik}$ ) )*b( 1_${ik}$, j ) ) /conjg( d( 2_${ik}$ ) ) do i = 3, n b( i, j ) = ( b( i, j )-conjg( du( i-1 ) )*b( i-1, j )-conjg( du2( i-2 ) )*b( & i-2, j ) ) /conjg( d( i ) ) end do ! solve l**h * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - conjg( dl( i ) )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - conjg( dl( i ) )*temp b( i, j ) = temp end if end do if( j<nrhs ) then j = j + 1_${ik}$ go to 130 end if else do j = 1, nrhs ! solve u**h * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / conjg( d( 1_${ik}$ ) ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-conjg( du( 1_${ik}$ ) )*b( 1_${ik}$, j ) ) /conjg( d( 2_${ik}$ ) ) do i = 3, n b( i, j ) = ( b( i, j )-conjg( du( i-1 ) )*b( i-1, j )-conjg( du2( i-2 ) )& *b( i-2, j ) ) / conjg( d( i ) ) end do ! solve l**h * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - conjg( dl( i ) )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - conjg( dl( i ) )*temp b( i, j ) = temp end if end do end do end if end if end subroutine stdlib${ii}$_cgtts2 pure module subroutine stdlib${ii}$_zgtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) !! ZGTTS2 solves one of the systems of equations !! A * X = B, A**T * X = B, or A**H * X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by ZGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: itrans, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(dp), intent(inout) :: b(ldb,*) complex(dp), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j complex(dp) :: temp ! Intrinsic Functions ! Executable Statements ! quick return if possible if( n==0 .or. nrhs==0 )return if( itrans==0_${ik}$ ) then ! solve a*x = b using the lu factorization of a, ! overwriting each right hand side vector with its solution. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 10 continue ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do if( j<nrhs ) then j = j + 1_${ik}$ go to 10 end if else do j = 1, nrhs ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do end do end if else if( itrans==1_${ik}$ ) then ! solve a**t * x = b. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 70 continue ! solve u**t * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d( i & ) end do ! solve l**t * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do if( j<nrhs ) then j = j + 1_${ik}$ go to 70 end if else do j = 1, nrhs ! solve u**t * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d(& i ) end do ! solve l**t * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do end do end if else ! solve a**h * x = b. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 130 continue ! solve u**h * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / conjg( d( 1_${ik}$ ) ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-conjg( du( 1_${ik}$ ) )*b( 1_${ik}$, j ) ) /conjg( d( 2_${ik}$ ) ) do i = 3, n b( i, j ) = ( b( i, j )-conjg( du( i-1 ) )*b( i-1, j )-conjg( du2( i-2 ) )*b( & i-2, j ) ) /conjg( d( i ) ) end do ! solve l**h * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - conjg( dl( i ) )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - conjg( dl( i ) )*temp b( i, j ) = temp end if end do if( j<nrhs ) then j = j + 1_${ik}$ go to 130 end if else do j = 1, nrhs ! solve u**h * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / conjg( d( 1_${ik}$ ) ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-conjg( du( 1_${ik}$ ) )*b( 1_${ik}$, j ) )/ conjg( d( 2_${ik}$ ) ) do i = 3, n b( i, j ) = ( b( i, j )-conjg( du( i-1 ) )*b( i-1, j )-conjg( du2( i-2 ) )& *b( i-2, j ) ) / conjg( d( i ) ) end do ! solve l**h * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - conjg( dl( i ) )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - conjg( dl( i ) )*temp b( i, j ) = temp end if end do end do end if end if end subroutine stdlib${ii}$_zgtts2 #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gtts2( itrans, n, nrhs, dl, d, du, du2, ipiv, b, ldb ) !! ZGTTS2: solves one of the systems of equations !! A * X = B, A**T * X = B, or A**H * X = B, !! with a tridiagonal matrix A using the LU factorization computed !! by ZGTTRF. ! -- lapack computational routine -- ! -- lapack 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) :: itrans, ldb, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) complex(${ck}$), intent(inout) :: b(ldb,*) complex(${ck}$), intent(in) :: d(*), dl(*), du(*), du2(*) ! ===================================================================== ! Local Scalars integer(${ik}$) :: i, j complex(${ck}$) :: temp ! Intrinsic Functions ! Executable Statements ! quick return if possible if( n==0 .or. nrhs==0 )return if( itrans==0_${ik}$ ) then ! solve a*x = b using the lu factorization of a, ! overwriting each right hand side vector with its solution. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 10 continue ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do if( j<nrhs ) then j = j + 1_${ik}$ go to 10 end if else do j = 1, nrhs ! solve l*x = b. do i = 1, n - 1 if( ipiv( i )==i ) then b( i+1, j ) = b( i+1, j ) - dl( i )*b( i, j ) else temp = b( i, j ) b( i, j ) = b( i+1, j ) b( i+1, j ) = temp - dl( i )*b( i, j ) end if end do ! solve u*x = b. b( n, j ) = b( n, j ) / d( n ) if( n>1_${ik}$ )b( n-1, j ) = ( b( n-1, j )-du( n-1 )*b( n, j ) ) /d( n-1 ) do i = n - 2, 1, -1 b( i, j ) = ( b( i, j )-du( i )*b( i+1, j )-du2( i )*b( i+2, j ) ) / d( i ) end do end do end if else if( itrans==1_${ik}$ ) then ! solve a**t * x = b. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 70 continue ! solve u**t * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d( i & ) end do ! solve l**t * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do if( j<nrhs ) then j = j + 1_${ik}$ go to 70 end if else do j = 1, nrhs ! solve u**t * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / d( 1_${ik}$ ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-du( 1_${ik}$ )*b( 1_${ik}$, j ) ) / d( 2_${ik}$ ) do i = 3, n b( i, j ) = ( b( i, j )-du( i-1 )*b( i-1, j )-du2( i-2 )*b( i-2, j ) ) / d(& i ) end do ! solve l**t * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - dl( i )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - dl( i )*temp b( i, j ) = temp end if end do end do end if else ! solve a**h * x = b. if( nrhs<=1_${ik}$ ) then j = 1_${ik}$ 130 continue ! solve u**h * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / conjg( d( 1_${ik}$ ) ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-conjg( du( 1_${ik}$ ) )*b( 1_${ik}$, j ) ) /conjg( d( 2_${ik}$ ) ) do i = 3, n b( i, j ) = ( b( i, j )-conjg( du( i-1 ) )*b( i-1, j )-conjg( du2( i-2 ) )*b( & i-2, j ) ) /conjg( d( i ) ) end do ! solve l**h * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - conjg( dl( i ) )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - conjg( dl( i ) )*temp b( i, j ) = temp end if end do if( j<nrhs ) then j = j + 1_${ik}$ go to 130 end if else do j = 1, nrhs ! solve u**h * x = b. b( 1_${ik}$, j ) = b( 1_${ik}$, j ) / conjg( d( 1_${ik}$ ) ) if( n>1_${ik}$ )b( 2_${ik}$, j ) = ( b( 2_${ik}$, j )-conjg( du( 1_${ik}$ ) )*b( 1_${ik}$, j ) )/ conjg( d( 2_${ik}$ ) ) do i = 3, n b( i, j ) = ( b( i, j )-conjg( du( i-1 ) )*b( i-1, j )-conjg( du2( i-2 ) )& *b( i-2, j ) ) / conjg( d( i ) ) end do ! solve l**h * x = b. do i = n - 1, 1, -1 if( ipiv( i )==i ) then b( i, j ) = b( i, j ) - conjg( dl( i ) )*b( i+1, j ) else temp = b( i+1, j ) b( i+1, j ) = b( i, j ) - conjg( dl( i ) )*temp b( i, j ) = temp end if end do end do end if end if end subroutine stdlib${ii}$_${ci}$gtts2 #:endif #:endfor pure module subroutine stdlib${ii}$_sgtrfs( trans, n, nrhs, dl, d, du, dlf, df, duf, du2,ipiv, b, ldb, x, & !! SGTRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is tridiagonal, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(sp), intent(in) :: b(ldb,*), d(*), df(*), dl(*), dlf(*), du(*), du2(*), duf(*) real(sp), intent(out) :: berr(*), ferr(*), work(*) real(sp), intent(inout) :: x(ldx,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: itmax = 5_${ik}$ ! Local Scalars logical(lk) :: notran character :: transn, transt integer(${ik}$) :: count, i, j, kase, nz real(sp) :: eps, lstres, s, safe1, safe2, safmin ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -13_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -15_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'SGTRFS', -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 if( notran ) then transn = 'N' transt = 'T' else transn = 'T' transt = 'N' 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_110: do j = 1, nrhs count = 1_${ik}$ lstres = three 20 continue ! loop until stopping criterion is satisfied. ! compute residual r = b - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_scopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_slagtm( trans, n, 1_${ik}$, -one, dl, d, du, x( 1_${ik}$, j ), ldx, one,work( n+1 ), & n ) ! compute abs(op(a))*abs(x) + abs(b) for use in the backward ! error bound. if( notran ) then if( n==1_${ik}$ ) then work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) else work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) +abs( du( 1_${ik}$ )*x( 2_${ik}$, j )& ) do i = 2, n - 1 work( i ) = abs( b( i, j ) ) +abs( dl( i-1 )*x( i-1, j ) ) +abs( d( i )*x( & i, j ) ) +abs( du( i )*x( i+1, j ) ) end do work( n ) = abs( b( n, j ) ) +abs( dl( n-1 )*x( n-1, j ) ) +abs( d( n )*x( n, & j ) ) end if else if( n==1_${ik}$ ) then work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) else work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) +abs( dl( 1_${ik}$ )*x( 2_${ik}$, j )& ) do i = 2, n - 1 work( i ) = abs( b( i, j ) ) +abs( du( i-1 )*x( i-1, j ) ) +abs( d( i )*x( & i, j ) ) +abs( dl( i )*x( i+1, j ) ) end do work( n ) = abs( b( n, j ) ) +abs( du( n-1 )*x( n-1, j ) ) +abs( d( n )*x( n, & j ) ) end if end if ! compute componentwise relative backward error from formula ! max(i) ( abs(r(i)) / ( abs(op(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}$_sgttrs( trans, n, 1_${ik}$, dlf, df, duf, du2, ipiv,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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_slacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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}$ 70 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(op(a)**t). call stdlib${ii}$_sgttrs( transt, n, 1_${ik}$, dlf, df, duf, du2, ipiv,work( n+1 ), n, & info ) do i = 1, n work( n+i ) = work( i )*work( n+i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( i )*work( n+i ) end do call stdlib${ii}$_sgttrs( transn, n, 1_${ik}$, dlf, df, duf, du2, ipiv,work( n+1 ), n, & info ) end if go to 70 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_110 return end subroutine stdlib${ii}$_sgtrfs pure module subroutine stdlib${ii}$_dgtrfs( trans, n, nrhs, dl, d, du, dlf, df, duf, du2,ipiv, b, ldb, x, & !! DGTRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is tridiagonal, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(dp), intent(in) :: b(ldb,*), d(*), df(*), dl(*), dlf(*), du(*), du2(*), duf(*) real(dp), intent(out) :: berr(*), ferr(*), work(*) real(dp), intent(inout) :: x(ldx,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: itmax = 5_${ik}$ ! Local Scalars logical(lk) :: notran character :: transn, transt integer(${ik}$) :: count, i, j, kase, nz real(dp) :: eps, lstres, s, safe1, safe2, safmin ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -13_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -15_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGTRFS', -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 if( notran ) then transn = 'N' transt = 'T' else transn = 'T' transt = 'N' 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_110: do j = 1, nrhs count = 1_${ik}$ lstres = three 20 continue ! loop until stopping criterion is satisfied. ! compute residual r = b - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_dcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_dlagtm( trans, n, 1_${ik}$, -one, dl, d, du, x( 1_${ik}$, j ), ldx, one,work( n+1 ), & n ) ! compute abs(op(a))*abs(x) + abs(b) for use in the backward ! error bound. if( notran ) then if( n==1_${ik}$ ) then work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) else work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) +abs( du( 1_${ik}$ )*x( 2_${ik}$, j )& ) do i = 2, n - 1 work( i ) = abs( b( i, j ) ) +abs( dl( i-1 )*x( i-1, j ) ) +abs( d( i )*x( & i, j ) ) +abs( du( i )*x( i+1, j ) ) end do work( n ) = abs( b( n, j ) ) +abs( dl( n-1 )*x( n-1, j ) ) +abs( d( n )*x( n, & j ) ) end if else if( n==1_${ik}$ ) then work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) else work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) +abs( dl( 1_${ik}$ )*x( 2_${ik}$, j )& ) do i = 2, n - 1 work( i ) = abs( b( i, j ) ) +abs( du( i-1 )*x( i-1, j ) ) +abs( d( i )*x( & i, j ) ) +abs( dl( i )*x( i+1, j ) ) end do work( n ) = abs( b( n, j ) ) +abs( du( n-1 )*x( n-1, j ) ) +abs( d( n )*x( n, & j ) ) end if end if ! compute componentwise relative backward error from formula ! max(i) ( abs(r(i)) / ( abs(op(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}$_dgttrs( trans, n, 1_${ik}$, dlf, df, duf, du2, ipiv,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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_dlacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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}$ 70 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(op(a)**t). call stdlib${ii}$_dgttrs( transt, n, 1_${ik}$, dlf, df, duf, du2, ipiv,work( n+1 ), n, & info ) do i = 1, n work( n+i ) = work( i )*work( n+i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( i )*work( n+i ) end do call stdlib${ii}$_dgttrs( transn, n, 1_${ik}$, dlf, df, duf, du2, ipiv,work( n+1 ), n, & info ) end if go to 70 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_110 return end subroutine stdlib${ii}$_dgtrfs #:for rk,rt,ri in REAL_KINDS_TYPES #:if not rk in ["sp","dp"] pure module subroutine stdlib${ii}$_${ri}$gtrfs( trans, n, nrhs, dl, d, du, dlf, df, duf, du2,ipiv, b, ldb, x, & !! DGTRFS: improves the computed solution to a system of linear !! equations when the coefficient matrix is tridiagonal, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) integer(${ik}$), intent(out) :: iwork(*) real(${rk}$), intent(in) :: b(ldb,*), d(*), df(*), dl(*), dlf(*), du(*), du2(*), duf(*) real(${rk}$), intent(out) :: berr(*), ferr(*), work(*) real(${rk}$), intent(inout) :: x(ldx,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: itmax = 5_${ik}$ ! Local Scalars logical(lk) :: notran character :: transn, transt integer(${ik}$) :: count, i, j, kase, nz real(${rk}$) :: eps, lstres, s, safe1, safe2, safmin ! Local Arrays integer(${ik}$) :: isave(3_${ik}$) ! Intrinsic Functions ! Executable Statements ! test the input parameters. info = 0_${ik}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -13_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -15_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'DGTRFS', -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 if( notran ) then transn = 'N' transt = 'T' else transn = 'T' transt = 'N' 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_110: do j = 1, nrhs count = 1_${ik}$ lstres = three 20 continue ! loop until stopping criterion is satisfied. ! compute residual r = b - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_${ri}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work( n+1 ), 1_${ik}$ ) call stdlib${ii}$_${ri}$lagtm( trans, n, 1_${ik}$, -one, dl, d, du, x( 1_${ik}$, j ), ldx, one,work( n+1 ), & n ) ! compute abs(op(a))*abs(x) + abs(b) for use in the backward ! error bound. if( notran ) then if( n==1_${ik}$ ) then work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) else work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) +abs( du( 1_${ik}$ )*x( 2_${ik}$, j )& ) do i = 2, n - 1 work( i ) = abs( b( i, j ) ) +abs( dl( i-1 )*x( i-1, j ) ) +abs( d( i )*x( & i, j ) ) +abs( du( i )*x( i+1, j ) ) end do work( n ) = abs( b( n, j ) ) +abs( dl( n-1 )*x( n-1, j ) ) +abs( d( n )*x( n, & j ) ) end if else if( n==1_${ik}$ ) then work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) else work( 1_${ik}$ ) = abs( b( 1_${ik}$, j ) ) + abs( d( 1_${ik}$ )*x( 1_${ik}$, j ) ) +abs( dl( 1_${ik}$ )*x( 2_${ik}$, j )& ) do i = 2, n - 1 work( i ) = abs( b( i, j ) ) +abs( du( i-1 )*x( i-1, j ) ) +abs( d( i )*x( & i, j ) ) +abs( dl( i )*x( i+1, j ) ) end do work( n ) = abs( b( n, j ) ) +abs( du( n-1 )*x( n-1, j ) ) +abs( d( n )*x( n, & j ) ) end if end if ! compute componentwise relative backward error from formula ! max(i) ( abs(r(i)) / ( abs(op(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}$gttrs( trans, n, 1_${ik}$, dlf, df, duf, du2, ipiv,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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_${ri}$lacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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}$ 70 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(op(a)**t). call stdlib${ii}$_${ri}$gttrs( transt, n, 1_${ik}$, dlf, df, duf, du2, ipiv,work( n+1 ), n, & info ) do i = 1, n work( n+i ) = work( i )*work( n+i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( n+i ) = work( i )*work( n+i ) end do call stdlib${ii}$_${ri}$gttrs( transn, n, 1_${ik}$, dlf, df, duf, du2, ipiv,work( n+1 ), n, & info ) end if go to 70 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_110 return end subroutine stdlib${ii}$_${ri}$gtrfs #:endif #:endfor pure module subroutine stdlib${ii}$_cgtrfs( trans, n, nrhs, dl, d, du, dlf, df, duf, du2,ipiv, b, ldb, x, & !! CGTRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is tridiagonal, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(sp), intent(out) :: berr(*), ferr(*), rwork(*) complex(sp), intent(in) :: b(ldb,*), d(*), df(*), dl(*), dlf(*), du(*), du2(*), duf(*) complex(sp), intent(out) :: work(*) complex(sp), intent(inout) :: x(ldx,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: itmax = 5_${ik}$ ! Local Scalars logical(lk) :: notran character :: transn, transt integer(${ik}$) :: count, i, j, kase, nz real(sp) :: eps, lstres, s, safe1, safe2, safmin 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -13_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -15_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'CGTRFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' 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_110: do j = 1, nrhs count = 1_${ik}$ lstres = three 20 continue ! loop until stopping criterion is satisfied. ! compute residual r = b - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_ccopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_clagtm( trans, n, 1_${ik}$, -one, dl, d, du, x( 1_${ik}$, j ), ldx, one,work, n ) ! compute abs(op(a))*abs(x) + abs(b) for use in the backward ! error bound. if( notran ) then if( n==1_${ik}$ ) then rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) else rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) +cabs1( & du( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) ) do i = 2, n - 1 rwork( i ) = cabs1( b( i, j ) ) +cabs1( dl( i-1 ) )*cabs1( x( i-1, j ) ) +& cabs1( d( i ) )*cabs1( x( i, j ) ) +cabs1( du( i ) )*cabs1( x( i+1, j ) ) end do rwork( n ) = cabs1( b( n, j ) ) +cabs1( dl( n-1 ) )*cabs1( x( n-1, j ) ) +& cabs1( d( n ) )*cabs1( x( n, j ) ) end if else if( n==1_${ik}$ ) then rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) else rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) +cabs1( & dl( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) ) do i = 2, n - 1 rwork( i ) = cabs1( b( i, j ) ) +cabs1( du( i-1 ) )*cabs1( x( i-1, j ) ) +& cabs1( d( i ) )*cabs1( x( i, j ) ) +cabs1( dl( i ) )*cabs1( x( i+1, j ) ) end do rwork( n ) = cabs1( b( n, j ) ) +cabs1( du( n-1 ) )*cabs1( x( n-1, j ) ) +& cabs1( d( n ) )*cabs1( x( n, j ) ) end if end if ! compute componentwise relative backward error from formula ! max(i) ( abs(r(i)) / ( abs(op(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}$_cgttrs( trans, n, 1_${ik}$, dlf, df, duf, du2, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_clacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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}$ 70 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(op(a)**h). call stdlib${ii}$_cgttrs( transt, n, 1_${ik}$, dlf, df, duf, du2, ipiv, work,n, info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_cgttrs( transn, n, 1_${ik}$, dlf, df, duf, du2, ipiv, work,n, info ) end if go to 70 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_110 return end subroutine stdlib${ii}$_cgtrfs pure module subroutine stdlib${ii}$_zgtrfs( trans, n, nrhs, dl, d, du, dlf, df, duf, du2,ipiv, b, ldb, x, & !! ZGTRFS improves the computed solution to a system of linear !! equations when the coefficient matrix is tridiagonal, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(dp), intent(out) :: berr(*), ferr(*), rwork(*) complex(dp), intent(in) :: b(ldb,*), d(*), df(*), dl(*), dlf(*), du(*), du2(*), duf(*) complex(dp), intent(out) :: work(*) complex(dp), intent(inout) :: x(ldx,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: itmax = 5_${ik}$ ! Local Scalars logical(lk) :: notran character :: transn, transt integer(${ik}$) :: count, i, j, kase, nz real(dp) :: eps, lstres, s, safe1, safe2, safmin 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -13_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -15_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGTRFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' 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_110: do j = 1, nrhs count = 1_${ik}$ lstres = three 20 continue ! loop until stopping criterion is satisfied. ! compute residual r = b - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_zcopy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_zlagtm( trans, n, 1_${ik}$, -one, dl, d, du, x( 1_${ik}$, j ), ldx, one,work, n ) ! compute abs(op(a))*abs(x) + abs(b) for use in the backward ! error bound. if( notran ) then if( n==1_${ik}$ ) then rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) else rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) +cabs1( & du( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) ) do i = 2, n - 1 rwork( i ) = cabs1( b( i, j ) ) +cabs1( dl( i-1 ) )*cabs1( x( i-1, j ) ) +& cabs1( d( i ) )*cabs1( x( i, j ) ) +cabs1( du( i ) )*cabs1( x( i+1, j ) ) end do rwork( n ) = cabs1( b( n, j ) ) +cabs1( dl( n-1 ) )*cabs1( x( n-1, j ) ) +& cabs1( d( n ) )*cabs1( x( n, j ) ) end if else if( n==1_${ik}$ ) then rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) else rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) +cabs1( & dl( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) ) do i = 2, n - 1 rwork( i ) = cabs1( b( i, j ) ) +cabs1( du( i-1 ) )*cabs1( x( i-1, j ) ) +& cabs1( d( i ) )*cabs1( x( i, j ) ) +cabs1( dl( i ) )*cabs1( x( i+1, j ) ) end do rwork( n ) = cabs1( b( n, j ) ) +cabs1( du( n-1 ) )*cabs1( x( n-1, j ) ) +& cabs1( d( n ) )*cabs1( x( n, j ) ) end if end if ! compute componentwise relative backward error from formula ! max(i) ( abs(r(i)) / ( abs(op(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}$_zgttrs( trans, n, 1_${ik}$, dlf, df, duf, du2, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_zlacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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}$ 70 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(op(a)**h). call stdlib${ii}$_zgttrs( transt, n, 1_${ik}$, dlf, df, duf, du2, ipiv, work,n, info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_zgttrs( transn, n, 1_${ik}$, dlf, df, duf, du2, ipiv, work,n, info ) end if go to 70 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_110 return end subroutine stdlib${ii}$_zgtrfs #:for ck,ct,ci in CMPLX_KINDS_TYPES #:if not ck in ["sp","dp"] pure module subroutine stdlib${ii}$_${ci}$gtrfs( trans, n, nrhs, dl, d, du, dlf, df, duf, du2,ipiv, b, ldb, x, & !! ZGTRFS: improves the computed solution to a system of linear !! equations when the coefficient matrix is tridiagonal, and provides !! error bounds and backward error estimates for the solution. ldx, ferr, 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) :: trans integer(${ik}$), intent(out) :: info integer(${ik}$), intent(in) :: ldb, ldx, n, nrhs ! Array Arguments integer(${ik}$), intent(in) :: ipiv(*) real(${ck}$), intent(out) :: berr(*), ferr(*), rwork(*) complex(${ck}$), intent(in) :: b(ldb,*), d(*), df(*), dl(*), dlf(*), du(*), du2(*), duf(*) complex(${ck}$), intent(out) :: work(*) complex(${ck}$), intent(inout) :: x(ldx,*) ! ===================================================================== ! Parameters integer(${ik}$), parameter :: itmax = 5_${ik}$ ! Local Scalars logical(lk) :: notran character :: transn, transt integer(${ik}$) :: count, i, j, kase, nz real(${ck}$) :: eps, lstres, s, safe1, safe2, safmin 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}$ notran = stdlib_lsame( trans, 'N' ) if( .not.notran .and. .not.stdlib_lsame( trans, 'T' ) .and. .not.stdlib_lsame( trans, & 'C' ) ) 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 = -13_${ik}$ else if( ldx<max( 1_${ik}$, n ) ) then info = -15_${ik}$ end if if( info/=0_${ik}$ ) then call stdlib${ii}$_xerbla( 'ZGTRFS', -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 if( notran ) then transn = 'N' transt = 'C' else transn = 'C' transt = 'N' 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_110: do j = 1, nrhs count = 1_${ik}$ lstres = three 20 continue ! loop until stopping criterion is satisfied. ! compute residual r = b - op(a) * x, ! where op(a) = a, a**t, or a**h, depending on trans. call stdlib${ii}$_${ci}$copy( n, b( 1_${ik}$, j ), 1_${ik}$, work, 1_${ik}$ ) call stdlib${ii}$_${ci}$lagtm( trans, n, 1_${ik}$, -one, dl, d, du, x( 1_${ik}$, j ), ldx, one,work, n ) ! compute abs(op(a))*abs(x) + abs(b) for use in the backward ! error bound. if( notran ) then if( n==1_${ik}$ ) then rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) else rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) +cabs1( & du( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) ) do i = 2, n - 1 rwork( i ) = cabs1( b( i, j ) ) +cabs1( dl( i-1 ) )*cabs1( x( i-1, j ) ) +& cabs1( d( i ) )*cabs1( x( i, j ) ) +cabs1( du( i ) )*cabs1( x( i+1, j ) ) end do rwork( n ) = cabs1( b( n, j ) ) +cabs1( dl( n-1 ) )*cabs1( x( n-1, j ) ) +& cabs1( d( n ) )*cabs1( x( n, j ) ) end if else if( n==1_${ik}$ ) then rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) else rwork( 1_${ik}$ ) = cabs1( b( 1_${ik}$, j ) ) +cabs1( d( 1_${ik}$ ) )*cabs1( x( 1_${ik}$, j ) ) +cabs1( & dl( 1_${ik}$ ) )*cabs1( x( 2_${ik}$, j ) ) do i = 2, n - 1 rwork( i ) = cabs1( b( i, j ) ) +cabs1( du( i-1 ) )*cabs1( x( i-1, j ) ) +& cabs1( d( i ) )*cabs1( x( i, j ) ) +cabs1( dl( i ) )*cabs1( x( i+1, j ) ) end do rwork( n ) = cabs1( b( n, j ) ) +cabs1( du( n-1 ) )*cabs1( x( n-1, j ) ) +& cabs1( d( n ) )*cabs1( x( n, j ) ) end if end if ! compute componentwise relative backward error from formula ! max(i) ( abs(r(i)) / ( abs(op(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}$gttrs( trans, n, 1_${ik}$, dlf, df, duf, du2, ipiv, 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(op(a)))* ! ( abs(r) + nz*eps*( abs(op(a))*abs(x)+abs(b) ))) / norm(x) ! where ! norm(z) is the magnitude of the largest component of z ! inv(op(a)) is the inverse of op(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(op(a))*abs(x)+abs(b)) ! is incremented by safe1 if the i-th component of ! abs(op(a))*abs(x) + abs(b) is less than safe2. ! use stdlib_${ci}$lacn2 to estimate the infinity-norm of the matrix ! inv(op(a)) * diag(w), ! where w = abs(r) + nz*eps*( abs(op(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}$ 70 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(op(a)**h). call stdlib${ii}$_${ci}$gttrs( transt, n, 1_${ik}$, dlf, df, duf, du2, ipiv, work,n, info ) do i = 1, n work( i ) = rwork( i )*work( i ) end do else ! multiply by inv(op(a))*diag(w). do i = 1, n work( i ) = rwork( i )*work( i ) end do call stdlib${ii}$_${ci}$gttrs( transn, n, 1_${ik}$, dlf, df, duf, du2, ipiv, work,n, info ) end if go to 70 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_110 return end subroutine stdlib${ii}$_${ci}$gtrfs #:endif #:endfor #:endfor end submodule stdlib_lapack_solve_lu_comp