zpbsvx.f
来自「famous linear algebra library (LAPACK) p」· F 代码 · 共 422 行 · 第 1/2 页
F
422 行
*
* The band storage scheme is illustrated by the following example, when
* N = 6, KD = 2, and UPLO = 'U':
*
* Two-dimensional storage of the Hermitian matrix A:
*
* a11 a12 a13
* a22 a23 a24
* a33 a34 a35
* a44 a45 a46
* a55 a56
* (aij=conjg(aji)) a66
*
* Band storage of the upper triangle of A:
*
* * * a13 a24 a35 a46
* * a12 a23 a34 a45 a56
* a11 a22 a33 a44 a55 a66
*
* Similarly, if UPLO = 'L' the format of A is as follows:
*
* a11 a22 a33 a44 a55 a66
* a21 a32 a43 a54 a65 *
* a31 a42 a53 a64 * *
*
* Array elements marked * are not used by the routine.
*
* =====================================================================
*
* .. Parameters ..
DOUBLE PRECISION ZERO, ONE
PARAMETER ( ZERO = 0.0D+0, ONE = 1.0D+0 )
* ..
* .. Local Scalars ..
LOGICAL EQUIL, NOFACT, RCEQU, UPPER
INTEGER I, INFEQU, J, J1, J2
DOUBLE PRECISION AMAX, ANORM, BIGNUM, SCOND, SMAX, SMIN, SMLNUM
* ..
* .. External Functions ..
LOGICAL LSAME
DOUBLE PRECISION DLAMCH, ZLANHB
EXTERNAL LSAME, DLAMCH, ZLANHB
* ..
* .. External Subroutines ..
EXTERNAL XERBLA, ZCOPY, ZLACPY, ZLAQHB, ZPBCON, ZPBEQU,
$ ZPBRFS, ZPBTRF, ZPBTRS
* ..
* .. Intrinsic Functions ..
INTRINSIC MAX, MIN
* ..
* .. Executable Statements ..
*
INFO = 0
NOFACT = LSAME( FACT, 'N' )
EQUIL = LSAME( FACT, 'E' )
UPPER = LSAME( UPLO, 'U' )
IF( NOFACT .OR. EQUIL ) THEN
EQUED = 'N'
RCEQU = .FALSE.
ELSE
RCEQU = LSAME( EQUED, 'Y' )
SMLNUM = DLAMCH( 'Safe minimum' )
BIGNUM = ONE / SMLNUM
END IF
*
* Test the input parameters.
*
IF( .NOT.NOFACT .AND. .NOT.EQUIL .AND. .NOT.LSAME( FACT, 'F' ) )
$ THEN
INFO = -1
ELSE IF( .NOT.UPPER .AND. .NOT.LSAME( UPLO, 'L' ) ) THEN
INFO = -2
ELSE IF( N.LT.0 ) THEN
INFO = -3
ELSE IF( KD.LT.0 ) THEN
INFO = -4
ELSE IF( NRHS.LT.0 ) THEN
INFO = -5
ELSE IF( LDAB.LT.KD+1 ) THEN
INFO = -7
ELSE IF( LDAFB.LT.KD+1 ) THEN
INFO = -9
ELSE IF( LSAME( FACT, 'F' ) .AND. .NOT.
$ ( RCEQU .OR. LSAME( EQUED, 'N' ) ) ) THEN
INFO = -10
ELSE
IF( RCEQU ) THEN
SMIN = BIGNUM
SMAX = ZERO
DO 10 J = 1, N
SMIN = MIN( SMIN, S( J ) )
SMAX = MAX( SMAX, S( J ) )
10 CONTINUE
IF( SMIN.LE.ZERO ) THEN
INFO = -11
ELSE IF( N.GT.0 ) THEN
SCOND = MAX( SMIN, SMLNUM ) / MIN( SMAX, BIGNUM )
ELSE
SCOND = ONE
END IF
END IF
IF( INFO.EQ.0 ) THEN
IF( LDB.LT.MAX( 1, N ) ) THEN
INFO = -13
ELSE IF( LDX.LT.MAX( 1, N ) ) THEN
INFO = -15
END IF
END IF
END IF
*
IF( INFO.NE.0 ) THEN
CALL XERBLA( 'ZPBSVX', -INFO )
RETURN
END IF
*
IF( EQUIL ) THEN
*
* Compute row and column scalings to equilibrate the matrix A.
*
CALL ZPBEQU( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, INFEQU )
IF( INFEQU.EQ.0 ) THEN
*
* Equilibrate the matrix.
*
CALL ZLAQHB( UPLO, N, KD, AB, LDAB, S, SCOND, AMAX, EQUED )
RCEQU = LSAME( EQUED, 'Y' )
END IF
END IF
*
* Scale the right-hand side.
*
IF( RCEQU ) THEN
DO 30 J = 1, NRHS
DO 20 I = 1, N
B( I, J ) = S( I )*B( I, J )
20 CONTINUE
30 CONTINUE
END IF
*
IF( NOFACT .OR. EQUIL ) THEN
*
* Compute the Cholesky factorization A = U'*U or A = L*L'.
*
IF( UPPER ) THEN
DO 40 J = 1, N
J1 = MAX( J-KD, 1 )
CALL ZCOPY( J-J1+1, AB( KD+1-J+J1, J ), 1,
$ AFB( KD+1-J+J1, J ), 1 )
40 CONTINUE
ELSE
DO 50 J = 1, N
J2 = MIN( J+KD, N )
CALL ZCOPY( J2-J+1, AB( 1, J ), 1, AFB( 1, J ), 1 )
50 CONTINUE
END IF
*
CALL ZPBTRF( UPLO, N, KD, AFB, LDAFB, INFO )
*
* Return if INFO is non-zero.
*
IF( INFO.GT.0 )THEN
RCOND = ZERO
RETURN
END IF
END IF
*
* Compute the norm of the matrix A.
*
ANORM = ZLANHB( '1', UPLO, N, KD, AB, LDAB, RWORK )
*
* Compute the reciprocal of the condition number of A.
*
CALL ZPBCON( UPLO, N, KD, AFB, LDAFB, ANORM, RCOND, WORK, RWORK,
$ INFO )
*
* Compute the solution matrix X.
*
CALL ZLACPY( 'Full', N, NRHS, B, LDB, X, LDX )
CALL ZPBTRS( UPLO, N, KD, NRHS, AFB, LDAFB, X, LDX, INFO )
*
* Use iterative refinement to improve the computed solution and
* compute error bounds and backward error estimates for it.
*
CALL ZPBRFS( UPLO, N, KD, NRHS, AB, LDAB, AFB, LDAFB, B, LDB, X,
$ LDX, FERR, BERR, WORK, RWORK, INFO )
*
* Transform the solution matrix X to a solution of the original
* system.
*
IF( RCEQU ) THEN
DO 70 J = 1, NRHS
DO 60 I = 1, N
X( I, J ) = S( I )*X( I, J )
60 CONTINUE
70 CONTINUE
DO 80 J = 1, NRHS
FERR( J ) = FERR( J ) / SCOND
80 CONTINUE
END IF
*
* Set INFO = N+1 if the matrix is singular to working precision.
*
IF( RCOND.LT.DLAMCH( 'Epsilon' ) )
$ INFO = N + 1
*
RETURN
*
* End of ZPBSVX
*
END
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?